progress on courseform

This commit is contained in:
austinkelsay 2024-04-28 17:00:58 -05:00
parent 76d40c6deb
commit 6572f8ec99
4 changed files with 142 additions and 55 deletions

View File

@ -25,7 +25,7 @@ const ContentDropdownItem = ({ content, onSelect, selected }) => {
</div> </div>
</div> </div>
</div> </div>
) );
} }
return ( return (

View File

@ -5,7 +5,7 @@ import { InputNumber } from "primereact/inputnumber";
import { InputSwitch } from "primereact/inputswitch"; import { InputSwitch } from "primereact/inputswitch";
import { Button } from "primereact/button"; import { Button } from "primereact/button";
import { Dropdown } from "primereact/dropdown"; import { Dropdown } from "primereact/dropdown";
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4, v4 } from 'uuid';
import { useLocalStorageWithEffect } from "@/hooks/useLocalStorage"; import { useLocalStorageWithEffect } from "@/hooks/useLocalStorage";
import { useNostr } from "@/hooks/useNostr"; import { useNostr } from "@/hooks/useNostr";
import { parseEvent } from "@/utils/nostr"; import { parseEvent } from "@/utils/nostr";
@ -25,7 +25,7 @@ const CourseForm = () => {
const [drafts, setDrafts] = useState([]); const [drafts, setDrafts] = useState([]);
const [resources, setResources] = useState([]); const [resources, setResources] = useState([]);
const [workshops, setWorkshops] = useState([]); const [workshops, setWorkshops] = useState([]);
const { fetchResources, fetchWorkshops } = useNostr(); const { fetchResources, fetchWorkshops, publish, fetchSingleEvent } = useNostr();
const [pubkey, setPubkey] = useState(''); const [pubkey, setPubkey] = useState('');
const fetchAllContent = async () => { const fetchAllContent = async () => {
@ -59,52 +59,130 @@ const CourseForm = () => {
} }
}, [user]); }, [user]);
console.log('lessons', selectedLessons);
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
const createdAt = Math.floor(Date.now() / 1000); // UNIX timestamp
const eventKind = 30050; // Custom kind for a course list
// Publish unpublished drafts as NIP-23 events // Set aside a list for all of the final ids in order
const publishedLessons = await Promise.all( const finalIds = [];
lessons.map(async (lesson) => {
console.log('lesson:', lesson); // Iterate over selectedLessons and process each lesson
if (lesson.type === 'draft') { for (const lesson of selectedLessons) {
const draftEvent = { if (lesson.published_at) {
kind: 30023, // If the lesson is already published, add its id to finalIds
created_at: createdAt, finalIds.push(lesson.id);
} else {
// If the lesson is unpublished, create an event and sign it
let event;
if (lesson.price) {
event = {
kind: 30402,
content: lesson.content, content: lesson.content,
created_at: Math.floor(Date.now() / 1000),
tags: [ tags: [
["d", lesson.id], ['d', lesson.id],
["title", lesson.title], ['title', lesson.title],
// Add other metadata tags as needed ['summary', lesson.summary],
], ['image', lesson.image],
pubkey: pubkey, ['t', ...lesson.topics],
['published_at', Math.floor(Date.now() / 1000).toString()],
['price', lesson.price],
['location', `https://plebdevs.com/${lesson.topics[1]}/${lesson.id}`],
]
};
} else {
event = {
kind: 30023,
content: lesson.content,
created_at: Math.floor(Date.now() / 1000),
tags: [
['d', lesson.id],
['title', lesson.title],
['summary', lesson.summary],
['image', lesson.image],
['t', ...lesson.topics],
['published_at', Math.floor(Date.now() / 1000).toString()]
]
}; };
console.log('draftEvent:', draftEvent);
return draftEvent;
} }
}));
const tags = [ // Sign the event
["title", title], const signedEvent = await window?.nostr?.signEvent(event);
["summary", summary],
["price", checked ? price.toString() : "free"],
["image", coverImage],
...publishedLessons.map(lesson => ["a", `30023:${lesson.id}:${lesson.id}`]),
...topics.map(topic => ["topic", topic.trim().toLowerCase()])
];
const content = JSON.stringify({ description: "Course content details" }); // Placeholder content // Add the signed event's id to finalIds
finalIds.push(signedEvent.id);
const courseEvent = { // Publish the lesson (uncomment the line below if you want to publish immediately)
kind: eventKind, // await publish(signedEvent);
created_at: createdAt, }
content: content, }
tags: tags,
pubkey: pubkey,
};
console.log('courseEvent:', courseEvent); console.log('finalIds:', finalIds);
const testIds = ["8e364adf6b81ef34d30f42bf0356a9b362bf928e178d7bcd4baa912623f6b3ee", "41bcee8f1293ee3cc221f5bc1417ee3f5accfa90ccec8db4f9eda7e8ffef5c30"]
// Fetch all of the lessons from Nostr by their ids
const fetchedLessons = await Promise.all(
testIds.map(async (id) => {
const lesson = await fetchSingleEvent(id);
return lesson;
})
);
console.log('fetchedLessons:', fetchedLessons);
// // 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);
return {
id,
pubkey,
content,
title,
summary,
image,
published_at,
d,
topics
};
});
if (parsedLessons.length === selectedLessons.length) {
// Create a new course event
const courseEvent = {
kind: 30005,
created_at: Math.floor(Date.now() / 1000),
content: JSON.stringify({
title,
summary,
price,
topics,
}),
tags: [
['d', uuidv4()],
['name', title],
['picture', coverImage],
['about', summary],
parsedLessons.map((lesson) => ['a', `${lesson.kind}:${lesson.pubkey}:${lesson.d}`]),
],
};
console.log('courseEvent:', courseEvent);
}
// Publish the course event using Nostr
// await publishCourse(courseEvent);
// Reset the form fields after publishing the course
setTitle('');
setSummary('');
setChecked(false);
setPrice(0);
setCoverImage('');
setLessons([{ id: uuidv4(), title: 'Select a lesson' }]);
setSelectedLessons([]);
setTopics(['']);
}; };
const handleLessonChange = (e, index) => { const handleLessonChange = (e, index) => {

View File

@ -39,7 +39,6 @@ export default function Details() {
const [author, setAuthor] = useState(null); const [author, setAuthor] = useState(null);
const [bitcoinConnect, setBitcoinConnect] = useState(false); const [bitcoinConnect, setBitcoinConnect] = useState(false);
const [nAddress, setNAddress] = useState(null); const [nAddress, setNAddress] = useState(null);
const [user] = useLocalStorageWithEffect('user', {}); const [user] = useLocalStorageWithEffect('user', {});
console.log('user:', user); console.log('user:', user);
const { returnImageProxy } = useImageProxy(); const { returnImageProxy } = useImageProxy();
@ -156,23 +155,26 @@ export default function Details() {
className="object-cover object-center rounded-lg" className="object-cover object-center rounded-lg"
/> />
{bitcoinConnect ? ( {bitcoinConnect ? (
<BitcoinConnectPayButton onClick={handleZapEvent} /> <div>
<BitcoinConnectPayButton onClick={handleZapEvent} />
</div>
) : ( ) : (
<div>
<Button <Button
icon="pi pi-bolt" icon="pi pi-bolt"
label="Zap" label="Zap"
severity="success" severity="success"
outlined outlined
onClick={handleZapEvent} onClick={handleZapEvent}
pt={{ pt={{
button: { button: {
icon: ({ context }) => ({ icon: ({ context }) => ({
className: 'bg-yellow-500' className: 'bg-yellow-500'
}) })
} }
}} }}
/> />
</div>
)} )}
</div> </div>
)} )}

View File

@ -22,6 +22,13 @@ const Login = () => {
rounded rounded
onClick={anonymousLogin} onClick={anonymousLogin}
/> />
<Button
label={"login with email"}
icon="pi pi-envelope"
className="text-[#f8f8ff] w-[250px] my-4"
rounded
onClick={anonymousLogin}
/>
</div> </div>
) )
} }