Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/article-2 #158

Merged
merged 43 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2e416ae
refactor: makes AddParts reusable
JohanHjelsethStorstad Feb 4, 2024
97aaa25
fix: new wrapper component missing use client
JohanHjelsethStorstad Feb 4, 2024
a4d503c
chore: start work on AddSection component
JohanHjelsethStorstad Feb 4, 2024
7ddd4ad
chore: use new cms alias
JohanHjelsethStorstad Feb 4, 2024
5f95395
feat: adds action to create new section
JohanHjelsethStorstad Feb 4, 2024
b8bedd1
chore: adds ability to add link, image, or paragraph when creating ne…
JohanHjelsethStorstad Feb 4, 2024
ae57e4c
chore: adds max number of sections in an article
JohanHjelsethStorstad Feb 4, 2024
5f78ded
feat: adds call to add ArticleSecion
JohanHjelsethStorstad Feb 5, 2024
1b628e5
chore: displays mac number sections reached on frontend
JohanHjelsethStorstad Feb 5, 2024
1bb90e8
chore: remove console.log
JohanHjelsethStorstad Feb 5, 2024
9ab9a8a
chore: remove chack for login on home. The page wont be shown on log …
JohanHjelsethStorstad Feb 5, 2024
40744d9
fix: uniqe name
JohanHjelsethStorstad Feb 5, 2024
cffea11
fix: part not adding to section on addSection
JohanHjelsethStorstad Feb 5, 2024
5f84581
feat: adds destroy aaction for articleSection
JohanHjelsethStorstad Feb 5, 2024
9e5f49d
chore: modify scema.prisma
JohanHjelsethStorstad Feb 5, 2024
337187c
chore: adds a @map for convention
JohanHjelsethStorstad Feb 5, 2024
3457514
chore: adds a @map for convention
JohanHjelsethStorstad Feb 5, 2024
b003ced
chore: change removePart to delete whole section if empty
JohanHjelsethStorstad Feb 5, 2024
04412c0
fix: spelling
JohanHjelsethStorstad Feb 5, 2024
c5ee1a6
fix: removed articlesections counted towards max # sections
JohanHjelsethStorstad Feb 5, 2024
d22f3af
Merge branch 'main' into feat/Article
JohanHjelsethStorstad Feb 5, 2024
1844952
chore: fix some lint thing
JohanHjelsethStorstad Feb 6, 2024
f75d0fd
chore: fix some minor styling
JohanHjelsethStorstad Feb 6, 2024
46f48fc
chore: styles add section buttons
JohanHjelsethStorstad Feb 6, 2024
926dab2
chore: adds component for moving sections within article
JohanHjelsethStorstad Feb 6, 2024
64d59e7
chore: adds styling to move section buttons
JohanHjelsethStorstad Feb 6, 2024
a627491
chore: styles move buttons positions
JohanHjelsethStorstad Feb 6, 2024
ba83fdc
feat: adds action to move a section
JohanHjelsethStorstad Feb 6, 2024
813f94c
chore: adds call to move action in frontend
JohanHjelsethStorstad Feb 6, 2024
9d29539
fix: pass sectionId to mover
JohanHjelsethStorstad Feb 6, 2024
e6344c2
fix: sections can bow be moved
JohanHjelsethStorstad Feb 6, 2024
3e10bdf
chore: just change intermidate value
JohanHjelsethStorstad Feb 6, 2024
ab069f3
fix: action was fetching all sections not just the one for the article
JohanHjelsethStorstad Feb 6, 2024
06a2668
chore: remove button if section is already at top/bottom
JohanHjelsethStorstad Feb 6, 2024
41f375c
chore: adds styling to max length text
JohanHjelsethStorstad Feb 6, 2024
7ebe600
feat: EditableTextField
JohanHjelsethStorstad Feb 6, 2024
d81da36
feat: adds styling to edittextfield
JohanHjelsethStorstad Feb 6, 2024
c428d51
chore: fix linting
JohanHjelsethStorstad Feb 6, 2024
bc4510d
fix: safari issue
JohanHjelsethStorstad Feb 6, 2024
94bde7a
chore: fixes linting
JohanHjelsethStorstad Feb 6, 2024
d8c1fa7
fix: spelling errors
Paulijuz Feb 6, 2024
2ce0328
chore: fix merge conflicts
JohanHjelsethStorstad Feb 6, 2024
9a0db3d
Merge remote-tracking branch 'origin/feat/Article' into feat/Article
JohanHjelsethStorstad Feb 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/actions/cms/articleSections/destroy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use server'
import prisma from '@/prisma'
import errorHandler from '@/prisma/errorHandler'
import { ActionReturn } from '@/actions/type'
import { ArticleSection } from '@prisma/client'

export default async function destroy(name: string) : Promise<ActionReturn<ArticleSection>> {
try {
const articleSection = await prisma.articleSection.delete({
where: { name },
})
return { success: true, data: articleSection }
} catch (error) {
return errorHandler(error)
}
}
62 changes: 38 additions & 24 deletions src/actions/cms/articleSections/update.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use server'
import { maxImageSize, minImageSize } from './ConfigVars'
import destroy from './destroy'
import prisma from '@/prisma'
import errorHandler from '@/prisma/errorHandler'
import { default as createCmsImage } from '@/actions/cms/images/create'
Expand Down Expand Up @@ -130,37 +131,50 @@ export async function removePart(name: string, part: Part) : Promise<ActionRetur
switch (part) {
case 'cmsLink':
await prisma.cmsLink.delete({ where: { id: articleSection.cmsLink?.id } })
return {
success: true,
data: await prisma.articleSection.findUnique({
where: { name },
include: { cmsParagraph: true, cmsImage: true, cmsLink: true }
}) || articleSection
}

break
case 'cmsParagraph':
await prisma.cmsParagraph.delete({ where: { id: articleSection.cmsParagraph?.id } })
return {
success: true,
data: await prisma.articleSection.findUnique({
where: { name },
include: { cmsParagraph: true, cmsImage: true, cmsLink: true }
}) || articleSection
}

break
case 'cmsImage':
await prisma.cmsImage.delete({ where: { id: articleSection.cmsImage?.id } })
return {
success: true,
data: await prisma.articleSection.findUnique({
where: { name },
include: { cmsParagraph: true, cmsImage: true, cmsLink: true }
}) || articleSection
}
break
default:
break
}
return { success: false, error: [{ message: 'Invalid part' }] }


// check if all Parts are removed and if so, remove the articleSection,
// but only if destroyOnEmpty is true
const afterDelete = await prisma.articleSection.findUnique({
where: { name },
include: { cmsParagraph: true, cmsImage: true, cmsLink: true }
})
if (!afterDelete) {
return {
success: false,
error: [{ message: 'Noe uventet skjedde etter sletting av del av artclesection' }]
}
}
if (
articleSection.destroyOnEmpty &&
!afterDelete.cmsImage &&
!afterDelete.cmsParagraph &&
!afterDelete.cmsImage
) {
const destroyRes = await destroy(name)
if (!destroyRes.success) {
return {
success: false,
error: [{ message: 'Greide ikke slette artikkelseksjonen' }]
}
}
return { success: true, data: destroyRes.data }
}

return {
success: true,
data: afterDelete
}
} catch (error) {
return errorHandler(error)
}
Expand Down
1 change: 1 addition & 0 deletions src/actions/cms/articles/ConfigVars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const maxSections = 10 // Max 10 sections in an article
4 changes: 2 additions & 2 deletions src/actions/cms/articles/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { ActionReturn } from '@/actions/type'
import prisma from '@/prisma'
import errorHandeler from '@/prisma/errorHandler'

export default async function read(name: string): Promise<ActionReturn<ReturnType>> {
export default async function read(id: number): Promise<ActionReturn<ReturnType>> {
try {
const article = await prisma.article.findUnique({
where: {
name
id
},
include: {
articleSections: {
Expand Down
203 changes: 199 additions & 4 deletions src/actions/cms/articles/update.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
'use server'
import { maxSections } from './ConfigVars'
import prisma from '@/prisma'
import errorHandler from '@/prisma/errorHandler'
import { ActionReturn } from '@/actions/type'
import { addPart } from '@/cms/articleSections/update'
import { ArticleSection } from '@prisma/client'
import { z } from 'zod'
import type { Part } from '@/cms/articleSections/update'
import type { ReturnType } from './ReturnType'

export default async function update(id: number, config: {
name?: string,
}) : Promise<ActionReturn<ReturnType>> {
export default async function update(id: number, rawData: FormData) : Promise<ActionReturn<ReturnType>> {
const schema = z.object({
name: z.string().min(2).max(20)
})
const parse = schema.safeParse({
name: rawData.get('name'),
})

if (!parse.success) {
return {
success: false,
error: parse.error.issues
}
}
const data = parse.data

try {
const article = await prisma.article.update({
where: {
id,
},
data: {
...config,
...data,
},
include: {
coverImage: true,
Expand All @@ -31,3 +49,180 @@ export default async function update(id: number, config: {
return errorHandler(error)
}
}

export async function addSectionToArticle(
id: number,
include: Partial<Record<Part, boolean>>
) : Promise<ActionReturn<ReturnType>> {
try {
const article = await prisma.article.findUnique({
where: {
id,
},
})

if (!article) {
return {
success: false,
error: [{
message: 'Artikkel ikke funnet',
}],
}
}

const highestOrderSection = await prisma.articleSection.findMany({
where: {
articleId: id,
},
orderBy: {
order: 'desc',
},
take: 1,
})

// Get the order of the highest order section, or 0 if there are no sections
const nextOreder = highestOrderSection.length > 0 ? highestOrderSection[0].order + 1 : 0


const numberOfSections = await prisma.articleSection.count({
where: {
articleId: id,
},
})
if (numberOfSections >= maxSections) {
return {
success: false,
error: [{
message: `The maximum number of sections is ${maxSections}`,
}],
}
}

const newSectionName = `${article.name} section ${nextOreder}`

const updatedArticle = await prisma.article.update({
where: {
id,
},
data: {
articleSections: {
create: {
name: newSectionName,
order: nextOreder,
},
},
},
include: {
coverImage: true,
articleSections: {
include: {
cmsImage: true,
cmsParagraph: true,
cmsLink: true,
}
}
}
})

for (const part of ['cmsParagraph', 'cmsLink', 'cmsImage'] as const) {
if (include[part]) {
await addPart(newSectionName, part)
}
}

return { success: true, data: updatedArticle }
} catch (error) {
return errorHandler(error)
}
}

export async function moveSectionOrder(
id: number,
sectionId: number,
direction: 'UP' | 'DOWN'
) : Promise<ActionReturn<ArticleSection>> {
try {
//get section to move
const section = await prisma.articleSection.findUnique({
where: {
articleId: id,
id: sectionId,
},
})
if (!section) {
return {
success: false,
error: [{
message: 'Seksjon ikke funnet',
}],
}
}

//find the section with the order one higher/lower than the current section
const otherSection = await prisma.articleSection.findMany({
where: {
articleId: id,
order: direction === 'UP' ? {
lt: section.order,
} : {
gt: section.order,
},
},
orderBy: {
order: direction === 'UP' ? 'desc' : 'asc',
},
take: 1,
}).then(sections => sections[0])
if (!otherSection) {
return {
success: false,
error: [{
message: 'Seksjon kan ikke flyttes opp/ned',
}],
}
}


//flip thir order numbers
const tempOrder = -1 // Or any other value that won't violate the unique constraint

// First, set the order of the section to the temporary value
await prisma.articleSection.update({
where: {
articleId: id,
id: section.id
},
data: { order: tempOrder },
})
const updatedOtherSection = await prisma.articleSection.update({
where: {
articleId: id,
id: otherSection.id
},
data: { order: section.order },
})
// Finally, set the order of the section to the otherSection's original order
const updatedSection = await prisma.articleSection.update({
where: {
articleId: id,
id: section.id
},
data: { order: otherSection.order },
})


if (!updatedSection || !updatedOtherSection) {
return {
success: false,
error: [{
message: 'Noe uventet skjedde under flytting av seksjonen',
}],
}
}

return { success: true, data: updatedSection }
} catch (error) {
console.log(error)
return errorHandler(error)
}
}
11 changes: 2 additions & 9 deletions src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,19 @@ import SocialIcons from '@/components/SocialIcons/SocialIcons'
import CmsImage from '@/components/Cms/CmsImage/CmsImage'
import GoogleMap from '@/components/GoogleMap/GoogleMap'
import YouTube from '@/components/YouTube/YouTube'
import { getUser } from '@/auth'
import { faAngleDown } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import Link from 'next/link'

export default async function Home() {
const user = await getUser()

console.log(user)

return (
<div className={styles.wrapper}>
<div className={`${styles.part} ${styles.frontImg}`}>
<div className={styles.frontInfo}>
<div>
<CmsImage name="frontpage_logo" width={300}/>
{user === null && <>
<Link href="login">Logg inn</Link>
<Link href="infopages/nystudent">Ny student</Link>
</>}
<Link href="login">Logg inn</Link>
<Link href="infopages/nystudent">Ny student</Link>
<div className={styles.socials}>
<SocialIcons />
</div>
Expand Down
15 changes: 15 additions & 0 deletions src/app/components/Cms/AddParts.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@use '@/styles/ohma';


.AddParts {
z-index: 1;
display: flex;
button {
display: flex;
align-items: center;
justify-content: center;
&:hover {
cursor: pointer;
}
}
}
Loading
Loading