diff --git a/prisma/migrations/20240824210117_init/migration.sql b/prisma/migrations/20240824231326_init/migration.sql similarity index 98% rename from prisma/migrations/20240824210117_init/migration.sql rename to prisma/migrations/20240824231326_init/migration.sql index f228464..6d71f07 100644 --- a/prisma/migrations/20240824210117_init/migration.sql +++ b/prisma/migrations/20240824231326_init/migration.sql @@ -35,7 +35,7 @@ CREATE TABLE "Purchase" ( -- CreateTable CREATE TABLE "Lesson" ( "id" TEXT NOT NULL, - "courseId" TEXT NOT NULL, + "courseId" TEXT, "resourceId" TEXT, "draftId" TEXT, "index" INTEGER NOT NULL, @@ -140,7 +140,7 @@ ALTER TABLE "Purchase" ADD CONSTRAINT "Purchase_courseId_fkey" FOREIGN KEY ("cou ALTER TABLE "Purchase" ADD CONSTRAINT "Purchase_resourceId_fkey" FOREIGN KEY ("resourceId") REFERENCES "Resource"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Lesson" ADD CONSTRAINT "Lesson_courseId_fkey" FOREIGN KEY ("courseId") REFERENCES "Course"("id") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Lesson" ADD CONSTRAINT "Lesson_courseId_fkey" FOREIGN KEY ("courseId") REFERENCES "Course"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Lesson" ADD CONSTRAINT "Lesson_resourceId_fkey" FOREIGN KEY ("resourceId") REFERENCES "Resource"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index d018aa4..fbd69be 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -44,8 +44,8 @@ model Purchase { model Lesson { id String @id @default(uuid()) - courseId String - course Course @relation(fields: [courseId], references: [id]) + courseId String? + course Course? @relation(fields: [courseId], references: [id]) resourceId String? resource Resource? @relation(fields: [resourceId], references: [id]) draftId String? diff --git a/src/components/content/courses/DraftCourseDetails.js b/src/components/content/courses/DraftCourseDetails.js index 2de8635..91567cd 100644 --- a/src/components/content/courses/DraftCourseDetails.js +++ b/src/components/content/courses/DraftCourseDetails.js @@ -73,6 +73,27 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons }) }); } + const handlePostLesson = async (lesson) => { + console.log('lesson in handlePostLesson', lesson); + let payload; + + + if (lesson.d) { + payload = { + resourceId: lesson.d, + index: lesson.index + } + } else if (lesson.draftId) { + payload = { + draftId: lesson.draftId, + index: lesson.index + } + } + + const response = await axios.post(`/api/lessons`, payload); + return response.data; + } + const handlePostResource = async (resource) => { console.log('resourceeeeee:', resource.tags); const dTag = resource.tags.find(tag => tag[0] === 'd')[1]; @@ -125,64 +146,64 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons }) await addSigner(); } // Step 1: Process lessons + const createdLessons = []; for (const lesson of processedLessons) { - // publish any draft lessons and delete draft lessons - const unpublished = lesson?.unpublished; - if (unpublished && Object.keys(unpublished).length > 0) { - const validationResult = validateEvent(unpublished); + let savedLesson; + if (lesson.unpublished) { + const validationResult = validateEvent(lesson.unpublished); if (validationResult !== true) { console.error('Invalid event:', validationResult); showToast('error', 'Error', `Invalid event: ${validationResult}`); return; } - const published = await unpublished.publish(); + const published = await lesson.unpublished.publish(); + savedLesson = await handlePostResource(lesson.unpublished); - const saved = await handlePostResource(unpublished); - - console.log('saved', saved); - - if (published && saved) { - axios.delete(`/api/drafts/${lesson?.d}`) - .then(res => { - if (res.status === 204) { - showToast('success', 'Success', 'Draft deleted successfully.'); - } else { - showToast('error', 'Error', 'Failed to delete draft.'); - } - }) - .catch(err => { - console.error(err); - }); + if (published && savedLesson) { + const deleted = await axios.delete(`/api/drafts/${lesson.d}`); + if (deleted && deleted.status === 204) { + const savedLesson = await handlePostLesson(lesson); + if (savedLesson) { + createdLessons.push(savedLesson); + } + } + } + } else { + const savedLesson = await handlePostLesson(lesson); + if (savedLesson) { + createdLessons.push(savedLesson); } } } + console.log('createdLessons', createdLessons); + // Step 2: Create and publish course const courseEvent = createCourseEvent(newCourseId, processedEvent.title, processedEvent.summary, processedEvent.image, processedLessons, processedEvent.price); const published = await courseEvent.publish(); - console.log('published', published); - if (!published) { throw new Error('Failed to publish course'); } // Step 3: Save course to db - await axios.post('/api/courses', { + const courseData = { id: newCourseId, - resources: { - connect: processedLessons.map(lesson => ({ id: lesson?.d })) + lessons: { + connect: createdLessons.map(lesson => ({ id: lesson.id })) }, noteId: courseEvent.id, user: { connect: { id: user.id } }, price: processedEvent?.price || 0 - }); + }; - // step 4: Update all resources to have the course id - await Promise.all(processedLessons.map(lesson => axios.put(`/api/resources/${lesson?.d}`, { courseId: newCourseId }))); + const createdCourse = await axios.post('/api/courses', courseData); + + // Step 4: Update all lessons to have the course id + await Promise.all(createdLessons.map(lesson => axios.put(`/api/lessons/${lesson.id}`, { courseId: newCourseId }))); // Step 5: Delete draft await axios.delete(`/api/courses/drafts/${processedEvent.id}`); @@ -292,13 +313,15 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons }) d: lesson?.id, kind: lesson?.price ? 30402 : 30023, pubkey: unsignedEvent.pubkey, + index: lesson.index, unpublished: unsignedEvent }]); } else { setProcessedLessons(prev => [...prev, { d: lesson?.d, kind: lesson?.price ? 30402 : 30023, - pubkey: lesson.pubkey + pubkey: lesson.pubkey, + index: lesson.index }]); } }); @@ -323,6 +346,9 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })

{processedEvent?.title}

{processedEvent?.summary}

+ {processedEvent?.price && ( +

Price: {processedEvent.price} sats

+ )}
avatar thumbnail {
)} + {lesson?.price && ( +

Price: {lesson.price} sats

+ )}
avatar thumbnail {
{isPublished ? ( <> - +