import { useEffect, useState, useMemo } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useAdminTask } from '@/contexts/AdminTaskContext'; import GroupMultiSelect from '@/components/generic/GroupMultiSelect'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Label } from '@/components/ui/label'; import { Card, CardContent } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; import { ArrowLeft } from 'lucide-react'; export default function EditTaskList() { const navigate = useNavigate(); const { taskListId } = useParams(); const { fetchTaskList, updateTaskList, syncGroups, loading } = useAdminTask(); const [form, setForm] = useState(null); const [errors, setErrors] = useState({}); // ── Original values to diff against ────────────────────────────────────── const [original, setOriginal] = useState(null); const [originalGroupIds, setOriginalGroupIds] = useState([]); const [selectedGroupIds, setSelectedGroupIds] = useState([]); useEffect(() => { fetchTaskList(taskListId).then((data) => { if (!data) return; const initialForm = { name: data.name ?? '', description: data.description ?? '', }; setForm(initialForm); setOriginal(initialForm); const ids = (data.groups ?? []).map((g) => g.group_id); setOriginalGroupIds(ids); setSelectedGroupIds(ids); }); }, [taskListId]); // ── Dirty check — true only when something actually changed ─────────────── const isDirty = useMemo(() => { if (!form || !original) return false; const formChanged = form.name.trim() !== original.name.trim() || (form.description.trim() || null) !== (original.description.trim() || null); const groupsChanged = selectedGroupIds.length !== originalGroupIds.length || selectedGroupIds.some((id) => !originalGroupIds.includes(id)); return formChanged || groupsChanged; }, [form, original, selectedGroupIds, originalGroupIds]); const validate = () => { const e = {}; if (!form?.name?.trim()) e.name = 'Task list name is required.'; setErrors(e); return Object.keys(e).length === 0; }; const handleSubmit = async (e) => { e.preventDefault(); if (!validate()) return; // ── 1. Update name / description ────────────────────────────────────── const updated = await updateTaskList(taskListId, { name: form.name.trim(), description: form.description.trim() || null, }); if (!updated) return; // ── 2. Sync groups (single call — avoids burning two sensitive-op hits) ── const groupsChanged = selectedGroupIds.length !== originalGroupIds.length || selectedGroupIds.some((id) => !originalGroupIds.includes(id)); if (groupsChanged) { await syncGroups(taskListId, selectedGroupIds); } navigate(`/admin/taskList`); }; // ── Loading skeleton ────────────────────────────────────────────────────── if (!form) return (
); return (

Edit Task List

Update task list.

{/* Name */}
setForm({ ...form, name: e.target.value })} /> {errors.name && (

{errors.name}

)}
{/* Description */}