-
@ Marth
2024-08-18 23:02:09```js import React, { useEffect, useState, useCallback, useRef } from 'react'; import { useRouter } from 'next/router'; import { useImageProxy } from '@/hooks/useImageProxy'; import { Tag } from 'primereact/tag'; import { Button } from 'primereact/button'; import Image from 'next/image'; import dynamic from 'next/dynamic'; import axios from 'axios'; import { nip04, nip19 } from 'nostr-tools'; import { v4 as uuidv4 } from 'uuid'; import { useSession } from 'next-auth/react'; import { useNDKContext } from "@/context/NDKContext"; import { NDKEvent } from "@nostr-dev-kit/ndk"; import { findKind0Fields } from '@/utils/nostr'; import { useToast } from '@/hooks/useToast'; import 'primeicons/primeicons.css';
const MDDisplay = dynamic(() => import("@uiw/react-markdown-preview"), { ssr: false });
// ... keep the validateEvent function as is ...
export default function DraftCourseDetails({ processedEvent, draftId, lessons }) { // ... keep state declarations and hooks as is ...
const fetchAuthor = useCallback(async (pubkey) => { if (!pubkey) return; const author = await ndk.getUser({ pubkey }); const profile = await author.fetchProfile(); const fields = await findKind0Fields(profile); if (fields) setAuthor(fields); }, [ndk]); useEffect(() => { if (processedEvent) fetchAuthor(processedEvent?.user?.pubkey); }, [fetchAuthor, processedEvent]); useEffect(() => { if (session) setUser(session.user); }, [session]); const handleDelete = async () => { try { await axios.delete(`/api/courses/drafts/${processedEvent.id}`); showToast('success', 'Success', 'Draft Course deleted successfully'); router.push('/'); } catch (error) { showToast('error', 'Error', 'Failed to delete draft course'); } }; const handlePostResource = async (resource) => { // ... keep this function as is ... }; const createCourseEvent = (courseId, title, summary, coverImage, lessons, price) => { const event = new NDKEvent(ndk); event.kind = 30004; event.content = ""; event.tags = [ ['d', courseId], ['name', title], ['picture', coverImage], ['image', coverImage], ['description', summary], ['l', "Education"], ['price', price.toString()], ...lessons.map((lesson) => ['a', `${lesson.kind}:${lesson.pubkey}:${lesson.d}`]), ]; return event; }; const handleSubmit = async (e) => { e.preventDefault(); const newCourseId = uuidv4(); try { if (!ndk.signer) await addSigner(); // Process lessons await Promise.all(processedLessons.map(async (lesson) => { const unpublished = lesson?.unpublished; if (unpublished && Object.keys(unpublished).length > 0) { const validationResult = validateEvent(unpublished); if (validationResult !== true) { throw new Error(`Invalid event: ${validationResult}`); } const published = await unpublished.publish(); const saved = await handlePostResource(unpublished); if (published && saved) { await axios.delete(`/api/drafts/${lesson?.d}`); } } })); // Create and publish course const courseEvent = createCourseEvent(newCourseId, processedEvent.title, processedEvent.summary, processedEvent.image, processedLessons, processedEvent.price); const published = await courseEvent.publish(); if (!published) { throw new Error('Failed to publish course'); } // Save course to db await axios.post('/api/courses', { id: newCourseId, resources: { connect: processedLessons.map(lesson => ({ id: lesson?.d })) }, noteId: courseEvent.id, user: { connect: { id: user.id } }, price: processedEvent?.price || 0 }); // Update resources with course id await Promise.all(processedLessons.map(lesson => axios.put(`/api/resources/${lesson?.d}`, { courseId: newCourseId }) )); // Delete draft await axios.delete(`/api/courses/drafts/${processedEvent.id}`); showToast('success', 'Success', 'Course created successfully'); router.push(`/course/${courseEvent.id}`); } catch (error) { console.error('Error creating course:', error); showToast('error', 'Error', error.message || 'Failed to create course. Please try again.'); } }; useEffect(() => { const buildEvent = async (draft) => { // ... keep this function as is ... }; const buildDraftEvent = async (lesson) => { const { unsignedEvent } = await buildEvent(lesson); return unsignedEvent; }; const processLessons = async () => { if (!hasRunEffect.current && lessons.length > 0 && user && author) { hasRunEffect.current = true; const processedLessons = await Promise.all(lessons.map(async (lesson) => { const isDraft = !lesson?.pubkey; if (isDraft) { const unsignedEvent = await buildDraftEvent(lesson); return { d: lesson?.id, kind: lesson?.price ? 30402 : 30023, pubkey: unsignedEvent.pubkey, unpublished: unsignedEvent }; } else { return { d: lesson?.d, kind: lesson?.price ? 30402 : 30023, pubkey: lesson.pubkey }; } })); setProcessedLessons(processedLessons); } }; processLessons(); }, [lessons, user, author, ndk]); // ... keep the return statement (JSX) as is ...
} ```