mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-06 18:31:00 +00:00
Changed resource to document on the frontend
This commit is contained in:
parent
aa13faaf44
commit
cb3f124c3a
@ -15,7 +15,7 @@ const BottomBar = () => {
|
|||||||
<i className="pi pi-home text-2xl" />
|
<i className="pi pi-home text-2xl" />
|
||||||
</div>
|
</div>
|
||||||
<div onClick={() => router.push('/content?tag=all')} className={`hover:bg-gray-700 cursor-pointer px-4 py-3 rounded-lg ${isActive('/content') ? 'bg-gray-700' : ''}`}>
|
<div onClick={() => router.push('/content?tag=all')} className={`hover:bg-gray-700 cursor-pointer px-4 py-3 rounded-lg ${isActive('/content') ? 'bg-gray-700' : ''}`}>
|
||||||
<i className="pi pi-video text-2xl" />
|
<i className="pi pi-play-circle text-2xl" />
|
||||||
</div>
|
</div>
|
||||||
<div onClick={() => router.push('/feed?channel=global')} className={`hover:bg-gray-700 cursor-pointer px-4 py-3 rounded-lg ${isActive('/feed') ? 'bg-gray-700' : ''}`}>
|
<div onClick={() => router.push('/feed?channel=global')} className={`hover:bg-gray-700 cursor-pointer px-4 py-3 rounded-lg ${isActive('/feed') ? 'bg-gray-700' : ''}`}>
|
||||||
<i className="pi pi-comments text-2xl" />
|
<i className="pi pi-comments text-2xl" />
|
||||||
|
@ -4,6 +4,7 @@ import { useImageProxy } from "@/hooks/useImageProxy";
|
|||||||
import { formatUnixTimestamp } from "@/utils/time";
|
import { formatUnixTimestamp } from "@/utils/time";
|
||||||
import GenericButton from "@/components/buttons/GenericButton";
|
import GenericButton from "@/components/buttons/GenericButton";
|
||||||
const SelectedContentItem = ({ content, onRemove }) => {
|
const SelectedContentItem = ({ content, onRemove }) => {
|
||||||
|
console.log('content:', content);
|
||||||
const { returnImageProxy } = useImageProxy();
|
const { returnImageProxy } = useImageProxy();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Carousel } from 'primereact/carousel';
|
import { Carousel } from 'primereact/carousel';
|
||||||
import { parseEvent } from '@/utils/nostr';
|
import { parseEvent } from '@/utils/nostr';
|
||||||
// import ResourceTemplate from '@/components/content/carousels/templates/ResourceTemplate';
|
|
||||||
import { DocumentTemplate } from '@/components/content/carousels/templates/DocumentTemplate';
|
import { DocumentTemplate } from '@/components/content/carousels/templates/DocumentTemplate';
|
||||||
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
import TemplateSkeleton from '@/components/content/carousels/skeletons/TemplateSkeleton';
|
||||||
import { useResources } from '@/hooks/nostr/useResources';
|
import { useDocuments } from '@/hooks/nostr/useDocuments';
|
||||||
|
|
||||||
const responsiveOptions = [
|
const responsiveOptions = [
|
||||||
{
|
{
|
||||||
@ -24,44 +23,42 @@ const responsiveOptions = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function ResourcesCarousel() {
|
export default function DocumentsCarousel() {
|
||||||
const [processedResources, setProcessedResources] = useState([]);
|
const [processedDocuments, setProcessedDocuments] = useState([]);
|
||||||
const { resources, resourcesLoading, resourcesError } = useResources()
|
const { documents, documentsLoading, documentsError } = useDocuments()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetch = async () => {
|
const fetch = async () => {
|
||||||
try {
|
try {
|
||||||
if (resources && resources.length > 0) {
|
if (documents && documents.length > 0) {
|
||||||
const processedResources = resources.map(resource => parseEvent(resource));
|
const processedDocuments = documents.map(document => parseEvent(document));
|
||||||
|
|
||||||
// Sort resources by created_at in descending order (most recent first)
|
// Sort documents by created_at in descending order (most recent first)
|
||||||
const sortedResources = processedResources.sort((a, b) => b.created_at - a.created_at);
|
const sortedDocuments = processedDocuments.sort((a, b) => b.created_at - a.created_at);
|
||||||
|
|
||||||
console.log("Sorted resources:", sortedResources);
|
setProcessedDocuments(sortedDocuments);
|
||||||
|
|
||||||
setProcessedResources(sortedResources);
|
|
||||||
} else {
|
} else {
|
||||||
console.log('No resources fetched or empty array returned');
|
console.log('No documents fetched or empty array returned');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching resources:', error);
|
console.error('Error fetching documents:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetch();
|
fetch();
|
||||||
}, [resources]);
|
}, [documents]);
|
||||||
|
|
||||||
if (resourcesError) {
|
if (documentsError) {
|
||||||
return <div>Error: {resourcesError.message}</div>
|
return <div>Error: {documentsError.message}</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="ml-[6%] mt-4">Resources</h3>
|
<h3 className="ml-[6%] mt-4">Documents</h3>
|
||||||
<Carousel
|
<Carousel
|
||||||
value={resourcesLoading || !processedResources.length ? [{}, {}, {}] : [...processedResources]}
|
value={documentsLoading || !processedDocuments.length ? [{}, {}, {}] : [...processedDocuments]}
|
||||||
numVisible={2}
|
numVisible={2}
|
||||||
itemTemplate={(item) =>
|
itemTemplate={(item) =>
|
||||||
processedResources.length > 0 ?
|
processedDocuments.length > 0 ?
|
||||||
<DocumentTemplate key={item.id} document={item} /> :
|
<DocumentTemplate key={item.id} document={item} /> :
|
||||||
<TemplateSkeleton key={Math.random()} />
|
<TemplateSkeleton key={Math.random()} />
|
||||||
}
|
}
|
@ -64,7 +64,7 @@ export default function GenericCarousel({items, selectedTopic, title}) {
|
|||||||
value={carouselItems}
|
value={carouselItems}
|
||||||
itemTemplate={(item) => {
|
itemTemplate={(item) => {
|
||||||
if (carouselItems.length > 0) {
|
if (carouselItems.length > 0) {
|
||||||
if (item.type === 'resource') {
|
if (item.type === 'document') {
|
||||||
return <DocumentTemplate key={item.id} document={item} />;
|
return <DocumentTemplate key={item.id} document={item} />;
|
||||||
} else if (item.type === 'video') {
|
} else if (item.type === 'video') {
|
||||||
return <VideoTemplate key={item.id} video={item} />;
|
return <VideoTemplate key={item.id} video={item} />;
|
||||||
|
@ -33,9 +33,9 @@ const promotions = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
category: "RESOURCES",
|
category: "DOCUMENTS",
|
||||||
title: "In-depth Resources and Documentation",
|
title: "In-depth Resources and Documentation",
|
||||||
description: "Access our extensive library of resources, including guides, documentation, and best practices for Bitcoin development.",
|
description: "Access our extensive library of documents, including guides, resources, and best practices for Bitcoin development.",
|
||||||
icon: "pi pi-file",
|
icon: "pi pi-file",
|
||||||
image: "https://img.freepik.com/free-photo/programming-background-with-person-working-with-codes-computer_23-2150010125.jpg",
|
image: "https://img.freepik.com/free-photo/programming-background-with-person-working-with-codes-computer_23-2150010125.jpg",
|
||||||
},
|
},
|
||||||
@ -101,9 +101,9 @@ const InteractivePromotionalCarousel = () => {
|
|||||||
return (
|
return (
|
||||||
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="View All Videos" className="w-fit py-2 font-semibold" size="small" outlined />
|
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="View All Videos" className="w-fit py-2 font-semibold" size="small" outlined />
|
||||||
);
|
);
|
||||||
case "RESOURCES":
|
case "DOCUMENTS":
|
||||||
return (
|
return (
|
||||||
<GenericButton onClick={() => router.push('/content?tag=resources')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Resources" className="w-fit py-2 font-semibold" size="small" outlined />
|
<GenericButton onClick={() => router.push('/content?tag=documents')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Documents" className="w-fit py-2 font-semibold" size="small" outlined />
|
||||||
);
|
);
|
||||||
case "COMMUNITY":
|
case "COMMUNITY":
|
||||||
return (
|
return (
|
||||||
@ -149,9 +149,9 @@ const InteractivePromotionalCarousel = () => {
|
|||||||
return (
|
return (
|
||||||
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="View All Videos" className="py-2 font-semibold" size="small" outlined />
|
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="View All Videos" className="py-2 font-semibold" size="small" outlined />
|
||||||
);
|
);
|
||||||
case "RESOURCES":
|
case "DOCUMENTS":
|
||||||
return (
|
return (
|
||||||
<GenericButton onClick={() => router.push('/content?tag=resources')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Resources" className="py-2 font-semibold" size="small" outlined />
|
<GenericButton onClick={() => router.push('/content?tag=documents')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Documents" className="py-2 font-semibold" size="small" outlined />
|
||||||
);
|
);
|
||||||
case "COMMUNITY":
|
case "COMMUNITY":
|
||||||
return (
|
return (
|
||||||
|
@ -94,14 +94,14 @@ export function CourseTemplate({ course }) {
|
|||||||
{course.description || course.summary && (
|
{course.description || course.summary && (
|
||||||
<>
|
<>
|
||||||
{course.description && (
|
{course.description && (
|
||||||
<div className="text-xl mt-4">
|
<div>
|
||||||
{course.description.split('\n').map((line, index) => (
|
{course.description.split('\n').map((line, index) => (
|
||||||
<p key={index}>{line}</p>
|
<p key={index}>{line}</p>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{course.summary && (
|
{course.summary && (
|
||||||
<div className="text-xl mt-4">
|
<div>
|
||||||
{course.summary.split('\n').map((line, index) => (
|
{course.summary.split('\n').map((line, index) => (
|
||||||
<p key={index}>{line}</p>
|
<p key={index}>{line}</p>
|
||||||
))}
|
))}
|
||||||
|
@ -82,14 +82,14 @@ export function DocumentTemplate({ document }) {
|
|||||||
{document.description || document.summary && (
|
{document.description || document.summary && (
|
||||||
<>
|
<>
|
||||||
{document.description && (
|
{document.description && (
|
||||||
<div className="text-xl mt-4">
|
<div>
|
||||||
{document.description.split('\n').map((line, index) => (
|
{document.description.split('\n').map((line, index) => (
|
||||||
<p key={index}>{line}</p>
|
<p key={index}>{line}</p>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{document.summary && (
|
{document.summary && (
|
||||||
<div className="text-xl mt-4">
|
<div>
|
||||||
{document.summary.split('\n').map((line, index) => (
|
{document.summary.split('\n').map((line, index) => (
|
||||||
<p key={index}>{line}</p>
|
<p key={index}>{line}</p>
|
||||||
))}
|
))}
|
||||||
|
@ -83,14 +83,14 @@ export function VideoTemplate({ video }) {
|
|||||||
{video.description || video.summary && (
|
{video.description || video.summary && (
|
||||||
<>
|
<>
|
||||||
{video.description && (
|
{video.description && (
|
||||||
<div className="text-xl mt-4">
|
<div>
|
||||||
{video.description.split('\n').map((line, index) => (
|
{video.description.split('\n').map((line, index) => (
|
||||||
<p key={index}>{line}</p>
|
<p key={index}>{line}</p>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{video.summary && (
|
{video.summary && (
|
||||||
<div className="text-xl mt-4">
|
<div>
|
||||||
{video.summary.split('\n').map((line, index) => (
|
{video.summary.split('\n').map((line, index) => (
|
||||||
<p key={index}>{line}</p>
|
<p key={index}>{line}</p>
|
||||||
))}
|
))}
|
||||||
|
@ -95,7 +95,7 @@ const CourseLesson = ({ lesson, course, decryptionPerformed, isPaid }) => {
|
|||||||
{lesson && (
|
{lesson && (
|
||||||
<div className='flex flex-col items-center justify-between rounded-lg h-72 p-4 bg-gray-700 drop-shadow-md'>
|
<div className='flex flex-col items-center justify-between rounded-lg h-72 p-4 bg-gray-700 drop-shadow-md'>
|
||||||
<Image
|
<Image
|
||||||
alt="resource thumbnail"
|
alt="course thumbnail"
|
||||||
src={returnImageProxy(lesson.image)}
|
src={returnImageProxy(lesson.image)}
|
||||||
width={344}
|
width={344}
|
||||||
height={194}
|
height={194}
|
||||||
|
@ -130,8 +130,6 @@ const DocumentLesson = ({ lesson, course, decryptionPerformed, isPaid }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Divider />
|
<Divider />
|
||||||
</div>
|
|
||||||
{renderContent()}
|
|
||||||
{lesson?.additionalLinks && lesson.additionalLinks.length > 0 && (
|
{lesson?.additionalLinks && lesson.additionalLinks.length > 0 && (
|
||||||
<div className='mt-6 bg-gray-800/90 rounded-lg p-4'>
|
<div className='mt-6 bg-gray-800/90 rounded-lg p-4'>
|
||||||
<h3 className='text-lg font-semibold mb-2 text-white'>External links:</h3>
|
<h3 className='text-lg font-semibold mb-2 text-white'>External links:</h3>
|
||||||
@ -147,6 +145,8 @@ const DocumentLesson = ({ lesson, course, decryptionPerformed, isPaid }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{renderContent()}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })
|
|||||||
|
|
||||||
// Step 6: Show success message and redirect
|
// Step 6: Show success message and redirect
|
||||||
showToast('success', 'Success', 'Course created successfully');
|
showToast('success', 'Success', 'Course created successfully');
|
||||||
router.push(`/course/${courseEvent.id}`);
|
router.push("/");
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error creating course:', error);
|
console.error('Error creating course:', error);
|
||||||
@ -252,7 +252,7 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })
|
|||||||
console.log('Draft:', draft);
|
console.log('Draft:', draft);
|
||||||
|
|
||||||
switch (draft?.type) {
|
switch (draft?.type) {
|
||||||
case 'resource':
|
case 'document':
|
||||||
if (draft?.price) {
|
if (draft?.price) {
|
||||||
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
||||||
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY, process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY, process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
||||||
@ -273,7 +273,7 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })
|
|||||||
...(draft?.additionalLinks ? draft.additionalLinks.map(link => ['r', link]) : []),
|
...(draft?.additionalLinks ? draft.additionalLinks.map(link => ['r', link]) : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
type = 'resource';
|
type = 'document';
|
||||||
break;
|
break;
|
||||||
case 'video':
|
case 'video':
|
||||||
if (draft?.price) {
|
if (draft?.price) {
|
||||||
|
@ -110,7 +110,7 @@ const DraftCourseLesson = ({ lesson, course }) => {
|
|||||||
{lesson && (
|
{lesson && (
|
||||||
<div className='flex flex-col items-center justify-between rounded-lg h-72 p-4 bg-gray-700 drop-shadow-md'>
|
<div className='flex flex-col items-center justify-between rounded-lg h-72 p-4 bg-gray-700 drop-shadow-md'>
|
||||||
<Image
|
<Image
|
||||||
alt="resource thumbnail"
|
alt="course thumbnail"
|
||||||
src={returnImageProxy(lesson.image)}
|
src={returnImageProxy(lesson.image)}
|
||||||
width={344}
|
width={344}
|
||||||
height={194}
|
height={194}
|
||||||
|
@ -22,7 +22,7 @@ import { Tooltip } from 'primereact/tooltip';
|
|||||||
import 'primereact/resources/primereact.min.css';
|
import 'primereact/resources/primereact.min.css';
|
||||||
|
|
||||||
// todo make the summarry save in a formatted way so we can keep this spaces and line breaks
|
// todo make the summarry save in a formatted way so we can keep this spaces and line breaks
|
||||||
const ResourceForm = ({ draft = null, isPublished = false }) => {
|
const DocumentForm = ({ draft = null, isPublished = false }) => {
|
||||||
const [title, setTitle] = useState(draft?.title || '');
|
const [title, setTitle] = useState(draft?.title || '');
|
||||||
const [summary, setSummary] = useState(draft?.summary || '');
|
const [summary, setSummary] = useState(draft?.summary || '');
|
||||||
const [isPaidResource, setIsPaidResource] = useState(draft?.price ? true : false);
|
const [isPaidResource, setIsPaidResource] = useState(draft?.price ? true : false);
|
||||||
@ -104,7 +104,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
|||||||
content,
|
content,
|
||||||
d: draft.d,
|
d: draft.d,
|
||||||
image: coverImage,
|
image: coverImage,
|
||||||
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'resource'])],
|
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'document'])],
|
||||||
additionalLinks: additionalLinks.filter(link => link.trim() !== '')
|
additionalLinks: additionalLinks.filter(link => link.trim() !== '')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,14 +127,14 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
|||||||
// update the resource with new noteId
|
// update the resource with new noteId
|
||||||
const response = await axios.put(`/api/resources/${draft.d}`, { noteId: event.id });
|
const response = await axios.put(`/api/resources/${draft.d}`, { noteId: event.id });
|
||||||
console.log('response', response);
|
console.log('response', response);
|
||||||
showToast('success', 'Success', 'Resource published successfully.');
|
showToast('success', 'Success', 'Document published successfully.');
|
||||||
router.push(`/details/${event.id}`);
|
router.push(`/details/${event.id}`);
|
||||||
} else {
|
} else {
|
||||||
showToast('error', 'Error', 'Failed to publish resource. Please try again.');
|
showToast('error', 'Error', 'Failed to publish document. Please try again.');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
showToast('error', 'Error', 'Failed to publish resource. Please try again.');
|
showToast('error', 'Error', 'Failed to publish document. Please try again.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,11 +151,11 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
|||||||
const payload = {
|
const payload = {
|
||||||
title,
|
title,
|
||||||
summary,
|
summary,
|
||||||
type: 'resource',
|
type: 'document',
|
||||||
price: isPaidResource ? price : null,
|
price: isPaidResource ? price : null,
|
||||||
content,
|
content,
|
||||||
image: coverImage,
|
image: coverImage,
|
||||||
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'resource'])],
|
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'document'])],
|
||||||
additionalLinks: additionalLinks.filter(link => link.trim() !== '')
|
additionalLinks: additionalLinks.filter(link => link.trim() !== '')
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
|||||||
axios[method](url, payload)
|
axios[method](url, payload)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.status === 200 || response.status === 201) {
|
if (response.status === 200 || response.status === 201) {
|
||||||
showToast('success', 'Success', draft ? 'Resource updated successfully.' : 'Resource saved as draft.');
|
showToast('success', 'Success', draft ? 'Document updated successfully.' : 'Document saved as draft.');
|
||||||
|
|
||||||
if (response.data?.id) {
|
if (response.data?.id) {
|
||||||
router.push(`/draft/${response.data.id}`);
|
router.push(`/draft/${response.data.id}`);
|
||||||
@ -180,7 +180,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
showToast('error', 'Error', 'Failed to save resource. Please try again.');
|
showToast('error', 'Error', 'Failed to save document. Please try again.');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -230,7 +230,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="p-inputgroup flex-1 mt-8 flex-col">
|
<div className="p-inputgroup flex-1 mt-8 flex-col">
|
||||||
<p className="py-2">Paid Resource</p>
|
<p className="py-2">Paid Document</p>
|
||||||
<InputSwitch autoResize checked={isPaidResource} onChange={(e) => setIsPaidResource(e.value)} />
|
<InputSwitch autoResize checked={isPaidResource} onChange={(e) => setIsPaidResource(e.value)} />
|
||||||
{isPaidResource && (
|
{isPaidResource && (
|
||||||
<div className="p-inputgroup flex-1 py-4">
|
<div className="p-inputgroup flex-1 py-4">
|
||||||
@ -292,4 +292,4 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ResourceForm;
|
export default DocumentForm;
|
@ -9,7 +9,7 @@ import { useRouter } from 'next/router';
|
|||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { parseEvent } from '@/utils/nostr';
|
import { parseEvent } from '@/utils/nostr';
|
||||||
import { useDraftsQuery } from '@/hooks/apiQueries/useDraftsQuery';
|
import { useDraftsQuery } from '@/hooks/apiQueries/useDraftsQuery';
|
||||||
import { useResources } from '@/hooks/nostr/useResources';
|
import { useDocuments } from '@/hooks/nostr/useDocuments';
|
||||||
import { useVideos } from '@/hooks/nostr/useVideos';
|
import { useVideos } from '@/hooks/nostr/useVideos';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import LessonSelector from './LessonSelector';
|
import LessonSelector from './LessonSelector';
|
||||||
@ -27,16 +27,17 @@ const CourseForm = ({ draft = null }) => {
|
|||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { showToast } = useToast();
|
const { showToast } = useToast();
|
||||||
const { resources, resourcesLoading, resourcesError } = useResources();
|
const { documents, documentsLoading, documentsError } = useDocuments();
|
||||||
const { videos, videosLoading, videosError } = useVideos();
|
const { videos, videosLoading, videosError } = useVideos();
|
||||||
const { drafts, draftsLoading, draftsError } = useDraftsQuery();
|
const { drafts, draftsLoading, draftsError } = useDraftsQuery();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (draft && resources && videos && drafts) {
|
if (draft && documents && videos && drafts) {
|
||||||
const populatedLessons = draft.draftLessons.map((lesson, index) => {
|
const populatedLessons = draft.draftLessons.map((lesson, index) => {
|
||||||
if (lesson?.resource) {
|
if (lesson?.resource) {
|
||||||
const matchingResource = resources.find((resource) => resource.d === lesson.resource.d);
|
const matchingResource = documents.find((resource) => resource.d === lesson.resource.d);
|
||||||
return { ...parseEvent(matchingResource), index };
|
const matchingParsedResource = parseEvent(matchingResource);
|
||||||
|
return { ...matchingParsedResource, index };
|
||||||
} else if (lesson?.draft) {
|
} else if (lesson?.draft) {
|
||||||
const matchingDraft = drafts.find((draft) => draft.id === lesson.draft.id);
|
const matchingDraft = drafts.find((draft) => draft.id === lesson.draft.id);
|
||||||
return { ...matchingDraft, index };
|
return { ...matchingDraft, index };
|
||||||
@ -46,24 +47,15 @@ const CourseForm = ({ draft = null }) => {
|
|||||||
|
|
||||||
setLessons(populatedLessons);
|
setLessons(populatedLessons);
|
||||||
}
|
}
|
||||||
}, [draft, resources, videos, drafts]);
|
}, [draft, documents, videos, drafts]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('allContent', allContent);
|
if (!documentsLoading && !videosLoading && !draftsLoading) {
|
||||||
}, [allContent]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('fasfsa', videos)
|
|
||||||
}, [videos])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!resourcesLoading && !videosLoading && !draftsLoading) {
|
|
||||||
let combinedContent = [];
|
let combinedContent = [];
|
||||||
if (resources) {
|
if (documents) {
|
||||||
combinedContent = [...combinedContent, ...resources];
|
combinedContent = [...combinedContent, ...documents];
|
||||||
}
|
}
|
||||||
if (videos) {
|
if (videos) {
|
||||||
console.log('workssdfsdfdsf', videos)
|
|
||||||
combinedContent = [...combinedContent, ...videos];
|
combinedContent = [...combinedContent, ...videos];
|
||||||
}
|
}
|
||||||
if (drafts) {
|
if (drafts) {
|
||||||
@ -71,7 +63,7 @@ const CourseForm = ({ draft = null }) => {
|
|||||||
}
|
}
|
||||||
setAllContent(combinedContent);
|
setAllContent(combinedContent);
|
||||||
}
|
}
|
||||||
}, [resources, videos, drafts, resourcesLoading, videosLoading, draftsLoading]);
|
}, [documents, videos, drafts, documentsLoading, videosLoading, draftsLoading]);
|
||||||
|
|
||||||
const handleSubmit = async (event) => {
|
const handleSubmit = async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -171,7 +163,7 @@ const CourseForm = ({ draft = null }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (resourcesLoading || videosLoading || draftsLoading) {
|
if (documentsLoading || videosLoading || draftsLoading) {
|
||||||
return <ProgressSpinner />;
|
return <ProgressSpinner />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,14 +3,14 @@ import { Dropdown } from 'primereact/dropdown';
|
|||||||
import GenericButton from '@/components/buttons/GenericButton';
|
import GenericButton from '@/components/buttons/GenericButton';
|
||||||
import { Dialog } from 'primereact/dialog';
|
import { Dialog } from 'primereact/dialog';
|
||||||
import { Accordion, AccordionTab } from 'primereact/accordion';
|
import { Accordion, AccordionTab } from 'primereact/accordion';
|
||||||
import EmbeddedResourceForm from '@/components/forms/course/embedded/EmbeddedResourceForm';
|
import EmbeddedDocumentForm from '@/components/forms/course/embedded/EmbeddedDocumentForm';
|
||||||
import EmbeddedVideoForm from '@/components/forms/course/embedded/EmbeddedVideoForm';
|
import EmbeddedVideoForm from '@/components/forms/course/embedded/EmbeddedVideoForm';
|
||||||
import ContentDropdownItem from '@/components/content/dropdowns/ContentDropdownItem';
|
import ContentDropdownItem from '@/components/content/dropdowns/ContentDropdownItem';
|
||||||
import SelectedContentItem from '@/components/content/SelectedContentItem';
|
import SelectedContentItem from '@/components/content/SelectedContentItem';
|
||||||
import { parseEvent } from '@/utils/nostr';
|
import { parseEvent } from '@/utils/nostr';
|
||||||
|
|
||||||
const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewResourceCreate, onNewVideoCreate }) => {
|
const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewResourceCreate, onNewVideoCreate }) => {
|
||||||
const [showResourceForm, setShowResourceForm] = useState(false);
|
const [showDocumentForm, setShowDocumentForm] = useState(false);
|
||||||
const [showVideoForm, setShowVideoForm] = useState(false);
|
const [showVideoForm, setShowVideoForm] = useState(false);
|
||||||
const [contentOptions, setContentOptions] = useState([]);
|
const [contentOptions, setContentOptions] = useState([]);
|
||||||
const [openTabs, setOpenTabs] = useState([]);
|
const [openTabs, setOpenTabs] = useState([]);
|
||||||
@ -47,7 +47,7 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
|
|||||||
|
|
||||||
console.log('filtered content', filteredContent)
|
console.log('filtered content', filteredContent)
|
||||||
|
|
||||||
const draftResourceOptions = filteredContent.filter(content => content?.topics.includes('resource') && !content.kind).map(content => ({
|
const draftDocumentOptions = filteredContent.filter(content => content?.topics.includes('document') && !content.kind).map(content => ({
|
||||||
label: content.title,
|
label: content.title,
|
||||||
value: content
|
value: content
|
||||||
}));
|
}));
|
||||||
@ -57,7 +57,7 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
|
|||||||
value: content
|
value: content
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const resourceOptions = filteredContent.filter(content => content?.topics.includes('resource') && content.kind).map(content => ({
|
const documentOptions = filteredContent.filter(content => content?.topics.includes('document') && content.kind).map(content => ({
|
||||||
label: content.title,
|
label: content.title,
|
||||||
value: content
|
value: content
|
||||||
}));
|
}));
|
||||||
@ -69,16 +69,16 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
|
|||||||
|
|
||||||
setContentOptions([
|
setContentOptions([
|
||||||
{
|
{
|
||||||
label: 'Draft Resources',
|
label: 'Draft Documents',
|
||||||
items: draftResourceOptions
|
items: draftDocumentOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Draft Videos',
|
label: 'Draft Videos',
|
||||||
items: draftVideoOptions
|
items: draftVideoOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Published Resources',
|
label: 'Published Documents',
|
||||||
items: resourceOptions
|
items: documentOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Published Videos',
|
label: 'Published Videos',
|
||||||
@ -116,16 +116,15 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
|
|||||||
setLessons([...lessons, { index: lessons.length }]);
|
setLessons([...lessons, { index: lessons.length }]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNewResourceSave = async (newResource) => {
|
const handleNewDocumentSave = async (newDocument) => {
|
||||||
const createdResource = await onNewResourceCreate(newResource);
|
const createdDocument = await onNewDocumentCreate(newDocument);
|
||||||
if (createdResource) {
|
if (createdDocument) {
|
||||||
handleContentSelect(createdResource, lessons.length);
|
handleContentSelect(createdDocument, lessons.length);
|
||||||
setShowResourceForm(false);
|
setShowDocumentForm(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNewVideoSave = async (newVideo) => {
|
const handleNewVideoSave = async (newVideo) => {
|
||||||
console.log('newVideo', newVideo);
|
|
||||||
const createdVideo = await onNewVideoCreate(newVideo);
|
const createdVideo = await onNewVideoCreate(newVideo);
|
||||||
if (createdVideo) {
|
if (createdVideo) {
|
||||||
handleContentSelect(createdVideo, lessons.length);
|
handleContentSelect(createdVideo, lessons.length);
|
||||||
@ -167,7 +166,7 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
|
|||||||
<div className="flex mt-4">
|
<div className="flex mt-4">
|
||||||
{lesson.id ? null : (
|
{lesson.id ? null : (
|
||||||
<>
|
<>
|
||||||
<GenericButton label="New Resource" onClick={(e) => {e.preventDefault(); setShowResourceForm(true)}} className="mr-2" />
|
<GenericButton label="New Document" onClick={(e) => {e.preventDefault(); setShowDocumentForm(true)}} className="mr-2" />
|
||||||
<GenericButton label="New Video" onClick={(e) => {e.preventDefault(); setShowVideoForm(true)}} className="mr-2" />
|
<GenericButton label="New Video" onClick={(e) => {e.preventDefault(); setShowVideoForm(true)}} className="mr-2" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -187,11 +186,11 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
|
|||||||
label="Add New Lesson"
|
label="Add New Lesson"
|
||||||
onClick={addNewLesson}
|
onClick={addNewLesson}
|
||||||
className="mt-4"
|
className="mt-4"
|
||||||
type="button" // Explicitly set type to "button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Dialog className='w-full max-w-screen-md' visible={showResourceForm} onHide={() => setShowResourceForm(false)} header="Create New Resource">
|
<Dialog className='w-full max-w-screen-md' visible={showDocumentForm} onHide={() => setShowDocumentForm(false)} header="Create New Document">
|
||||||
<EmbeddedResourceForm onSave={handleNewResourceSave} isPaid={isPaidCourse} />
|
<EmbeddedDocumentForm onSave={handleNewDocumentSave} isPaid={isPaidCourse} />
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<Dialog className='w-full max-w-screen-md' visible={showVideoForm} onHide={() => setShowVideoForm(false)} header="Create New Video">
|
<Dialog className='w-full max-w-screen-md' visible={showVideoForm} onHide={() => setShowVideoForm(false)} header="Create New Video">
|
||||||
|
@ -19,7 +19,7 @@ import 'primeicons/primeicons.css';
|
|||||||
import { Tooltip } from 'primereact/tooltip';
|
import { Tooltip } from 'primereact/tooltip';
|
||||||
import 'primereact/resources/primereact.min.css';
|
import 'primereact/resources/primereact.min.css';
|
||||||
|
|
||||||
const EmbeddedResourceForm = ({ draft = null, isPublished = false, onSave, isPaid }) => {
|
const EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPaid }) => {
|
||||||
const [title, setTitle] = useState(draft?.title || '');
|
const [title, setTitle] = useState(draft?.title || '');
|
||||||
const [summary, setSummary] = useState(draft?.summary || '');
|
const [summary, setSummary] = useState(draft?.summary || '');
|
||||||
const [isPaidResource, setIsPaidResource] = useState(isPaid);
|
const [isPaidResource, setIsPaidResource] = useState(isPaid);
|
||||||
@ -96,11 +96,11 @@ const EmbeddedResourceForm = ({ draft = null, isPublished = false, onSave, isPai
|
|||||||
const payload = {
|
const payload = {
|
||||||
title,
|
title,
|
||||||
summary,
|
summary,
|
||||||
type: 'resource',
|
type: 'document',
|
||||||
price: isPaidResource ? price : null,
|
price: isPaidResource ? price : null,
|
||||||
content,
|
content,
|
||||||
image: coverImage,
|
image: coverImage,
|
||||||
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'resource'])],
|
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'document'])],
|
||||||
additionalLinks: additionalLinks.filter(link => link.trim() !== ''),
|
additionalLinks: additionalLinks.filter(link => link.trim() !== ''),
|
||||||
user: user?.id || user?.pubkey
|
user: user?.id || user?.pubkey
|
||||||
};
|
};
|
||||||
@ -108,10 +108,10 @@ const EmbeddedResourceForm = ({ draft = null, isPublished = false, onSave, isPai
|
|||||||
if (onSave) {
|
if (onSave) {
|
||||||
try {
|
try {
|
||||||
await onSave(payload);
|
await onSave(payload);
|
||||||
showToast('success', 'Success', draft ? 'Resource updated successfully.' : 'Resource created successfully.');
|
showToast('success', 'Success', draft ? 'Document updated successfully.' : 'Document created successfully.');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
showToast('error', 'Error', 'Failed to save resource. Please try again.');
|
showToast('error', 'Error', 'Failed to save document. Please try again.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -161,7 +161,7 @@ const EmbeddedResourceForm = ({ draft = null, isPublished = false, onSave, isPai
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="p-inputgroup flex-1 mt-8 flex-col">
|
<div className="p-inputgroup flex-1 mt-8 flex-col">
|
||||||
<p className="py-2">Paid Resource</p>
|
<p className="py-2">Paid Document</p>
|
||||||
<InputSwitch checked={isPaidResource} onChange={(e) => setIsPaidResource(e.value)} />
|
<InputSwitch checked={isPaidResource} onChange={(e) => setIsPaidResource(e.value)} />
|
||||||
{isPaidResource && (
|
{isPaidResource && (
|
||||||
<div className="p-inputgroup flex-1 py-4">
|
<div className="p-inputgroup flex-1 py-4">
|
||||||
@ -223,4 +223,4 @@ const EmbeddedResourceForm = ({ draft = null, isPublished = false, onSave, isPai
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EmbeddedResourceForm;
|
export default EmbeddedDocumentForm;
|
@ -3,7 +3,7 @@ import { useRouter } from "next/router";
|
|||||||
import GenericButton from "@/components/buttons/GenericButton";
|
import GenericButton from "@/components/buttons/GenericButton";
|
||||||
import MenuTab from "@/components/menutab/MenuTab";
|
import MenuTab from "@/components/menutab/MenuTab";
|
||||||
import { useCourses } from "@/hooks/nostr/useCourses";
|
import { useCourses } from "@/hooks/nostr/useCourses";
|
||||||
import { useResources } from "@/hooks/nostr/useResources";
|
import { useDocuments } from "@/hooks/nostr/useDocuments";
|
||||||
import { useVideos } from "@/hooks/nostr/useVideos";
|
import { useVideos } from "@/hooks/nostr/useVideos";
|
||||||
import { useDraftsQuery } from "@/hooks/apiQueries/useDraftsQuery";
|
import { useDraftsQuery } from "@/hooks/apiQueries/useDraftsQuery";
|
||||||
import { useCourseDraftsQuery } from "@/hooks/apiQueries/useCourseDraftsQuery";
|
import { useCourseDraftsQuery } from "@/hooks/apiQueries/useCourseDraftsQuery";
|
||||||
@ -31,7 +31,7 @@ const UserContent = () => {
|
|||||||
const { showToast } = useToast();
|
const { showToast } = useToast();
|
||||||
const {ndk, addSigner} = useNDKContext();
|
const {ndk, addSigner} = useNDKContext();
|
||||||
const { courses, coursesLoading, coursesError } = useCourses();
|
const { courses, coursesLoading, coursesError } = useCourses();
|
||||||
const { resources, resourcesLoading, resourcesError } = useResources();
|
const { documents, documentsLoading, documentsError } = useDocuments();
|
||||||
const { videos, videosLoading, videosError } = useVideos();
|
const { videos, videosLoading, videosError } = useVideos();
|
||||||
const { courseDrafts, courseDraftsLoading, courseDraftsError } = useCourseDraftsQuery();
|
const { courseDrafts, courseDraftsLoading, courseDraftsError } = useCourseDraftsQuery();
|
||||||
const { drafts, draftsLoading, draftsError } = useDraftsQuery();
|
const { drafts, draftsLoading, draftsError } = useDraftsQuery();
|
||||||
@ -51,7 +51,7 @@ const UserContent = () => {
|
|||||||
{ label: "Published", icon: "pi pi-verified" },
|
{ label: "Published", icon: "pi pi-verified" },
|
||||||
{ label: "Drafts", icon: "pi pi-file-edit" },
|
{ label: "Drafts", icon: "pi pi-file-edit" },
|
||||||
{ label: "Draft Courses", icon: "pi pi-book" },
|
{ label: "Draft Courses", icon: "pi pi-book" },
|
||||||
{ label: "Resources", icon: "pi pi-file" },
|
{ label: "Documents", icon: "pi pi-file" },
|
||||||
{ label: "Videos", icon: "pi pi-video" },
|
{ label: "Videos", icon: "pi pi-video" },
|
||||||
{ label: "Courses", icon: "pi pi-desktop" },
|
{ label: "Courses", icon: "pi pi-desktop" },
|
||||||
];
|
];
|
||||||
@ -98,8 +98,8 @@ const UserContent = () => {
|
|||||||
case 2:
|
case 2:
|
||||||
return courseDrafts || [];
|
return courseDrafts || [];
|
||||||
case 3:
|
case 3:
|
||||||
return resources?.map(parseEvent) || [];
|
return documents?.map(parseEvent) || [];
|
||||||
case 3:
|
case 4:
|
||||||
return videos?.map(parseEvent) || [];
|
return videos?.map(parseEvent) || [];
|
||||||
case 4:
|
case 4:
|
||||||
return courses?.map(parseEvent) || [];
|
return courses?.map(parseEvent) || [];
|
||||||
@ -110,10 +110,10 @@ const UserContent = () => {
|
|||||||
|
|
||||||
setContent(getContentByIndex(activeIndex));
|
setContent(getContentByIndex(activeIndex));
|
||||||
}
|
}
|
||||||
}, [activeIndex, isClient, drafts, resources, videos, courses, publishedContent, courseDrafts])
|
}, [activeIndex, isClient, drafts, documents, videos, courses, publishedContent, courseDrafts])
|
||||||
|
|
||||||
const isLoading = coursesLoading || resourcesLoading || videosLoading || draftsLoading || contentIdsLoading || courseDraftsLoading;
|
const isLoading = coursesLoading || documentsLoading || videosLoading || draftsLoading || contentIdsLoading || courseDraftsLoading;
|
||||||
const isError = coursesError || resourcesError || videosError || draftsError || contentIdsError || courseDraftsError;
|
const isError = coursesError || documentsError || videosError || draftsError || contentIdsError || courseDraftsError;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
|
@ -40,6 +40,7 @@ const Sidebar = ({ course = false }) => {
|
|||||||
if (router.isReady) {
|
if (router.isReady) {
|
||||||
const { slug } = router.query;
|
const { slug } = router.query;
|
||||||
|
|
||||||
|
try {
|
||||||
if (slug && course) {
|
if (slug && course) {
|
||||||
const { data } = nip19.decode(slug)
|
const { data } = nip19.decode(slug)
|
||||||
|
|
||||||
@ -73,6 +74,9 @@ const Sidebar = ({ course = false }) => {
|
|||||||
fetchCourse(id);
|
fetchCourse(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [router.isReady, router.query, ndk, course]);
|
}, [router.isReady, router.query, ndk, course]);
|
||||||
|
|
||||||
@ -136,8 +140,8 @@ const Sidebar = ({ course = false }) => {
|
|||||||
<div onClick={() => router.push('/content?tag=videos')} className={`w-full cursor-pointer py-2 my-2 hover:bg-gray-700 rounded-lg ${isActive('/content?tag=videos') ? 'bg-gray-700' : ''}`}>
|
<div onClick={() => router.push('/content?tag=videos')} className={`w-full cursor-pointer py-2 my-2 hover:bg-gray-700 rounded-lg ${isActive('/content?tag=videos') ? 'bg-gray-700' : ''}`}>
|
||||||
<p className="pl-3 rounded-md font-bold text-lg"><i className="pi pi-video text-sm pr-1"></i> Videos</p>
|
<p className="pl-3 rounded-md font-bold text-lg"><i className="pi pi-video text-sm pr-1"></i> Videos</p>
|
||||||
</div>
|
</div>
|
||||||
<div onClick={() => router.push('/content?tag=resources')} className={`w-full cursor-pointer py-2 my-2 hover:bg-gray-700 rounded-lg ${isActive('/content?tag=resources') ? 'bg-gray-700' : ''}`}>
|
<div onClick={() => router.push('/content?tag=documents')} className={`w-full cursor-pointer py-2 my-2 hover:bg-gray-700 rounded-lg ${isActive('/content?tag=documents') ? 'bg-gray-700' : ''}`}>
|
||||||
<p className="pl-3 rounded-md font-bold text-lg"><i className="pi pi-file text-sm pr-1"></i> Resources</p>
|
<p className="pl-3 rounded-md font-bold text-lg"><i className="pi pi-file text-sm pr-1"></i> Documents</p>
|
||||||
</div>
|
</div>
|
||||||
</AccordionTab>
|
</AccordionTab>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
@ -4,12 +4,12 @@ import { useContentIdsQuery } from '@/hooks/apiQueries/useContentIdsQuery';
|
|||||||
|
|
||||||
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY;
|
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY;
|
||||||
|
|
||||||
export function useResources() {
|
export function useDocuments() {
|
||||||
const [isClient, setIsClient] = useState(false);
|
const [isClient, setIsClient] = useState(false);
|
||||||
const [resources, setResources] = useState();
|
const [documents, setDocuments] = useState();
|
||||||
// Add new state variables for loading and error
|
// Add new state variables for loading and error
|
||||||
const [resourcesLoading, setResourcesLoading] = useState(false);
|
const [documentsLoading, setDocumentsLoading] = useState(false);
|
||||||
const [resourcesError, setResourcesError] = useState(null);
|
const [documentsError, setDocumentsError] = useState(null);
|
||||||
|
|
||||||
const { contentIds } = useContentIdsQuery()
|
const { contentIds } = useContentIdsQuery()
|
||||||
const {ndk, addSigner} = useNDKContext();
|
const {ndk, addSigner} = useNDKContext();
|
||||||
@ -19,18 +19,18 @@ export function useResources() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const hasRequiredProperties = (event, contentIds) => {
|
const hasRequiredProperties = (event, contentIds) => {
|
||||||
const hasResource = event.tags.some(([tag, value]) => tag === "t" && value === "resource");
|
const hasDocument = event.tags.some(([tag, value]) => tag === "t" && value === "document");
|
||||||
const hasId = event.tags.some(([tag, value]) => tag === "d" && contentIds.includes(value));
|
const hasId = event.tags.some(([tag, value]) => tag === "d" && contentIds.includes(value));
|
||||||
return hasResource && hasId;
|
return hasDocument && hasId;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchResourcesFromNDK = async () => {
|
const fetchDocumentsFromNDK = async () => {
|
||||||
setResourcesLoading(true);
|
setDocumentsLoading(true);
|
||||||
setResourcesError(null);
|
setDocumentsError(null);
|
||||||
try {
|
try {
|
||||||
if (!contentIds || contentIds.length === 0) {
|
if (!contentIds || contentIds.length === 0) {
|
||||||
console.log('No content IDs found');
|
console.log('No content IDs found');
|
||||||
setResourcesLoading(false);
|
setDocumentsLoading(false);
|
||||||
return []; // Return early if no content IDs are found
|
return []; // Return early if no content IDs are found
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,29 +41,29 @@ export function useResources() {
|
|||||||
|
|
||||||
if (events && events.size > 0) {
|
if (events && events.size > 0) {
|
||||||
const eventsArray = Array.from(events);
|
const eventsArray = Array.from(events);
|
||||||
const resources = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
|
const documents = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
|
||||||
setResourcesLoading(false);
|
setDocumentsLoading(false);
|
||||||
return resources;
|
return documents;
|
||||||
}
|
}
|
||||||
setResourcesLoading(false);
|
setDocumentsLoading(false);
|
||||||
return [];
|
return [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching resources from NDK:', error);
|
console.error('Error fetching documents from NDK:', error);
|
||||||
setResourcesError(error);
|
setDocumentsError(error);
|
||||||
setResourcesLoading(false);
|
setDocumentsLoading(false);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isClient && contentIds) {
|
if (isClient && contentIds) {
|
||||||
fetchResourcesFromNDK().then(fetchedResources => {
|
fetchDocumentsFromNDK().then(fetchedDocuments => {
|
||||||
if (fetchedResources && fetchedResources.length > 0) {
|
if (fetchedDocuments && fetchedDocuments.length > 0) {
|
||||||
setResources(fetchedResources);
|
setDocuments(fetchedDocuments);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [isClient, contentIds]);
|
}, [isClient, contentIds]);
|
||||||
|
|
||||||
return { resources, resourcesLoading, resourcesError };
|
return { documents, documentsLoading, documentsError };
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ import axios from 'axios';
|
|||||||
|
|
||||||
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY;
|
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY;
|
||||||
|
|
||||||
export function useResourcesQuery() {
|
export function useDocumentsQuery() {
|
||||||
const [isClient, setIsClient] = useState(false);
|
const [isClient, setIsClient] = useState(false);
|
||||||
const {ndk, addSigner} = useNDKContext();
|
const {ndk, addSigner} = useNDKContext();
|
||||||
|
|
||||||
@ -14,12 +14,12 @@ export function useResourcesQuery() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const hasRequiredProperties = (event, contentIds) => {
|
const hasRequiredProperties = (event, contentIds) => {
|
||||||
const hasResource = event.tags.some(([tag, value]) => tag === "t" && value === "resource");
|
const hasDocument = event.tags.some(([tag, value]) => tag === "t" && value === "document");
|
||||||
const hasId = event.tags.some(([tag, value]) => tag === "d" && contentIds.includes(value));
|
const hasId = event.tags.some(([tag, value]) => tag === "d" && contentIds.includes(value));
|
||||||
return hasResource && hasId;
|
return hasDocument && hasId;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchResourcesFromNDK = async () => {
|
const fetchDocumentsFromNDK = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`/api/content/all`);
|
const response = await axios.get(`/api/content/all`);
|
||||||
const contentIds = response.data;
|
const contentIds = response.data;
|
||||||
@ -36,23 +36,23 @@ export function useResourcesQuery() {
|
|||||||
|
|
||||||
if (events && events.size > 0) {
|
if (events && events.size > 0) {
|
||||||
const eventsArray = Array.from(events);
|
const eventsArray = Array.from(events);
|
||||||
const resources = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
|
const documents = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
|
||||||
return resources;
|
return documents;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching resources from NDK:', error);
|
console.error('Error fetching documents from NDK:', error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data: resources, isLoading: resourcesLoading, error: resourcesError, refetch: refetchResources } = useQuery({
|
const { data: documents, isLoading: documentsLoading, error: documentsError, refetch: refetchDocuments } = useQuery({
|
||||||
queryKey: ['resources', isClient],
|
queryKey: ['documents', isClient],
|
||||||
queryFn: fetchResourcesFromNDK,
|
queryFn: fetchDocumentsFromNDK,
|
||||||
// staleTime: 1000 * 60 * 30, // 30 minutes
|
// staleTime: 1000 * 60 * 30, // 30 minutes
|
||||||
// refetchInterval: 1000 * 60 * 30, // 30 minutes
|
// refetchInterval: 1000 * 60 * 30, // 30 minutes
|
||||||
enabled: isClient,
|
enabled: isClient,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { resources, resourcesLoading, resourcesError, refetchResources };
|
return { documents, documentsLoading, documentsError, refetchDocuments };
|
||||||
}
|
}
|
@ -29,7 +29,7 @@ export default function MyApp({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsCourseView(router.pathname.includes('course'));
|
setIsCourseView(router.pathname.includes('course') && !router.pathname.includes('draft'));
|
||||||
}, [router.pathname]);
|
}, [router.pathname]);
|
||||||
|
|
||||||
// const [sidebarExpanded, setSidebarExpanded] = useState(true);
|
// const [sidebarExpanded, setSidebarExpanded] = useState(true);
|
||||||
|
@ -60,9 +60,9 @@ const AboutPage = () => {
|
|||||||
title="Content Types"
|
title="Content Types"
|
||||||
description={
|
description={
|
||||||
<ul className="list-disc list-inside ml-6 space-y-2">
|
<ul className="list-disc list-inside ml-6 space-y-2">
|
||||||
<li><span className="font-bold">Resources:</span> Markdown documents posted as NIP-23 long-form events on Nostr.</li>
|
<li><span className="font-bold">Documents:</span> Markdown documents posted as NIP-23 long-form events on Nostr.</li>
|
||||||
<li><span className="font-bold">Videos:</span> Enhanced markdown files with rich media support, including embedded videos, also saved as NIP-23 events.</li>
|
<li><span className="font-bold">Videos:</span> Enhanced markdown files with rich media support, including embedded videos, also saved as NIP-23 events.</li>
|
||||||
<li><span className="font-bold">Courses:</span> Nostr lists that combine multiple resources and videos into a structured learning path.</li>
|
<li><span className="font-bold">Courses:</span> Nostr lists that combine multiple documents and videos into a structured learning path.</li>
|
||||||
</ul>
|
</ul>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useState, useMemo } from 'react';
|
import React, { useEffect, useState, useMemo } from 'react';
|
||||||
import GenericCarousel from '@/components/content/carousels/GenericCarousel';
|
import GenericCarousel from '@/components/content/carousels/GenericCarousel';
|
||||||
import { parseEvent, parseCourseEvent } from '@/utils/nostr';
|
import { parseEvent, parseCourseEvent } from '@/utils/nostr';
|
||||||
import { useResources } from '@/hooks/nostr/useResources';
|
import { useDocuments } from '@/hooks/nostr/useDocuments';
|
||||||
import { useVideos } from '@/hooks/nostr/useVideos';
|
import { useVideos } from '@/hooks/nostr/useVideos';
|
||||||
import { useCourses } from '@/hooks/nostr/useCourses';
|
import { useCourses } from '@/hooks/nostr/useCourses';
|
||||||
import { TabMenu } from 'primereact/tabmenu';
|
import { TabMenu } from 'primereact/tabmenu';
|
||||||
@ -17,7 +17,7 @@ const MenuTab = ({ items, selectedTopic, onTabChange }) => {
|
|||||||
const menuItems = allItems.map((item, index) => {
|
const menuItems = allItems.map((item, index) => {
|
||||||
let icon = 'pi pi-tag';
|
let icon = 'pi pi-tag';
|
||||||
if (item === 'All') icon = 'pi pi-eye';
|
if (item === 'All') icon = 'pi pi-eye';
|
||||||
else if (item === 'Resources') icon = 'pi pi-file';
|
else if (item === 'Documents') icon = 'pi pi-file';
|
||||||
else if (item === 'Videos') icon = 'pi pi-video';
|
else if (item === 'Videos') icon = 'pi pi-video';
|
||||||
else if (item === 'Courses') icon = 'pi pi-desktop';
|
else if (item === 'Courses') icon = 'pi pi-desktop';
|
||||||
|
|
||||||
@ -67,11 +67,11 @@ const MenuTab = ({ items, selectedTopic, onTabChange }) => {
|
|||||||
|
|
||||||
const ContentPage = () => {
|
const ContentPage = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { resources, resourcesLoading } = useResources();
|
const { documents, documentsLoading } = useDocuments();
|
||||||
const { videos, videosLoading } = useVideos();
|
const { videos, videosLoading } = useVideos();
|
||||||
const { courses, coursesLoading } = useCourses();
|
const { courses, coursesLoading } = useCourses();
|
||||||
|
|
||||||
const [processedResources, setProcessedResources] = useState([]);
|
const [processedDocuments, setProcessedDocuments] = useState([]);
|
||||||
const [processedVideos, setProcessedVideos] = useState([]);
|
const [processedVideos, setProcessedVideos] = useState([]);
|
||||||
const [processedCourses, setProcessedCourses] = useState([]);
|
const [processedCourses, setProcessedCourses] = useState([]);
|
||||||
const [allContent, setAllContent] = useState([]);
|
const [allContent, setAllContent] = useState([]);
|
||||||
@ -92,11 +92,11 @@ const ContentPage = () => {
|
|||||||
}, [router.query.tag]);
|
}, [router.query.tag]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (resources && !resourcesLoading) {
|
if (documents && !documentsLoading) {
|
||||||
const processedResources = resources.map(resource => ({...parseEvent(resource), type: 'resource'}));
|
const processedDocuments = documents.map(document => ({...parseEvent(document), type: 'document'}));
|
||||||
setProcessedResources(processedResources);
|
setProcessedDocuments(processedDocuments);
|
||||||
}
|
}
|
||||||
}, [resources, resourcesLoading]);
|
}, [documents, documentsLoading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (videos && !videosLoading) {
|
if (videos && !videosLoading) {
|
||||||
@ -113,11 +113,11 @@ const ContentPage = () => {
|
|||||||
}, [courses, coursesLoading]);
|
}, [courses, coursesLoading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const allContent = [...processedResources, ...processedVideos, ...processedCourses];
|
const allContent = [...processedDocuments, ...processedVideos, ...processedCourses];
|
||||||
setAllContent(allContent);
|
setAllContent(allContent);
|
||||||
|
|
||||||
const uniqueTopics = new Set(allContent.map(item => item.topics).flat());
|
const uniqueTopics = new Set(allContent.map(item => item.topics).flat());
|
||||||
const priorityItems = ['All', 'Courses', 'Videos', 'Resources'];
|
const priorityItems = ['All', 'Courses', 'Videos', 'Documents'];
|
||||||
const otherTopics = Array.from(uniqueTopics).filter(topic => !priorityItems.includes(topic));
|
const otherTopics = Array.from(uniqueTopics).filter(topic => !priorityItems.includes(topic));
|
||||||
const combinedTopics = [...priorityItems.slice(1), ...otherTopics];
|
const combinedTopics = [...priorityItems.slice(1), ...otherTopics];
|
||||||
setAllTopics(combinedTopics);
|
setAllTopics(combinedTopics);
|
||||||
@ -125,13 +125,13 @@ const ContentPage = () => {
|
|||||||
if (selectedTopic) {
|
if (selectedTopic) {
|
||||||
filterContent(selectedTopic, allContent);
|
filterContent(selectedTopic, allContent);
|
||||||
}
|
}
|
||||||
}, [processedResources, processedVideos, processedCourses]);
|
}, [processedDocuments, processedVideos, processedCourses]);
|
||||||
|
|
||||||
const filterContent = (topic, content) => {
|
const filterContent = (topic, content) => {
|
||||||
let filtered = content;
|
let filtered = content;
|
||||||
if (topic !== 'All') {
|
if (topic !== 'All') {
|
||||||
const topicLower = topic.toLowerCase();
|
const topicLower = topic.toLowerCase();
|
||||||
if (['courses', 'videos', 'resources'].includes(topicLower)) {
|
if (['courses', 'videos', 'documents'].includes(topicLower)) {
|
||||||
filtered = content.filter(item => item.type === topicLower.slice(0, -1));
|
filtered = content.filter(item => item.type === topicLower.slice(0, -1));
|
||||||
} else {
|
} else {
|
||||||
filtered = content.filter(item => item.topics && item.topics.includes(topic.toLowerCase()));
|
filtered = content.filter(item => item.topics && item.topics.includes(topic.toLowerCase()));
|
||||||
@ -166,7 +166,7 @@ const ContentPage = () => {
|
|||||||
<h1 className="text-3xl font-bold mb-4 ml-1">All Content</h1>
|
<h1 className="text-3xl font-bold mb-4 ml-1">All Content</h1>
|
||||||
</div>
|
</div>
|
||||||
<MenuTab
|
<MenuTab
|
||||||
items={['Courses', 'Videos', 'Resources', ...allTopics.filter(topic => !['Courses', 'Videos', 'Resources'].includes(topic))]}
|
items={['Courses', 'Videos', 'Documents', ...allTopics.filter(topic => !['Courses', 'Videos', 'Documents'].includes(topic))]}
|
||||||
selectedTopic={selectedTopic}
|
selectedTopic={selectedTopic}
|
||||||
onTabChange={handleTopicChange}
|
onTabChange={handleTopicChange}
|
||||||
className="max-w-[90%] mx-auto"
|
className="max-w-[90%] mx-auto"
|
||||||
|
@ -44,7 +44,6 @@ const DraftCourse = () => {
|
|||||||
axios.get(`/api/courses/drafts/${slug}`)
|
axios.get(`/api/courses/drafts/${slug}`)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
setCourse(res.data);
|
setCourse(res.data);
|
||||||
console.log('coursesssss:', res.data);
|
|
||||||
setLessons(res.data.draftLessons);
|
setLessons(res.data.draftLessons);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
@ -53,16 +53,19 @@ const useCourseData = (ndk, fetchAuthor, router) => {
|
|||||||
return { course, lessonIds };
|
return { course, lessonIds };
|
||||||
};
|
};
|
||||||
|
|
||||||
const useLessons = (ndk, fetchAuthor, lessonIds) => {
|
const useLessons = (ndk, fetchAuthor, lessonIds, pubkey) => {
|
||||||
const [lessons, setLessons] = useState([]);
|
const [lessons, setLessons] = useState([]);
|
||||||
const [uniqueLessons, setUniqueLessons] = useState([]);
|
const [uniqueLessons, setUniqueLessons] = useState([]);
|
||||||
|
|
||||||
|
console.log('lessonIds', lessonIds);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (lessonIds.length > 0) {
|
if (lessonIds.length > 0) {
|
||||||
const fetchLesson = async (lessonId) => {
|
const fetchLesson = async (lessonId) => {
|
||||||
|
console.log('lessonId', lessonId);
|
||||||
try {
|
try {
|
||||||
await ndk.connect();
|
await ndk.connect();
|
||||||
const filter = { "#d": [lessonId] };
|
const filter = { "#d": [lessonId], kinds:[30023, 30402], authors: [pubkey] };
|
||||||
const event = await ndk.fetchEvent(filter);
|
const event = await ndk.fetchEvent(filter);
|
||||||
if (event) {
|
if (event) {
|
||||||
const author = await fetchAuthor(event.pubkey);
|
const author = await fetchAuthor(event.pubkey);
|
||||||
@ -83,6 +86,10 @@ const useLessons = (ndk, fetchAuthor, lessonIds) => {
|
|||||||
setUniqueLessons(newUniqueLessons);
|
setUniqueLessons(newUniqueLessons);
|
||||||
}, [lessons]);
|
}, [lessons]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('uniqueLessons', uniqueLessons);
|
||||||
|
}, [uniqueLessons]);
|
||||||
|
|
||||||
return { lessons, uniqueLessons, setLessons };
|
return { lessons, uniqueLessons, setLessons };
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -139,7 +146,7 @@ const Course = () => {
|
|||||||
}, [ndk]);
|
}, [ndk]);
|
||||||
|
|
||||||
const { course, lessonIds } = useCourseData(ndk, fetchAuthor, router);
|
const { course, lessonIds } = useCourseData(ndk, fetchAuthor, router);
|
||||||
const { lessons, uniqueLessons, setLessons } = useLessons(ndk, fetchAuthor, lessonIds);
|
const { lessons, uniqueLessons, setLessons } = useLessons(ndk, fetchAuthor, lessonIds, course?.pubkey);
|
||||||
const { decryptionPerformed, loading } = useDecryption(session, paidCourse, course, lessons, setLessons);
|
const { decryptionPerformed, loading } = useDecryption(session, paidCourse, course, lessons, setLessons);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import MenuTab from "@/components/menutab/MenuTab";
|
import MenuTab from "@/components/menutab/MenuTab";
|
||||||
import ResourceForm from "@/components/forms/ResourceForm";
|
import DocumentForm from "@/components/forms/DocumentForm";
|
||||||
import VideoForm from "@/components/forms/VideoForm";
|
import VideoForm from "@/components/forms/VideoForm";
|
||||||
import CourseForm from "@/components/forms/course/CourseForm";
|
import CourseForm from "@/components/forms/course/CourseForm";
|
||||||
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
||||||
@ -12,7 +12,7 @@ const Create = () => {
|
|||||||
const { isAdmin, isLoading } = useIsAdmin();
|
const { isAdmin, isLoading } = useIsAdmin();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const homeItems = [
|
const homeItems = [
|
||||||
{ label: 'Resource', icon: 'pi pi-book' },
|
{ label: 'Document', icon: 'pi pi-file' },
|
||||||
{ label: 'Video', icon: 'pi pi-video' },
|
{ label: 'Video', icon: 'pi pi-video' },
|
||||||
{ label: 'Course', icon: 'pi pi-desktop' }
|
{ label: 'Course', icon: 'pi pi-desktop' }
|
||||||
];
|
];
|
||||||
@ -32,8 +32,8 @@ const Create = () => {
|
|||||||
return <CourseForm />;
|
return <CourseForm />;
|
||||||
case 'Video':
|
case 'Video':
|
||||||
return <VideoForm />;
|
return <VideoForm />;
|
||||||
case 'Resource':
|
case 'Document':
|
||||||
return <ResourceForm />;
|
return <DocumentForm />;
|
||||||
default:
|
default:
|
||||||
return null; // or a default component
|
return null; // or a default component
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { parseEvent } from "@/utils/nostr";
|
import { parseEvent } from "@/utils/nostr";
|
||||||
import ResourceForm from "@/components/forms/ResourceForm";
|
import DocumentForm from "@/components/forms/DocumentForm";
|
||||||
import VideoForm from "@/components/forms/VideoForm";
|
import VideoForm from "@/components/forms/VideoForm";
|
||||||
import CourseForm from "@/components/forms/course/CourseForm";
|
import CourseForm from "@/components/forms/course/CourseForm";
|
||||||
import { useNDKContext } from "@/context/NDKContext";
|
import { useNDKContext } from "@/context/NDKContext";
|
||||||
@ -41,7 +41,7 @@ export default function Edit() {
|
|||||||
<h2 className="text-center mb-8">Edit Published Event</h2>
|
<h2 className="text-center mb-8">Edit Published Event</h2>
|
||||||
{event?.topics.includes('course') && <CourseForm draft={event} isPublished />}
|
{event?.topics.includes('course') && <CourseForm draft={event} isPublished />}
|
||||||
{!event?.topics.includes('video') && <VideoForm draft={event} isPublished />}
|
{!event?.topics.includes('video') && <VideoForm draft={event} isPublished />}
|
||||||
{event?.topics.includes('resource') && <ResourceForm draft={event} isPublished />}
|
{event?.topics.includes('document') && <DocumentForm draft={event} isPublished />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import ResourceForm from "@/components/forms/ResourceForm";
|
import DocumentForm from "@/components/forms/DocumentForm";
|
||||||
import VideoForm from "@/components/forms/VideoForm";
|
import VideoForm from "@/components/forms/VideoForm";
|
||||||
import CourseForm from "@/components/forms/course/CourseForm";
|
import CourseForm from "@/components/forms/course/CourseForm";
|
||||||
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
||||||
@ -38,7 +38,7 @@ const Edit = () => {
|
|||||||
<h2 className="text-center mb-8">Edit Draft</h2>
|
<h2 className="text-center mb-8">Edit Draft</h2>
|
||||||
{draft?.type === 'course' && <CourseForm draft={draft} />}
|
{draft?.type === 'course' && <CourseForm draft={draft} />}
|
||||||
{draft?.type === 'video' && <VideoForm draft={draft} />}
|
{draft?.type === 'video' && <VideoForm draft={draft} />}
|
||||||
{draft?.type === 'resource' && <ResourceForm draft={draft} />}
|
{draft?.type === 'document' && <DocumentForm draft={draft} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -32,6 +32,7 @@ export default function Draft() {
|
|||||||
const { returnImageProxy } = useImageProxy();
|
const { returnImageProxy } = useImageProxy();
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState(null);
|
||||||
|
const [nAddress, setNAddress] = useState(null);
|
||||||
const [videoId, setVideoId] = useState(null);
|
const [videoId, setVideoId] = useState(null);
|
||||||
const { width, height } = useResponsiveImageDimensions();
|
const { width, height } = useResponsiveImageDimensions();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -187,7 +188,7 @@ export default function Draft() {
|
|||||||
console.log('NewDTag:', NewDTag);
|
console.log('NewDTag:', NewDTag);
|
||||||
|
|
||||||
switch (draft?.type) {
|
switch (draft?.type) {
|
||||||
case 'resource':
|
case 'document':
|
||||||
if (draft?.price) {
|
if (draft?.price) {
|
||||||
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
||||||
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY, process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY, process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
||||||
@ -208,7 +209,7 @@ export default function Draft() {
|
|||||||
...(draft?.additionalLinks ? draft.additionalLinks.map(link => ['r', link]) : []),
|
...(draft?.additionalLinks ? draft.additionalLinks.map(link => ['r', link]) : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
type = 'resource';
|
type = 'document';
|
||||||
break;
|
break;
|
||||||
case 'video':
|
case 'video':
|
||||||
if (draft?.price) {
|
if (draft?.price) {
|
||||||
@ -315,7 +316,7 @@ export default function Draft() {
|
|||||||
</div>
|
</div>
|
||||||
<div className='flex flex-col max-tab:mt-12 max-mob:mt-12'>
|
<div className='flex flex-col max-tab:mt-12 max-mob:mt-12'>
|
||||||
{draft && (
|
{draft && (
|
||||||
<div style={{ width: width < 768 ? "auto" : width }} onClick={() => router.push(`/details/${draft.id}`)} className="flex flex-col items-center mx-auto cursor-pointer rounded-md shadow-lg">
|
<div style={{ width: width < 768 ? "auto" : width }} onClick={() => router.push(`/details/${nAddress}`)} className="flex flex-col items-center mx-auto cursor-pointer rounded-md shadow-lg">
|
||||||
<div style={{ maxWidth: width, minWidth: width }} className="max-tab:h-auto max-mob:h-auto">
|
<div style={{ maxWidth: width, minWidth: width }} className="max-tab:h-auto max-mob:h-auto">
|
||||||
<Image
|
<Image
|
||||||
alt="resource thumbnail"
|
alt="resource thumbnail"
|
||||||
|
@ -2,7 +2,7 @@ import Head from 'next/head';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import CoursesCarousel from '@/components/content/carousels/CoursesCarousel';
|
import CoursesCarousel from '@/components/content/carousels/CoursesCarousel';
|
||||||
import VideosCarousel from '@/components/content/carousels/VideosCarousel';
|
import VideosCarousel from '@/components/content/carousels/VideosCarousel';
|
||||||
import ResourcesCarousel from '@/components/content/carousels/ResourcesCarousel';
|
import DocumentsCarousel from '@/components/content/carousels/DocumentsCarousel';
|
||||||
import InteractivePromotionalCarousel from '@/components/content/carousels/InteractivePromotionalCarousel';
|
import InteractivePromotionalCarousel from '@/components/content/carousels/InteractivePromotionalCarousel';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
@ -18,7 +18,7 @@ export default function Home() {
|
|||||||
<InteractivePromotionalCarousel />
|
<InteractivePromotionalCarousel />
|
||||||
<CoursesCarousel />
|
<CoursesCarousel />
|
||||||
<VideosCarousel />
|
<VideosCarousel />
|
||||||
<ResourcesCarousel />
|
<DocumentsCarousel />
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -63,7 +63,7 @@ export const parseEvent = (event) => {
|
|||||||
image: '',
|
image: '',
|
||||||
published_at: '',
|
published_at: '',
|
||||||
topics: [], // Added to hold all topics
|
topics: [], // Added to hold all topics
|
||||||
type: 'resource', // Default type
|
type: 'document', // Default type
|
||||||
};
|
};
|
||||||
|
|
||||||
// Iterate over the tags array to extract data
|
// Iterate over the tags array to extract data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user