@@ -244,4 +290,4 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
);
}
-export default ResourceForm;
+export default ResourceForm;
\ No newline at end of file
diff --git a/src/components/forms/WorkshopForm.js b/src/components/forms/WorkshopForm.js
index 29976c1..4a5f456 100644
--- a/src/components/forms/WorkshopForm.js
+++ b/src/components/forms/WorkshopForm.js
@@ -8,6 +8,8 @@ import { Button } from 'primereact/button';
import { useToast } from '@/hooks/useToast';
import { useSession } from 'next-auth/react';
import 'primeicons/primeicons.css';
+import { Tooltip } from 'primereact/tooltip';
+import 'primereact/resources/primereact.min.css';
const WorkshopForm = ({ draft = null }) => {
const [title, setTitle] = useState(draft?.title || '');
@@ -17,6 +19,7 @@ const WorkshopForm = ({ draft = null }) => {
const [videoUrl, setVideoUrl] = useState(draft?.content || '');
const [coverImage, setCoverImage] = useState(draft?.image || '');
const [topics, setTopics] = useState(draft?.topics || ['']);
+ const [additionalLinks, setAdditionalLinks] = useState(draft?.additionalLinks || ['']);
const router = useRouter();
const { data: session, status } = useSession();
@@ -38,6 +41,7 @@ const WorkshopForm = ({ draft = null }) => {
setVideoUrl(draft.content);
setCoverImage(draft.image);
setTopics(draft.topics || ['']);
+ setAdditionalLinks(draft.additionalLinks || ['']);
}
}, [draft]);
@@ -72,7 +76,8 @@ const WorkshopForm = ({ draft = null }) => {
content: embedCode,
image: coverImage,
user: userResponse.data.id,
- topics: [...topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'workshop']
+ topics: [...topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'workshop'],
+ additionalLinks: additionalLinks.filter(link => link.trim() !== ''),
};
if (payload && payload.user) {
@@ -96,11 +101,6 @@ const WorkshopForm = ({ draft = null }) => {
}
};
- const onUpload = (event) => {
- showToast('success', 'Success', 'File Uploaded');
- console.log(event.files[0]);
- }
-
const handleTopicChange = (index, value) => {
const updatedTopics = topics.map((topic, i) => i === index ? value : topic);
setTopics(updatedTopics);
@@ -116,6 +116,22 @@ const WorkshopForm = ({ draft = null }) => {
const updatedTopics = topics.filter((_, i) => i !== index);
setTopics(updatedTopics);
};
+
+ const handleLinkChange = (index, value) => {
+ const updatedLinks = additionalLinks.map((link, i) => i === index ? value : link);
+ setAdditionalLinks(updatedLinks);
+ };
+
+ const addLink = (e) => {
+ e.preventDefault();
+ setAdditionalLinks([...additionalLinks, '']);
+ };
+
+ const removeLink = (e, index) => {
+ e.preventDefault();
+ const updatedLinks = additionalLinks.filter((_, i) => i !== index);
+ setAdditionalLinks(updatedLinks);
+ };
return (
@@ -143,6 +159,30 @@ const WorkshopForm = ({ draft = null }) => {
setCoverImage(e.target.value)} placeholder="Cover Image URL" />
+
+
+ Additional Links
+
+
+ {additionalLinks.map((link, index) => (
+
+ handleLinkChange(index, e.target.value)} placeholder="https://example.com" className="w-full mt-2" />
+ {index > 0 && (
+
+ ))}
+
+
+
+
+
{topics.map((topic, index) => (
@@ -163,4 +203,4 @@ const WorkshopForm = ({ draft = null }) => {
);
}
-export default WorkshopForm;
+export default WorkshopForm;
\ No newline at end of file
diff --git a/src/db/models/draftModels.js b/src/db/models/draftModels.js
index dc16d47..f00deb1 100644
--- a/src/db/models/draftModels.js
+++ b/src/db/models/draftModels.js
@@ -27,20 +27,22 @@ export const createDraft = async (data) => {
id: data.user,
},
},
+ additionalLinks: data.additionalLinks || [],
},
});
};
export const updateDraft = async (id, data) => {
- const { user, ...otherData } = data;
+ const { user, additionalLinks, ...otherData } = data;
return await prisma.draft.update({
where: { id },
data: {
...otherData,
user: user ? {
connect: { id: user }
- } : undefined
+ } : undefined,
+ additionalLinks: additionalLinks || undefined,
},
});
};
@@ -49,4 +51,4 @@ export const deleteDraft = async (id) => {
return await prisma.draft.delete({
where: { id },
});
-}
+}
\ No newline at end of file
diff --git a/src/pages/details/[slug]/edit.js b/src/pages/details/[slug]/edit.js
index b5919ff..84a3b89 100644
--- a/src/pages/details/[slug]/edit.js
+++ b/src/pages/details/[slug]/edit.js
@@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import { parseEvent } from "@/utils/nostr";
import ResourceForm from "@/components/forms/ResourceForm";
import WorkshopForm from "@/components/forms/WorkshopForm";
-import CourseForm from "@/components/forms/CourseForm";
+import CourseForm from "@/components/forms/course/CourseForm";
import { useNDKContext } from "@/context/NDKContext";
import { useToast } from "@/hooks/useToast";
diff --git a/src/pages/draft/[slug]/edit.js b/src/pages/draft/[slug]/edit.js
index 39a7925..f730028 100644
--- a/src/pages/draft/[slug]/edit.js
+++ b/src/pages/draft/[slug]/edit.js
@@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import axios from "axios";
import ResourceForm from "@/components/forms/ResourceForm";
import WorkshopForm from "@/components/forms/WorkshopForm";
-import CourseForm from "@/components/forms/CourseForm";
+import CourseForm from "@/components/forms/course/CourseForm";
const Edit = () => {
const [draft, setDraft] = useState(null);
diff --git a/src/pages/draft/[slug]/index.js b/src/pages/draft/[slug]/index.js
index 34996f9..bee1b5a 100644
--- a/src/pages/draft/[slug]/index.js
+++ b/src/pages/draft/[slug]/index.js
@@ -11,10 +11,13 @@ import { useToast } from '@/hooks/useToast';
import { Tag } from 'primereact/tag';
import { useNDKContext } from '@/context/NDKContext';
import { NDKEvent } from '@nostr-dev-kit/ndk';
+import { formatDateTime } from '@/utils/time';
import Image from 'next/image';
import useResponsiveImageDimensions from '@/hooks/useResponsiveImageDimensions';
import 'primeicons/primeicons.css';
import dynamic from 'next/dynamic';
+import { validateEvent } from '@/utils/nostr';
+
const MDDisplay = dynamic(
() => import("@uiw/react-markdown-preview"),
{
@@ -22,25 +25,6 @@ const MDDisplay = dynamic(
}
);
-function validateEvent(event) {
- if (typeof event.kind !== "number") return "Invalid kind";
- if (typeof event.content !== "string") return "Invalid content";
- if (typeof event.created_at !== "number") return "Invalid created_at";
- if (typeof event.pubkey !== "string") return "Invalid pubkey";
- if (!event.pubkey.match(/^[a-f0-9]{64}$/)) return "Invalid pubkey format";
-
- if (!Array.isArray(event.tags)) return "Invalid tags";
- for (let i = 0; i < event.tags.length; i++) {
- const tag = event.tags[i];
- if (!Array.isArray(tag)) return "Invalid tag structure";
- for (let j = 0; j < tag.length; j++) {
- if (typeof tag[j] === "object") return "Invalid tag value";
- }
- }
-
- return true;
-}
-
export default function Draft() {
const [draft, setDraft] = useState(null);
const { returnImageProxy } = useImageProxy();
@@ -206,6 +190,7 @@ export default function Draft() {
...draft.topics.map(topic => ['t', topic]),
['published_at', Math.floor(Date.now() / 1000).toString()],
...(draft?.price ? [['price', draft.price.toString()], ['location', `https://plebdevs.com/details/${draft.id}`]] : []),
+ ...(draft?.additionalLinks ? draft.additionalLinks.map(link => ['r', link]) : []),
];
type = 'resource';
@@ -228,6 +213,7 @@ export default function Draft() {
...draft.topics.map(topic => ['t', topic]),
['published_at', Math.floor(Date.now() / 1000).toString()],
...(draft?.price ? [['price', draft.price.toString()], ['location', `https://plebdevs.com/details/${draft.id}`]] : []),
+ ...(draft?.additionalLinks ? draft.additionalLinks.map(link => ['r', link]) : []),
];
type = 'workshop';
@@ -256,10 +242,24 @@ export default function Draft() {
{draft?.title}
{draft?.summary}
+ {draft?.additionalLinks && draft.additionalLinks.length > 0 && (
+
+ )}
)}
+
{draft?.createdAt && formatDateTime(draft?.createdAt)}
{draft && (
@@ -306,4 +307,4 @@ export default function Draft() {
);
-}
+}
\ No newline at end of file
diff --git a/src/utils/nostr.js b/src/utils/nostr.js
index 61d4f53..690ac6b 100644
--- a/src/utils/nostr.js
+++ b/src/utils/nostr.js
@@ -36,6 +36,7 @@ export const parseEvent = (event) => {
pubkey: event.pubkey || '',
content: event.content || '',
kind: event.kind || '',
+ additionalLinks: [],
title: '',
summary: '',
image: '',
@@ -83,6 +84,9 @@ export const parseEvent = (event) => {
case 't':
tag[1] !== "plebdevs" && eventData.topics.push(tag[1]);
break;
+ case 'r':
+ eventData.additionalLinks.push(tag[1]);
+ break;
default:
break;
}
@@ -144,6 +148,9 @@ export const parseCourseEvent = (event) => {
eventData.topics.push(topic);
});
break;
+ case 'r':
+ eventData.additionalLinks.push(tag[1]);
+ break;
default:
break;
}
@@ -155,3 +162,22 @@ export const parseCourseEvent = (event) => {
export const hexToNpub = (hex) => {
return nip19.npubEncode(hex);
}
+
+export function validateEvent(event) {
+ if (typeof event.kind !== "number") return "Invalid kind";
+ if (typeof event.content !== "string") return "Invalid content";
+ if (typeof event.created_at !== "number") return "Invalid created_at";
+ if (typeof event.pubkey !== "string") return "Invalid pubkey";
+ if (!event.pubkey.match(/^[a-f0-9]{64}$/)) return "Invalid pubkey format";
+
+ if (!Array.isArray(event.tags)) return "Invalid tags";
+ for (let i = 0; i < event.tags.length; i++) {
+ const tag = event.tags[i];
+ if (!Array.isArray(tag)) return "Invalid tag structure";
+ for (let j = 0; j < tag.length; j++) {
+ if (typeof tag[j] === "object") return "Invalid tag value";
+ }
+ }
+
+ return true;
+}