From bcd5b35f330fdef3c72dfa1cc02a5e54c1b6e768 Mon Sep 17 00:00:00 2001 From: Nazire Date: Fri, 13 Dec 2024 18:04:00 +0300 Subject: [PATCH 01/18] has bug in tag selection. --- frontend/src/routes/question.tsx | 158 +++++++++++++++++++++++++++++-- 1 file changed, 148 insertions(+), 10 deletions(-) diff --git a/frontend/src/routes/question.tsx b/frontend/src/routes/question.tsx index 5d2f7c26..b042e921 100644 --- a/frontend/src/routes/question.tsx +++ b/frontend/src/routes/question.tsx @@ -10,16 +10,36 @@ import { FullscreenLoading } from "@/components/FullscreenLoading"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { toast } from "@/components/ui/use-toast"; +import { DifficultyLevel, TagDetails } from "@/services/api/programmingForumSchemas"; + import { useDeleteQuestion as useDeleteQuestionById, useDownvoteQuestion, useGetQuestionDetails, useUpvoteQuestion, + useUpdateQuestion, + useSearchTags, } from "@/services/api/programmingForumComponents"; +import { MultiSelect } from "@/components/multi-select"; +import { + Form, + FormControl, + FormField, + FormItem, + FormMessage, +} from "@/components/ui/form"; +import { Info } from "lucide-react"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; +import SyntaxHighlighter from "react-syntax-highlighter"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; import useAuthStore from "@/services/auth"; import { convertTagToTrack, useExercismSearch } from "@/services/exercism"; import { Flag, MessageSquare, ThumbsDown, ThumbsUp, Trash } from "lucide-react"; -import { useState } from "react"; +import { useEffect,useRef, useState } from "react"; import { Link, useParams } from "react-router-dom"; export default function QuestionPage() { @@ -84,15 +104,70 @@ export default function QuestionPage() { }, ); + const { data: tagSearchData } = useSearchTags( + { queryParams: { q: "", pageSize: 1000 } }, + { enabled: true }, + ); + + useEffect(() => { + if (tagSearchData?.data) { + const tagsData = (tagSearchData.data as { items: TagDetails[] }).items; + setAvailableTags(tagsData); + } + }, [tagSearchData]); + + + + const question = data! || {}; + const [isEditing, setIsEditing] = useState(false); // To toggle edit mode + const [isPreviewMode, setIsPreviewMode] = useState(false); // Preview toggle for description + + const titleRef = useRef(null); + const contentRef = useRef(null); + + const [content, setContent] = useState(question.content || ""); // Controlled content state + const [tags, setTags] = useState(question.tags?.map((tag) => Number(tag.id)) || []); // Tag IDs state + const [availableTags, setAvailableTags] = useState<{ tagId: string; name: string }[]>([]); // Available tags + + const { mutateAsync: updateQuestion, isPending } = useUpdateQuestion({ + onSuccess: () => { + refetch(); + setIsEditing(false); + }, + }); + + + const saveChanges = async () => { + try { + await updateQuestion({ + pathParams: { questionId: question.id }, + body: { + title: titleRef.current?.value || question.title, + content: contentRef.current?.value || question.content, + tags: tags, + }, + }); + toast({ + variant: "default", + title: "Changes saved", + description: "The question has been updated successfully.", + }); + setIsEditing(false); + } catch (err) { + toast({ + variant: "destructive", + title: "Failed to save changes", + description: "An error occurred while updating the question.", + }); + } + }; + if (isLoading) { return ; } if (error) { return ; } - - const question = data! || {}; - if (!question) { return (
+ {isEditing ? ( + + ) : (

{question.title}

+ )} +
{/* Question Content */} - + {isEditing ? ( +
+
+ + +
+ {isPreviewMode ? ( +
+ +
+ ) : ( +