Spaces:
Runtime error
Runtime error
| "use client"; | |
| import { useState, useTransition } from "react"; | |
| import { useRouter } from "next/navigation"; | |
| import { BookEditIcon } from "@hugeicons/core-free-icons"; | |
| import type { CaseTypeValue } from "@/lib/constants"; | |
| import { Icon } from "@/components/shared/icon"; | |
| import { Button } from "@/components/ui/button"; | |
| import { | |
| Dialog, | |
| DialogContent, | |
| DialogDescription, | |
| DialogFooter, | |
| DialogHeader, | |
| DialogTitle, | |
| DialogTrigger, | |
| } from "@/components/ui/dialog"; | |
| import { Input } from "@/components/ui/input"; | |
| import { Label } from "@/components/ui/label"; | |
| import { | |
| Select, | |
| SelectContent, | |
| SelectItem, | |
| SelectTrigger, | |
| SelectValue, | |
| } from "@/components/ui/select"; | |
| import { Textarea } from "@/components/ui/textarea"; | |
| type CaseEditDialogProps = { | |
| customerId: string; | |
| caseId: string; | |
| defaultValues: { | |
| caseName: string; | |
| type: CaseTypeValue; | |
| subType?: string | null; | |
| opponentFullName: string; | |
| description?: string | null; | |
| }; | |
| }; | |
| export function CaseEditDialog({ | |
| customerId, | |
| caseId, | |
| defaultValues, | |
| }: CaseEditDialogProps) { | |
| const router = useRouter(); | |
| const [open, setOpen] = useState(false); | |
| const [isPending, startTransition] = useTransition(); | |
| const [error, setError] = useState<string | null>(null); | |
| const [formState, setFormState] = useState({ | |
| caseName: defaultValues.caseName, | |
| type: defaultValues.type, | |
| subType: defaultValues.subType ?? "", | |
| opponentFullName: defaultValues.opponentFullName, | |
| description: defaultValues.description ?? "", | |
| }); | |
| function updateField<Key extends keyof typeof formState>( | |
| key: Key, | |
| value: (typeof formState)[Key], | |
| ) { | |
| setFormState((current) => ({ | |
| ...current, | |
| [key]: value, | |
| })); | |
| } | |
| function handleSubmit(event: React.FormEvent<HTMLFormElement>) { | |
| event.preventDefault(); | |
| setError(null); | |
| startTransition(async () => { | |
| const response = await fetch( | |
| `/api/customers/${customerId}/cases/${caseId}`, | |
| { | |
| method: "PATCH", | |
| headers: { | |
| "Content-Type": "application/json", | |
| }, | |
| body: JSON.stringify({ | |
| action: "update", | |
| ...formState, | |
| }), | |
| }, | |
| ); | |
| const payload = (await response.json().catch(() => null)) as | |
| | { message?: string } | |
| | null; | |
| if (!response.ok) { | |
| setError(payload?.message || "تعذر تعديل بيانات القضية."); | |
| return; | |
| } | |
| setOpen(false); | |
| router.refresh(); | |
| }); | |
| } | |
| return ( | |
| <Dialog open={open} onOpenChange={setOpen}> | |
| <DialogTrigger asChild> | |
| <Button variant="secondary"> | |
| <span>تعديل القضية</span> | |
| <Icon icon={BookEditIcon} size={18} /> | |
| </Button> | |
| </DialogTrigger> | |
| <DialogContent> | |
| <DialogHeader> | |
| <DialogTitle>تعديل بيانات القضية</DialogTitle> | |
| <DialogDescription> | |
| حدّث نوع القضية أو بيانات الخصم أو الوصف المختصر وقت ما تحتاج. | |
| </DialogDescription> | |
| </DialogHeader> | |
| <form className="space-y-4" onSubmit={handleSubmit}> | |
| <div className="space-y-2"> | |
| <Label htmlFor="edit-case-name">اسم القضية</Label> | |
| <Input | |
| id="edit-case-name" | |
| value={formState.caseName} | |
| onChange={(event) => updateField("caseName", event.target.value)} | |
| required | |
| /> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label>نوع القضية</Label> | |
| <Select | |
| value={formState.type} | |
| onValueChange={(value) => updateField("type", value as CaseTypeValue)} | |
| > | |
| <SelectTrigger> | |
| <SelectValue /> | |
| </SelectTrigger> | |
| <SelectContent> | |
| <SelectItem value="CIVIL">مدنيه</SelectItem> | |
| <SelectItem value="CRIMINAL">جنائيه</SelectItem> | |
| <SelectItem value="PERSONAL_STATUS">أحوال</SelectItem> | |
| </SelectContent> | |
| </Select> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label htmlFor="edit-case-subType">النوع الفرعي</Label> | |
| <Input | |
| id="edit-case-subType" | |
| value={formState.subType} | |
| onChange={(event) => updateField("subType", event.target.value)} | |
| /> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label htmlFor="edit-case-opponent">اسم الخصم بالكامل</Label> | |
| <Input | |
| id="edit-case-opponent" | |
| value={formState.opponentFullName} | |
| onChange={(event) => | |
| updateField("opponentFullName", event.target.value) | |
| } | |
| required | |
| /> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label htmlFor="edit-case-description">وصف مختصر</Label> | |
| <Textarea | |
| id="edit-case-description" | |
| value={formState.description} | |
| onChange={(event) => updateField("description", event.target.value)} | |
| /> | |
| </div> | |
| {error ? ( | |
| <p className="rounded-2xl bg-[color:rgba(185,28,28,0.08)] px-4 py-3 text-sm font-medium text-[var(--destructive)]"> | |
| {error} | |
| </p> | |
| ) : null} | |
| <DialogFooter> | |
| <Button type="button" variant="outline" onClick={() => setOpen(false)}> | |
| إلغاء | |
| </Button> | |
| <Button type="submit" disabled={isPending}> | |
| {isPending ? "جارٍ الحفظ..." : "حفظ التعديلات"} | |
| </Button> | |
| </DialogFooter> | |
| </form> | |
| </DialogContent> | |
| </Dialog> | |
| ); | |
| } | |