diff --git a/src/components/forms/CourseForm.js b/src/components/forms/CourseForm.js index 69be9bf..f134f3e 100644 --- a/src/components/forms/CourseForm.js +++ b/src/components/forms/CourseForm.js @@ -85,7 +85,7 @@ const CourseForm = () => { ['title', lesson.title], ['summary', lesson.summary], ['image', lesson.image], - ['t', ...lesson.topics], + ...lesson.topics.map(topic => ['t', topic]), ['published_at', Math.floor(Date.now() / 1000).toString()], ['price', lesson.price], ['location', `https://plebdevs.com/${lesson.topics[1]}/${lesson.id}`], @@ -101,7 +101,7 @@ const CourseForm = () => { ['title', lesson.title], ['summary', lesson.summary], ['image', lesson.image], - ['t', ...lesson.topics], + ...lesson.topics.map(topic => ['t', topic]), ['published_at', Math.floor(Date.now() / 1000).toString()] ] }; @@ -134,9 +134,10 @@ const CourseForm = () => { // // Parse the fields from the lessons to get all of the necessary information const parsedLessons = fetchedLessons.map((lesson) => { - const { id, pubkey, content, title, summary, image, published_at, d, topics } = parseEvent(lesson); + const { id, kind, pubkey, content, title, summary, image, published_at, d, topics } = parseEvent(lesson); return { id, + kind, pubkey, content, title, @@ -153,26 +154,24 @@ const CourseForm = () => { const courseEvent = { kind: 30005, created_at: Math.floor(Date.now() / 1000), - content: JSON.stringify({ - title, - summary, - price, - topics, - }), + content: "", tags: [ ['d', uuidv4()], ['name', title], ['picture', coverImage], ['about', summary], - parsedLessons.map((lesson) => ['a', `${lesson.kind}:${lesson.pubkey}:${lesson.d}`]), + ...parsedLessons.map((lesson) => ['a', `${lesson.kind}:${lesson.pubkey}:${lesson.d}`]), ], }; console.log('courseEvent:', courseEvent); + + // Sign the course event + const signedCourseEvent = await window?.nostr?.signEvent(courseEvent); + // Publish the course event using Nostr + // await publish(signedCourseEvent); } - // Publish the course event using Nostr - // await publishCourse(courseEvent); // Reset the form fields after publishing the course setTitle(''); diff --git a/src/components/forms/WorkshopForm.js b/src/components/forms/WorkshopForm.js index 3d55969..bc144cf 100644 --- a/src/components/forms/WorkshopForm.js +++ b/src/components/forms/WorkshopForm.js @@ -1,13 +1,10 @@ import React, { useState } from 'react'; import axios from 'axios'; +import router from 'next/router'; import { InputText } from 'primereact/inputtext'; import { InputNumber } from 'primereact/inputnumber'; import { InputSwitch } from 'primereact/inputswitch'; -import { FileUpload } from 'primereact/fileupload'; -import { verifyEvent, nip19 } from "nostr-tools" -import { useNostr } from '@/hooks/useNostr'; import { Button } from 'primereact/button'; -import { v4 as uuidv4 } from 'uuid'; import { useToast } from '@/hooks/useToast'; import { useLocalStorageWithEffect } from '@/hooks/useLocalStorage'; import 'primeicons/primeicons.css'; @@ -15,19 +12,19 @@ import 'primeicons/primeicons.css'; const WorkshopForm = () => { const [title, setTitle] = useState(''); const [summary, setSummary] = useState(''); - const [checked, setChecked] = useState(false); const [price, setPrice] = useState(0); + const [isPaidResource, setIsPaidResource] = useState(false); const [videoUrl, setVideoUrl] = useState(''); const [coverImage, setCoverImage] = useState(''); const [topics, setTopics] = useState(['']); + const router = useRouter(); + const [user] = useLocalStorageWithEffect('user', {}); const { showToast } = useToast(); - const { publishAll } = useNostr(); - - const handleSubmit = (e) => { + const handleSubmit = async (e) => { e.preventDefault(); let embedCode = ''; @@ -42,169 +39,42 @@ const WorkshopForm = () => { embedCode = ``; } // Add more conditions here for other video services + + const userResponse = await axios.get(`/api/users/${user.pubkey}`); + + if (!userResponse.data) { + showToast('error', 'Error', 'User not found', 'Please try again.'); + return; + } const payload = { title, summary, - isPaidResource: checked, - price: checked ? price : null, - embedCode, + type: 'workshop', + price: isPaidResource ? price : null, + content: embedCode, + image: coverImage, + user: userResponse.data.id, topics: [...topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'workshop'] }; - console.log(payload); - if (checked) { - broadcastPaidWorkshop(payload); - } else { - broadcastFreeWorkshop(payload); + if (payload && payload.user) { + axios.post('/api/drafts', payload) + .then(response => { + if (response.status === 201) { + showToast('success', 'Success', 'Workshop saved as draft.'); + + if (response.data?.id) { + router.push(`/draft/${response.data.id}`); + } + } + }) + .catch(error => { + console.error(error); + }); } }; - const broadcastFreeWorkshop = async (payload) => { - const newWorkshopId = uuidv4(); - const event = { - kind: 30023, - content: payload.embedCode, - created_at: Math.floor(Date.now() / 1000), - tags: [ - ['d', newWorkshopId], - ['title', payload.title], - ['summary', payload.summary], - ['image', ''], - ['t', ...topics], - ['published_at', Math.floor(Date.now() / 1000).toString()], - ] - }; - - const signedEvent = await window.nostr.signEvent(event); - - const eventVerification = await verifyEvent(signedEvent); - - if (!eventVerification) { - showToast('error', 'Error', 'Event verification failed. Please try again.'); - return; - } - - const nAddress = nip19.naddrEncode({ - pubkey: signedEvent.pubkey, - kind: signedEvent.kind, - identifier: newWorkshopId, - }) - - console.log('nAddress:', nAddress); - - const userResponse = await axios.get(`/api/users/${user.pubkey}`) - - if (!userResponse.data) { - showToast('error', 'Error', 'User not found', 'Please try again.'); - return; - } - - const resourcePayload = { - id: newWorkshopId, - userId: userResponse.data.id, - price: 0, - noteId: nAddress, - } - const response = await axios.post(`/api/resources`, resourcePayload); - - console.log('response:', response); - - if (response.status !== 201) { - showToast('error', 'Error', 'Failed to create resource. Please try again.'); - return; - } - - const publishResponse = await publishAll(signedEvent); - - if (!publishResponse) { - showToast('error', 'Error', 'Failed to publish resource. Please try again.'); - return; - } else if (publishResponse?.failedRelays) { - publishResponse?.failedRelays.map(relay => { - showToast('warn', 'Warning', `Failed to publish to relay: ${relay}`); - }); - } - - publishResponse?.successfulRelays.map(relay => { - showToast('success', 'Success', `Published to relay: ${relay}`); - }) - } - - // For images, whether included in the markdown content or not, clients SHOULD use image tags as described in NIP-58. This allows clients to display images in carousel format more easily. - const broadcastPaidWorkshop = async (payload) => { - // encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY - const encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY ,process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, payload.content); - const newWorkshopId = uuidv4(); - const event = { - kind: 30402, - content: encryptedContent, - created_at: Math.floor(Date.now() / 1000), - tags: [ - ['title', payload.title], - ['summary', payload.summary], - ['t', ...topics], - ['image', ''], - ['d', newresourceId], - ['location', `https://plebdevs.com/resource/${newWorkshopId}`], - ['published_at', Math.floor(Date.now() / 1000).toString()], - ['price', payload.price] - ] - }; - - const signedEvent = await window.nostr.signEvent(event); - - const eventVerification = await verifyEvent(signedEvent); - - if (!eventVerification) { - showToast('error', 'Error', 'Event verification failed. Please try again.'); - return; - } - - const nAddress = nip19.naddrEncode({ - pubkey: signedEvent.pubkey, - kind: signedEvent.kind, - identifier: newWorkshopId, - }) - - console.log('nAddress:', nAddress); - - const userResponse = await axios.get(`/api/users/${user.pubkey}`) - - if (!userResponse.data) { - showToast('error', 'Error', 'User not found', 'Please try again.'); - return; - } - - const resourcePayload = { - id: newWorkshopId, - userId: userResponse.data.id, - price: payload.price || 0, - noteId: nAddress, - } - const response = await axios.post(`/api/resources`, resourcePayload); - - if (response.status !== 201) { - showToast('error', 'Error', 'Failed to create resource. Please try again.'); - return; - } - - const publishResponse = await publishAll(signedEvent); - - if (!publishResponse) { - showToast('error', 'Error', 'Failed to publish resource. Please try again.'); - return; - } else if (publishResponse?.failedRelays) { - publishResponse?.failedRelays.map(relay => { - showToast('warn', 'Warning', `Failed to publish to relay: ${relay}`); - }); - } - - publishResponse?.successfulRelays.map(relay => { - showToast('success', 'Success', `Published to relay: ${relay}`); - }) - } - const onUpload = (event) => { showToast('success', 'Success', 'File Uploaded'); console.log(event.files[0]); @@ -236,8 +106,8 @@ const WorkshopForm = () => {
Paid Workshop
-