Skip to content

Commit

Permalink
Refactor api and optimize saving
Browse files Browse the repository at this point in the history
  • Loading branch information
apbetioli committed Jun 1, 2024
1 parent befb6e7 commit 00fcfad
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 114 deletions.
1 change: 0 additions & 1 deletion app/admin/courses/[id]/course-form-lessons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const initialState = {
name: '',
slug: '',
video: '',
delete: false,
order: 0,
}

Expand Down
8 changes: 6 additions & 2 deletions app/admin/courses/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,12 @@ export default function CourseFormPage({ params }: { params: { id: string } }) {
<div className="flex justify-between items-center flex-col sm:flex-row gap-4">
<TabsList>
<TabsTrigger value="details">Details</TabsTrigger>
<TabsTrigger value="lessons">Lessons</TabsTrigger>
<TabsTrigger value="assets">Assets</TabsTrigger>
<TabsTrigger value="lessons" disabled={!course.id}>
Lessons
</TabsTrigger>
<TabsTrigger value="assets" disabled={!course.id}>
Assets
</TabsTrigger>
</TabsList>

<div className="flex items-center gap-3 justify-center sm:justify-end w-full">
Expand Down
242 changes: 136 additions & 106 deletions app/api/admin/courses/route.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { UIAsset, UICourse, UIGroup, UILesson } from '@/app/types'
import { getUserByClerkId } from '@/lib/server/auth'
import { prisma } from '@/lib/server/db'
import { NextResponse } from 'next/server'
Expand Down Expand Up @@ -38,77 +39,29 @@ export const POST = async (request: Request) => {
return NextResponse.json({ message: 'Forbidden' }, { status: 403 })
}

const { id, assets, groups, ...data } = await request.json()
const draftCourse = await request.json()

if (id) {
var course = await prisma.course.update({
data,
where: {
id,
},
})
console.log('Updated course', course.id)
} else {
var course = await prisma.course.create({
data,
})
console.log('Created course', course.id)
}
const course = await upsertCourse(draftCourse)

// TODO improve this logic
for (const { id, lessons, name, order, deleted: groupDeleted } of groups) {
if (groupDeleted) {
var newGroup = await prisma.group.delete({
where: {
id,
},
})
console.log('Deleted group', newGroup.id)
} else {
if (id) {
var newGroup = await prisma.group.update({
data: { name, order, courseId: course.id },
where: {
id,
},
})
console.log('Updated group', newGroup.id)
} else {
var newGroup = await prisma.group.create({
data: { name, order, courseId: course.id },
})
console.log('Created group', newGroup.id)
}
}
for (const draftGroup of draftCourse.groups) {
const group = await upsertGroup(course.id, draftGroup)

for (const { id, name, slug, video, deleted, order } of lessons) {
if (deleted || groupDeleted) {
var newLesson = await prisma.lesson.delete({
where: {
id,
},
})
console.log('Deleted lesson', newLesson.id)
} else {
if (id) {
var newLesson = await prisma.lesson.update({
data: { name, slug, video, order, groupId: newGroup.id },
where: {
id,
},
})
console.log('Updated lesson', newLesson.id)
} else {
var newLesson = await prisma.lesson.create({
data: { name, slug, video, order, groupId: newGroup.id },
})
console.log('Created lesson', newLesson.id)
}
}
for (const draftLesson of draftGroup.lessons) {
draftLesson.deleted ||= draftGroup.deleted

await upsertLesson(group.id, draftLesson)
}
}

for (const {
for (const asset of draftCourse.assets) {
await upsertAssets(course.id, asset)
}

return NextResponse.json(course)
}

async function upsertAssets(courseId: string, asset: UIAsset) {
const {
id,
name,
description,
Expand All @@ -117,47 +70,124 @@ export const POST = async (request: Request) => {
price,
anchor_price,
deleted,
} of assets) {
if (deleted) {
const newAsset = await prisma.asset.delete({
where: {
id,
},
})
console.log('Deleted asset', newAsset.id)
} else {
if (id) {
const newAsset = await prisma.asset.update({
data: {
name,
description,
image,
url,
price,
anchor_price,
courseId: course.id,
},
where: {
id,
},
})
console.log('Updated asset', newAsset.id)
} else {
const newAsset = await prisma.asset.create({
data: {
name,
description,
image,
url,
price,
anchor_price,
courseId: course.id,
},
})
console.log('Created asset', newAsset.id)
}
}
changed,
} = asset

if (deleted) {
return await prisma.asset.delete({
where: {
id,
},
})
}

return NextResponse.json(course)
if (!id) {
return await prisma.asset.create({
data: {
name,
description,
image,
url,
price,
anchor_price,
courseId,
},
})
}

if (!changed) {
return { id }
}

return await prisma.asset.update({
data: {
name,
description,
image,
url,
price,
anchor_price,
courseId,
},
where: {
id,
},
})
}

async function upsertLesson(
groupId: string,
{ id, name, slug, video, deleted, order, changed }: UILesson,
) {
if (deleted) {
return await prisma.lesson.delete({
where: {
id,
},
})
}

if (!id) {
return await prisma.lesson.create({
data: { name, slug, video, order, groupId },
})
}

if (!changed) {
return { id }
}

return await prisma.lesson.update({
data: { name, slug, video, order, groupId },
where: {
id,
},
})
}

async function upsertGroup(
courseId: string,
{ id, name, order, deleted, changed }: UIGroup,
) {
if (deleted) {
return await prisma.group.delete({
where: {
id,
},
})
}

if (!id) {
return await prisma.group.create({
data: { name, order, courseId },
})
}

if (!changed) {
return { id }
}

return await prisma.group.update({
data: { name, order, courseId },
where: {
id,
},
})
}

async function upsertCourse(course: UICourse) {
const { id, assets, groups, ...data } = course

if (!id) {
return await prisma.course.create({
data,
})
}

return await prisma.course.update({
data,
where: {
id,
},
})
}
1 change: 1 addition & 0 deletions app/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type Draft<T> = Omit<T, 'id'> & {
id?: string
uiId?: string
deleted?: boolean
changed?: boolean
}

export type UIAsset = Omit<Draft<Asset>, 'courseId'>
Expand Down
21 changes: 16 additions & 5 deletions lib/features/admin-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ const adminSlice = createSlice({
const index = state.course.groups.findIndex(
(group) => group.uiId === action.payload.uiId,
)
action.payload.changed = true
state.course.groups.splice(index, 1, action.payload)
},

Expand All @@ -128,6 +129,7 @@ const adminSlice = createSlice({
const index = state.course.assets.findIndex(
(asset) => asset.uiId === action.payload.uiId,
)
action.payload.changed = true
state.course.assets.splice(index, 1, action.payload)
},

Expand All @@ -149,12 +151,13 @@ const adminSlice = createSlice({
state,
action: PayloadAction<{ group: UIGroup; lesson: UILesson }>,
) => {
const groupToAdd = findGroup(state, action.payload.group)
const groupToUpdate = findGroup(state, action.payload.group)
groupToUpdate.changed = true

groupToAdd.lessons.push(
groupToUpdate.lessons.push(
createLesson({
...action.payload.lesson,
order: groupToAdd.lessons.length,
order: groupToUpdate.lessons.length,
}),
)
},
Expand All @@ -164,17 +167,21 @@ const adminSlice = createSlice({
action: PayloadAction<{ group: UIGroup; lesson: UILesson }>,
) => {
const groupToUpdate = findGroup(state, action.payload.group)

const index = findLessonIndex(groupToUpdate, action.payload.lesson)
groupToUpdate.changed = true

groupToUpdate.lessons.splice(index, 1, action.payload.lesson)
groupToUpdate.lessons.splice(index, 1, {
...action.payload.lesson,
changed: true,
})
},

deleteLesson: (
state,
action: PayloadAction<{ group: UIGroup; lesson: UILesson }>,
) => {
const groupToUpdate = findGroup(state, action.payload.group)
groupToUpdate.changed = true

const index = findLessonIndex(groupToUpdate, action.payload.lesson)

Expand Down Expand Up @@ -207,6 +214,8 @@ const adminSlice = createSlice({

groupToUpdate.lessons[index].order = index
groupToUpdate.lessons[index - 1].order = index - 1

groupToUpdate.changed = true
},

moveLessonDown: (
Expand All @@ -228,6 +237,8 @@ const adminSlice = createSlice({

groupToUpdate.lessons[index].order = index
groupToUpdate.lessons[index + 1].order = index + 1

groupToUpdate.changed = true
},
},
extraReducers: (builder) => {
Expand Down

0 comments on commit 00fcfad

Please sign in to comment.