diff --git a/next_frontend/components/Header.tsx b/next_frontend/components/Header.tsx index 99cccc1e..a134f973 100644 --- a/next_frontend/components/Header.tsx +++ b/next_frontend/components/Header.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from 'react'; +import React, { useState, useRef, useEffect, Dispatch, SetStateAction } from 'react'; import { Button } from './ui/button'; import { ArrowLeft, Check, ChevronsUpDown, Copy, MessageSquareMore, Search, SearchIcon, X } from 'lucide-react'; import { ModeToggle } from './ui/theme-toggle'; @@ -10,9 +10,11 @@ import Link from 'next/link'; import { useReactFlow } from 'reactflow'; import SearchNodes from './common/SearchNodes'; -interface HeaderProps {} +interface HeaderProps { + setOpen: Dispatch> +} -const Header = ({ }: HeaderProps) => { +const Header = ({ setOpen }: HeaderProps) => { const { nodes, assuranceCase, setAssuranceCase } = useStore(); const router = useRouter(); const [editName, setEditName] = useState(false); @@ -95,7 +97,7 @@ const Header = ({ }: HeaderProps) => { - {editName ? ( + {/* {editName ? (
{

{assuranceCase.name}

- )} + )} */} +

setOpen(true)} className='font-semibold hover:cursor-pointer'>{assuranceCase.name}

diff --git a/next_frontend/components/cases/CaseContainer.tsx b/next_frontend/components/cases/CaseContainer.tsx index 92a331fa..73eaa945 100644 --- a/next_frontend/components/cases/CaseContainer.tsx +++ b/next_frontend/components/cases/CaseContainer.tsx @@ -10,11 +10,13 @@ import { ReactFlowProvider } from 'reactflow'; import useStore from '@/data/store'; import { addHiddenProp } from '@/lib/case-helper'; +import CaseDetails from './CaseDetails'; const CaseContainer = () => { // const [assuranceCase, setAssuranceCase] = useState() const [loading, setLoading] = useState(true) const { assuranceCase, setAssuranceCase } = useStore(); + const [open, setOpen] = useState(false); const params = useParams() const { caseId } = params @@ -66,8 +68,9 @@ const CaseContainer = () => { ) : ( assuranceCase ? ( -
+
+ ) : (

No Case Found

diff --git a/next_frontend/components/cases/CaseDetails.tsx b/next_frontend/components/cases/CaseDetails.tsx new file mode 100644 index 00000000..74b8eb85 --- /dev/null +++ b/next_frontend/components/cases/CaseDetails.tsx @@ -0,0 +1,68 @@ +'use client' + +import React, { Dispatch, SetStateAction, useEffect, useState } from 'react' +import CaseSheet from '../ui/case-sheet' +import useStore from '@/data/store' +import CaseEditForm from './CaseEditForm' +import { AlertModal } from '../modals/alertModal' + +interface CaseDetailsProps { + isOpen: boolean + setOpen: Dispatch> +} + +const CaseDetails = ({ isOpen, setOpen }: CaseDetailsProps) => { + const [isMounted, setIsMounted] = useState(false); + const [loading, setLoading] = useState(false) + const [unresolvedChanges, setUnresolvedChanges] = useState(false) + const [alertOpen, setAlertOpen] = useState(false) + + const { assuranceCase } = useStore(); + + useEffect(() => { + setIsMounted(true); + }, []); + + if (!isMounted) { + return null; + } + + const handleClose = () => { + setOpen(false) + setAlertOpen(false) + setUnresolvedChanges(false) + } + + const onChange = (open: boolean) => { + if (unresolvedChanges) { + setAlertOpen(true) + } else { + handleClose() + } + }; + + return ( + +
+ + setAlertOpen(false)} + onConfirm={handleClose} + loading={loading} + message={'You have changes that have not been updated. Would you like to discard these changes?'} + confirmButtonText={'Yes, discard changes!'} + cancelButtonText={'No, keep editing'} + /> +
+
+ ) +} + +export default CaseDetails diff --git a/next_frontend/components/cases/CaseEditForm.tsx b/next_frontend/components/cases/CaseEditForm.tsx new file mode 100644 index 00000000..6e0b647b --- /dev/null +++ b/next_frontend/components/cases/CaseEditForm.tsx @@ -0,0 +1,132 @@ +'use client' + +import React, { Dispatch, SetStateAction, useEffect, useState } from 'react' +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { z } from "zod" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import { Textarea } from "../ui/textarea" +import { Button } from '../ui/button' +import useStore from '@/data/store'; +import { CloudFog, Loader, Loader2, LockIcon, LockKeyhole } from 'lucide-react' +import { getLayoutedElements } from '@/lib/layout-helper' +import { useLoginToken } from '@/hooks/useAuth' +import { findItemById, updateAssuranceCase, updateAssuranceCaseNode, caseItemDescription } from '@/lib/case-helper' + +const formSchema = z.object({ + name: z.string().min(2, { + message: "Name must be at least 2 characters.", + }).optional(), + description: z.string().min(2, { + message: "Description must be atleast 2 characters" + }) +}) + +interface CaseEditFormProps { + onClose: () => void + setUnresolvedChanges: Dispatch> +}; + +const CaseEditForm: React.FC = ({ + onClose, + setUnresolvedChanges +}) => { + const { assuranceCase, setAssuranceCase } = useStore(); + const [token] = useLoginToken(); + const [loading, setLoading] = useState(false) + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: assuranceCase || { + name: '', + description: '' + } + }); + + async function onSubmit(values: z.infer) { + setLoading(true) + const updateItem = { + name: values.name, + description: values.description + } + + const url = `${process.env.NEXT_PUBLIC_API_URL}/api/cases/${assuranceCase.id}/` + const requestOptions: RequestInit = { + method: "PUT", + headers: { + Authorization: `Token ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(updateItem) + } + const response = await fetch(url, requestOptions); + if(!response.ok) { + console.log('Render a new error') + } + + setLoading(false) + setAssuranceCase({ ...assuranceCase, name: updateItem.name, description: updateItem.description }) + onClose() + } + + useEffect(() => { + form.watch((values, { name }) => { + if (name === 'description' || name === 'name') { + setUnresolvedChanges(true); + } + }); + }, [form.watch, setUnresolvedChanges]); + + return ( +
+ + ( + + Name + + + + + + )} + /> + ( + + Description + +