diff --git a/peerprep-fe/src/app/(main)/components/filter/TopicsPopover.tsx b/peerprep-fe/src/app/(main)/components/filter/TopicsPopover.tsx index ce0073abd2..67610b70ee 100644 --- a/peerprep-fe/src/app/(main)/components/filter/TopicsPopover.tsx +++ b/peerprep-fe/src/app/(main)/components/filter/TopicsPopover.tsx @@ -7,7 +7,7 @@ import { PopoverTrigger, } from '@/components/ui/popover'; import { Button } from '@/components/ui/button'; -import { Check, ChevronsUpDown } from 'lucide-react'; +import { Check, ChevronsUpDown, Plus } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Input } from '@/components/ui/input'; import { ScrollArea } from '@/components/ui/scroll-area'; @@ -15,11 +15,13 @@ import { ScrollArea } from '@/components/ui/scroll-area'; interface TopicsPopoverProps { selectedTopics: string[]; onChange: (value: string[]) => void; + isAdmin?: boolean; } export function TopicsPopover({ selectedTopics, onChange, + isAdmin, }: TopicsPopoverProps) { const [open, setOpen] = useState(false); const [topics, setTopics] = useState([]); @@ -58,7 +60,7 @@ export function TopicsPopover({ -
+
+ {isAdmin && ( + + )}
- + {filteredTopics.length === 0 ? (

No topic found.

) : ( diff --git a/peerprep-fe/src/app/admin/page.tsx b/peerprep-fe/src/app/admin/page.tsx index 09d0ddd45f..95d286c606 100644 --- a/peerprep-fe/src/app/admin/page.tsx +++ b/peerprep-fe/src/app/admin/page.tsx @@ -23,6 +23,18 @@ function AdminPage() { refetchFilter, } = useFilteredProblems(); + const validateEntries = (problem: Problem) => { + if ( + problem.description === '' || + problem.title === '' || + problem.tags.length === 0 + ) { + setInformationDialog('Please fill in all required fields'); + return false; + } + return true; + }; + const handleDelete = async (id: number) => { const res = await axiosClient.delete(`/questions/${id}`); if (res.status !== 200) { @@ -34,6 +46,9 @@ function AdminPage() { const handleEdit = async (problem: Problem) => { try { + if (!validateEntries(problem)) { + throw new Error('Invalid problem entries'); + } const res = await axiosClient.put(`/questions/${problem._id}`, { difficulty: problem.difficulty, description: problem.description, @@ -68,16 +83,10 @@ function AdminPage() { }; const handleAdd = async (problem: Problem) => { - // TODO: Add proper validation of fields - if ( - problem.description === '' || - problem.title === '' || - problem.tags.length === 0 - ) { - setInformationDialog('Please fill in all required fields'); - return; - } try { + if (!validateEntries(problem)) { + throw new Error('Invalid problem entries'); + } const res = await axiosClient.post(`/questions`, { difficulty: problem.difficulty, description: problem.description, diff --git a/peerprep-fe/src/components/dialogs/ActionDialog.tsx b/peerprep-fe/src/components/dialogs/ActionDialog.tsx index b92dcc8996..663ca60e56 100644 --- a/peerprep-fe/src/components/dialogs/ActionDialog.tsx +++ b/peerprep-fe/src/components/dialogs/ActionDialog.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { ReactElement } from 'react'; import { Dialog, DialogContent, @@ -16,6 +16,7 @@ type Props = { description: string; callback?: () => void; callbackTitle?: string; + children?: ReactElement; }; const ActionDialog = ({ @@ -26,18 +27,23 @@ const ActionDialog = ({ description, callback, callbackTitle, + children, }: Props) => { return ( - + {title} {subtitle} -
-

Description:

-

{description}

-
+ {children ? ( + children + ) : ( +
+

Description:

+

{description}

+
+ )}
-
+ {hasHeader && ( +
+

{problem.title}

+ +
+ )} +

{problem.description}

{problem.examples.map((example, index) => ( diff --git a/peerprep-fe/src/components/problems/ProblemInputDialog.tsx b/peerprep-fe/src/components/problems/ProblemInputDialog.tsx index 293111b997..89fee37aea 100644 --- a/peerprep-fe/src/components/problems/ProblemInputDialog.tsx +++ b/peerprep-fe/src/components/problems/ProblemInputDialog.tsx @@ -90,6 +90,7 @@ function ProblemInputDialog({ onChange={(value) => { setProblemData({ ...problemData, tags: value }); }} + isAdmin />
diff --git a/peerprep-fe/src/components/problems/ProblemRow.tsx b/peerprep-fe/src/components/problems/ProblemRow.tsx index 2490172e17..9a602f7a41 100644 --- a/peerprep-fe/src/components/problems/ProblemRow.tsx +++ b/peerprep-fe/src/components/problems/ProblemRow.tsx @@ -10,6 +10,7 @@ import InformationDialog from '../dialogs/InformationDialog'; import ActionDialog from '../dialogs/ActionDialog'; import { useRouter } from 'next/navigation'; import { axiosClient } from '@/network/axiosClient'; +import ProblemDescriptionPanel from './ProblemDescriptionPanel'; function ProblemStatus({ status }: { status: string }) { if (status === 'solved') { @@ -156,7 +157,14 @@ export default function ProblemRow({ description={problem.description} callback={handleMatch} callbackTitle="Match" - /> + > + {}} + hasHeader={false} + /> + + {/* Dialog for deleting question */}