mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 19:01:19 +00:00
improve course display, accordians, and fixed tag usage for plebdevs resource and workshop
This commit is contained in:
parent
61a78f4b28
commit
280c0e5763
@ -116,8 +116,8 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
<h1 className='text-4xl mt-6'>{processedEvent?.title}</h1>
|
||||
<p className='text-xl mt-6'>{processedEvent?.summary}</p>
|
||||
<h1 className='text-4xl mt-6'>{processedEvent?.name}</h1>
|
||||
<p className='text-xl mt-6'>{processedEvent?.description}</p>
|
||||
<div className='flex flex-row w-full mt-6 items-center'>
|
||||
<Image
|
||||
alt="avatar thumbnail"
|
||||
|
@ -42,6 +42,20 @@ const CourseLesson = ({ lesson, course }) => {
|
||||
</div>
|
||||
<h1 className='text-4xl mt-6'>{lesson?.title}</h1>
|
||||
<p className='text-xl mt-6'>{lesson?.summary}</p>
|
||||
{lesson?.additionalLinks && lesson.additionalLinks.length > 0 && (
|
||||
<div className='mt-6'>
|
||||
<h3 className='text-lg font-semibold mb-2'>External links:</h3>
|
||||
<ul className='list-disc list-inside'>
|
||||
{lesson.additionalLinks.map((link, index) => (
|
||||
<li key={index}>
|
||||
<a href={link} target="_blank" rel="noopener noreferrer" className='text-blue-500 hover:underline'>
|
||||
{new URL(link).hostname}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
<div className='flex flex-row w-full mt-6 items-center'>
|
||||
<Image
|
||||
alt="avatar thumbnail"
|
||||
|
@ -346,9 +346,9 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })
|
||||
</div>
|
||||
<h1 className='text-4xl mt-6'>{processedEvent?.title}</h1>
|
||||
<p className='text-xl mt-6'>{processedEvent?.summary}</p>
|
||||
{processedEvent?.price && (
|
||||
{processedEvent?.price && processedEvent?.price !== 0 ? (
|
||||
<p className='text-lg mt-6'>Price: {processedEvent.price} sats</p>
|
||||
)}
|
||||
) : null}
|
||||
<div className='flex flex-row w-full mt-6 items-center'>
|
||||
<Image
|
||||
alt="avatar thumbnail"
|
||||
|
@ -6,14 +6,6 @@ import Image from "next/image";
|
||||
import { useImageProxy } from "@/hooks/useImageProxy";
|
||||
import { formatDateTime, formatUnixTimestamp } from "@/utils/time";
|
||||
import { useRouter } from "next/router";
|
||||
import axios from "axios";
|
||||
import { useNDKContext } from "@/context/NDKContext";
|
||||
import { nip04, nip19 } from "nostr-tools";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { validateEvent } from "@/utils/nostr";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const MDDisplay = dynamic(
|
||||
@ -25,19 +17,9 @@ const MDDisplay = dynamic(
|
||||
|
||||
const DraftCourseLesson = ({ lesson, course }) => {
|
||||
const [isPublished, setIsPublished] = useState(false);
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
const router = useRouter();
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const { ndk, addSigner } = useNDKContext();
|
||||
const { data: session } = useSession();
|
||||
const { showToast } = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
useEffect(() => {
|
||||
if (lesson?.kind) {
|
||||
|
@ -1,238 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import axios from "axios";
|
||||
import { InputText } from "primereact/inputtext";
|
||||
import { InputNumber } from "primereact/inputnumber";
|
||||
import { InputSwitch } from "primereact/inputswitch";
|
||||
import { Button } from "primereact/button";
|
||||
import { Dropdown } from "primereact/dropdown";
|
||||
import { ProgressSpinner } from "primereact/progressspinner";
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { useRouter } from "next/router";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useNDKContext } from "@/context/NDKContext";
|
||||
import { useWorkshopsQuery } from "@/hooks/nostrQueries/content/useWorkshopsQuery";
|
||||
import { useResourcesQuery } from "@/hooks/nostrQueries/content/useResourcesQuery";
|
||||
import { useDraftsQuery } from "@/hooks/apiQueries/useDraftsQuery";
|
||||
import { parseEvent } from "@/utils/nostr";
|
||||
import ContentDropdownItem from "@/components/content/dropdowns/ContentDropdownItem";
|
||||
import 'primeicons/primeicons.css';
|
||||
|
||||
// todo dealing with adding drafts as new lessons
|
||||
// todo disable ability to add a free lesson to a paid course and vice versa (or just make the user remove the lesson if they want to change the price)
|
||||
// todo deal with error where 2 new lessons popup when only one is added from the dropdown
|
||||
// todo on edit lessons need to make sure that the user is still choosing the order those lessons appear in the course
|
||||
const EditCourseForm = ({ draft }) => {
|
||||
const [title, setTitle] = useState('');
|
||||
const [summary, setSummary] = useState('');
|
||||
const [checked, setChecked] = useState(false);
|
||||
const [price, setPrice] = useState(0);
|
||||
const [isPaid, setIsPaid] = useState(false);
|
||||
const [coverImage, setCoverImage] = useState('');
|
||||
const [selectedLessons, setSelectedLessons] = useState([]);
|
||||
const [selectedLessonsLoading, setSelectedLessonsLoading] = useState(false);
|
||||
const [topics, setTopics] = useState(['']);
|
||||
|
||||
const { ndk } = useNDKContext();
|
||||
const { resources, resourcesLoading } = useResourcesQuery();
|
||||
const { workshops, workshopsLoading } = useWorkshopsQuery();
|
||||
const { drafts, draftsLoading } = useDraftsQuery();
|
||||
const { data: session } = useSession();
|
||||
const router = useRouter();
|
||||
const { showToast } = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
if (draft) {
|
||||
const fetchLessonEventFromNostr = async (eventId) => {
|
||||
try {
|
||||
await ndk.connect();
|
||||
const fetchedEvent = await ndk.fetchEvent(eventId);
|
||||
return fetchedEvent ? parseEvent(fetchedEvent) : null;
|
||||
} catch (error) {
|
||||
showToast('error', 'Error', `Failed to fetch lesson: ${eventId}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchLessons = async () => {
|
||||
const fetchedLessons = await Promise.all(
|
||||
draft.resources.map(lesson => fetchLessonEventFromNostr(lesson.noteId))
|
||||
);
|
||||
setSelectedLessons(fetchedLessons.filter(Boolean));
|
||||
};
|
||||
|
||||
fetchLessons();
|
||||
setTitle(draft.title);
|
||||
setSummary(draft.summary);
|
||||
setChecked(draft.price > 0);
|
||||
setPrice(draft.price || 0);
|
||||
setIsPaid(draft.price > 0);
|
||||
setCoverImage(draft.image);
|
||||
setTopics(draft.topics || ['']);
|
||||
}
|
||||
}, [draft, ndk, showToast, parseEvent]);
|
||||
|
||||
const handlePriceChange = (value) => {
|
||||
setPrice(value);
|
||||
setIsPaid(value > 0);
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
// Ensure selectedLessons is an array
|
||||
const lessonsToUpdate = Array.isArray(selectedLessons) ? selectedLessons : [];
|
||||
|
||||
// Update newly added lessons with courseDraftId
|
||||
const updatePromises = lessonsToUpdate
|
||||
.filter(lesson => lesson && lesson.id && !draft.resources.some(r => r.id === lesson.id))
|
||||
.map(lesson =>
|
||||
axios.put(`/api/resources/${lesson.d}`, { courseDraftId: draft.id })
|
||||
);
|
||||
|
||||
await Promise.all(updatePromises);
|
||||
|
||||
// Prepare payload for course draft update
|
||||
const payload = {
|
||||
id: draft.id, // Include the id in the payload
|
||||
title,
|
||||
summary,
|
||||
image: coverImage,
|
||||
price: isPaid ? price : 0,
|
||||
topics,
|
||||
resourceIds: lessonsToUpdate.filter(lesson => lesson && lesson.id).map(lesson => lesson.id)
|
||||
};
|
||||
|
||||
// Update course draft
|
||||
const response = await axios.put(`/api/courses/drafts/${draft.id}`, payload);
|
||||
console.log('Update response:', response.data);
|
||||
|
||||
showToast('success', 'Success', 'Course draft updated successfully');
|
||||
router.push(`/course/${draft.id}/draft`);
|
||||
} catch (error) {
|
||||
console.error('Error updating course draft:', error);
|
||||
showToast('error', 'Failed to update course draft', error.response?.data?.details || error.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLessonSelect = (content) => {
|
||||
if (!selectedLessons.some(lesson => lesson.id === content.id)) {
|
||||
setSelectedLessons(prevLessons => [...prevLessons, content]);
|
||||
}
|
||||
};
|
||||
|
||||
const removeLesson = (index) => {
|
||||
const updatedSelectedLessons = selectedLessons.filter((_, i) => i !== index);
|
||||
setSelectedLessons(updatedSelectedLessons);
|
||||
};
|
||||
|
||||
const addTopic = () => {
|
||||
setTopics([...topics, '']);
|
||||
};
|
||||
|
||||
const removeTopic = (index) => {
|
||||
const updatedTopics = topics.filter((_, i) => i !== index);
|
||||
setTopics(updatedTopics);
|
||||
};
|
||||
|
||||
const handleTopicChange = (index, value) => {
|
||||
const updatedTopics = topics.map((topic, i) => i === index ? value : topic);
|
||||
setTopics(updatedTopics);
|
||||
};
|
||||
|
||||
const getContentOptions = () => {
|
||||
if (resourcesLoading || !resources || workshopsLoading || !workshops || draftsLoading || !drafts) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const filterContent = (content) => {
|
||||
const contentPrice = content.price || 0;
|
||||
return isPaid ? contentPrice > 0 : contentPrice === 0;
|
||||
};
|
||||
|
||||
const resourceOptions = resources.filter(filterContent).map(resource => {
|
||||
const parsedResource = parseEvent(resource);
|
||||
return {
|
||||
label: <ContentDropdownItem content={parsedResource} onSelect={handleLessonSelect} selected={selectedLessons.some(lesson => lesson.id === parsedResource.id)} />,
|
||||
value: parsedResource
|
||||
};
|
||||
});
|
||||
|
||||
const workshopOptions = workshops.filter(filterContent).map(workshop => {
|
||||
const parsedWorkshop = parseEvent(workshop);
|
||||
return {
|
||||
label: <ContentDropdownItem content={parsedWorkshop} onSelect={handleLessonSelect} selected={selectedLessons.some(lesson => lesson.id === parsedWorkshop.id)} />,
|
||||
value: parsedWorkshop
|
||||
};
|
||||
});
|
||||
|
||||
return [
|
||||
{ label: 'Resources', items: resourceOptions },
|
||||
{ label: 'Workshops', items: workshopOptions }
|
||||
];
|
||||
};
|
||||
|
||||
if (resourcesLoading || workshopsLoading || draftsLoading || selectedLessonsLoading) {
|
||||
return <ProgressSpinner />;
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="p-inputgroup flex-1">
|
||||
<InputText value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Title" />
|
||||
</div>
|
||||
<div className="p-inputgroup flex-1 mt-4">
|
||||
<InputText value={summary} onChange={(e) => setSummary(e.target.value)} placeholder="Summary" />
|
||||
</div>
|
||||
<div className="p-inputgroup flex-1 mt-4">
|
||||
<InputText value={coverImage} onChange={(e) => setCoverImage(e.target.value)} placeholder="Cover Image URL" />
|
||||
</div>
|
||||
<div className="p-inputgroup flex-1 mt-4 flex-col">
|
||||
<p className="py-2">Paid Course</p>
|
||||
<InputSwitch checked={checked} onChange={(e) => setChecked(e.value)} />
|
||||
{checked && (
|
||||
<div className="p-inputgroup flex-1 py-4">
|
||||
<InputNumber value={price} onValueChange={(e) => handlePriceChange(e.value)} placeholder="Price (sats)" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-8 flex-col w-full">
|
||||
<div className="mt-4 flex-col w-full">
|
||||
{selectedLessons.map((lesson, index) => (
|
||||
<div key={index} className="p-inputgroup flex-1 mt-4">
|
||||
<ContentDropdownItem content={lesson} selected={true} />
|
||||
<Button icon="pi pi-times" className="p-button-danger" onClick={() => removeLesson(index)} />
|
||||
</div>
|
||||
))}
|
||||
<div className="p-inputgroup flex-1 mt-4">
|
||||
<Dropdown
|
||||
options={getContentOptions()}
|
||||
onChange={(e) => handleLessonSelect(e.value)}
|
||||
placeholder="Add a Lesson"
|
||||
optionLabel="label"
|
||||
optionGroupLabel="label"
|
||||
optionGroupChildren="items"
|
||||
value={null}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex-col w-full">
|
||||
{topics.map((topic, index) => (
|
||||
<div key={index} className="p-inputgroup flex-1 mt-4">
|
||||
<InputText value={topic} onChange={(e) => handleTopicChange(index, e.target.value)} placeholder={`Topic #${index + 1}`} className="w-full" />
|
||||
{index > 0 && (
|
||||
<Button icon="pi pi-times" className="p-button-danger mt-2" onClick={() => removeTopic(index)} />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
<Button type="button" icon="pi pi-plus" onClick={addTopic} className="p-button-outlined mt-2" />
|
||||
</div>
|
||||
<div className="flex justify-center mt-8">
|
||||
<Button type="submit" label="Update Draft" className="p-button-raised p-button-success" />
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditCourseForm;
|
@ -102,7 +102,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
||||
content,
|
||||
d: draft.d,
|
||||
image: coverImage,
|
||||
topics: [...topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'resource'],
|
||||
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'resource'])],
|
||||
additionalLinks: additionalLinks.filter(link => link.trim() !== '')
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
||||
price: isPaidResource ? price : null,
|
||||
content,
|
||||
image: coverImage,
|
||||
topics: [...topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'resource'],
|
||||
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'resource'])],
|
||||
additionalLinks: additionalLinks.filter(link => link.trim() !== '')
|
||||
};
|
||||
|
||||
|
@ -76,7 +76,7 @@ const WorkshopForm = ({ draft = null }) => {
|
||||
content: embedCode,
|
||||
image: coverImage,
|
||||
user: userResponse.data.id,
|
||||
topics: [...topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'workshop'],
|
||||
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase()), 'workshop'])],
|
||||
additionalLinks: additionalLinks.filter(link => link.trim() !== ''),
|
||||
};
|
||||
|
||||
|
@ -13,12 +13,17 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent }) => {
|
||||
const [showResourceForm, setShowResourceForm] = useState(false);
|
||||
const [showWorkshopForm, setShowWorkshopForm] = useState(false);
|
||||
const [contentOptions, setContentOptions] = useState([]);
|
||||
const [openTabs, setOpenTabs] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
updateContentOptions();
|
||||
console.log("lessons", lessons);
|
||||
}, [allContent, isPaidCourse, lessons]);
|
||||
|
||||
useEffect(() => {
|
||||
setOpenTabs(lessons.map((_, index) => index));
|
||||
}, [lessons]);
|
||||
|
||||
const updateContentOptions = () => {
|
||||
if (!allContent || allContent.length === 0) {
|
||||
setContentOptions([]);
|
||||
@ -26,7 +31,7 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent }) => {
|
||||
}
|
||||
|
||||
const filterContent = (content) => {
|
||||
const contentPrice = content.price || content.tags.find(tag => tag[0] === 'price')?.[1] || 0;
|
||||
const contentPrice = content?.price || (content?.tags && content?.tags.find(tag => tag[0] === 'price')?.[1]) || 0;
|
||||
return isPaidCourse ? contentPrice > 0 : true;
|
||||
};
|
||||
|
||||
@ -119,6 +124,10 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent }) => {
|
||||
setShowWorkshopForm(false);
|
||||
};
|
||||
|
||||
const handleTabChange = (e) => {
|
||||
setOpenTabs(e.index);
|
||||
};
|
||||
|
||||
const AccordianHeader = ({lesson, index}) => {
|
||||
return (
|
||||
<div className="flex justify-between items-center">
|
||||
@ -131,7 +140,7 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent }) => {
|
||||
return (
|
||||
<div className="mt-8">
|
||||
<h3>Lessons</h3>
|
||||
<Accordion multiple>
|
||||
<Accordion multiple activeIndex={openTabs} onTabChange={handleTabChange}>
|
||||
{lessons.map((lesson, index) => (
|
||||
<AccordionTab key={index} header={<AccordianHeader lesson={lesson} index={index} />}>
|
||||
<div className="p-inputgroup flex-1 mt-4">
|
||||
|
@ -71,7 +71,7 @@ export const updateCourseDraft = async (id, data) => {
|
||||
create: draftLessons.map((lesson, index) => ({
|
||||
draftId: lesson.draftId,
|
||||
resourceId: lesson.resourceId,
|
||||
index: index
|
||||
index
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
@ -14,8 +14,6 @@ export function useCoursesQuery() {
|
||||
}, []);
|
||||
|
||||
const hasRequiredProperties = (event, contentIds) => {
|
||||
// currently no topic tag added
|
||||
// const hasCourseTag = event.tags.some(([tag, value]) => tag === "t" && value === "course");
|
||||
const hasId = event.tags.some(([tag, value]) => tag === "d" && contentIds.includes(value));
|
||||
return hasId;
|
||||
};
|
||||
|
@ -14,10 +14,9 @@ export function useResourcesQuery() {
|
||||
}, []);
|
||||
|
||||
const hasRequiredProperties = (event, contentIds) => {
|
||||
const hasPlebDevs = event.tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
const hasResource = event.tags.some(([tag, value]) => tag === "t" && value === "resource");
|
||||
const hasId = event.tags.some(([tag, value]) => tag === "d" && contentIds.includes(value));
|
||||
return hasPlebDevs && hasResource && hasId;
|
||||
return hasResource && hasId;
|
||||
};
|
||||
|
||||
const fetchResourcesFromNDK = async () => {
|
||||
|
@ -14,10 +14,9 @@ export function useWorkshopsQuery() {
|
||||
}, []);
|
||||
|
||||
const hasRequiredProperties = (event, contentIds) => {
|
||||
const hasPlebDevs = event.tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
const hasWorkshop = event.tags.some(([tag, value]) => tag === "t" && value === "workshop");
|
||||
const hasId = event.tags.some(([tag, value]) => tag === "d" && contentIds.includes(value));
|
||||
return hasPlebDevs && hasWorkshop && hasId;
|
||||
return hasWorkshop && hasId;
|
||||
};
|
||||
|
||||
const fetchWorkshopsFromNDK = async () => {
|
||||
|
@ -27,17 +27,15 @@ export default async function handler(req, res) {
|
||||
} else if (req.method === 'PUT') {
|
||||
try {
|
||||
const { slug } = req.query;
|
||||
const { title, summary, image, price, topics } = req.body;
|
||||
const { title, summary, image, price, topics, draftLessons } = req.body;
|
||||
|
||||
const updatedCourseDraft = await prisma.courseDraft.update({
|
||||
where: { id: slug },
|
||||
data: {
|
||||
title,
|
||||
summary,
|
||||
image,
|
||||
price,
|
||||
topics,
|
||||
},
|
||||
const updatedCourseDraft = await updateCourseDraft(slug, {
|
||||
title,
|
||||
summary,
|
||||
image,
|
||||
price,
|
||||
topics,
|
||||
draftLessons
|
||||
});
|
||||
|
||||
res.status(200).json(updatedCourseDraft);
|
||||
@ -59,4 +57,4 @@ export default async function handler(req, res) {
|
||||
res.setHeader('Allow', ['GET', 'PUT', 'DELETE']);
|
||||
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +1,26 @@
|
||||
import prisma from "@/db/prisma";
|
||||
import { createCourseDraft } from "@/db/models/courseDraftModels";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
if (req.method === 'POST') {
|
||||
try {
|
||||
const { userId, title, summary, image, price, topics } = req.body;
|
||||
const { userId, title, summary, image, price, topics, draftLessons } = req.body;
|
||||
|
||||
if (!userId) {
|
||||
return res.status(400).json({ error: 'userId is required' });
|
||||
}
|
||||
|
||||
const courseDraft = await prisma.courseDraft.create({
|
||||
data: {
|
||||
title,
|
||||
summary,
|
||||
image,
|
||||
price,
|
||||
topics: topics || [],
|
||||
user: { connect: { id: userId } },
|
||||
},
|
||||
include: { draftLessons: true }
|
||||
const courseDraft = await createCourseDraft({
|
||||
userId,
|
||||
title,
|
||||
summary,
|
||||
image,
|
||||
price,
|
||||
topics: [...new Set([...topics.map(topic => topic.trim().toLowerCase())])],
|
||||
draftLessons: draftLessons?.map((lesson, index) => ({
|
||||
draftId: lesson.draftId,
|
||||
resourceId: lesson.resourceId,
|
||||
index
|
||||
})) || []
|
||||
});
|
||||
|
||||
res.status(201).json(courseDraft);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getResourceById, updateResource, deleteResource, isResourcePartOfAnyCourse, updateLessonInCourse } from "@/db/models/resourceModels";
|
||||
import { getResourceById, updateResource, deleteResource, } from "@/db/models/resourceModels";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { slug } = req.query;
|
||||
@ -32,13 +32,8 @@ export default async function handler(req, res) {
|
||||
}
|
||||
} else if (req.method === 'DELETE') {
|
||||
try {
|
||||
const isPartOfAnyCourse = await isResourcePartOfAnyCourse(slug);
|
||||
if (isPartOfAnyCourse) {
|
||||
res.status(400).json({ error: 'Resource is part of one or more courses' });
|
||||
} else {
|
||||
await deleteResource(slug);
|
||||
res.status(204).end();
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user