import { CheckCircle2, Circle, GripVertical, Plus, Trash2 } from "lucide-react"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { useCreateColumn } from "@/hooks/mutations/column/use-create-column"; import { useDeleteColumn } from "@/hooks/mutations/column/use-delete-column"; import { useReorderColumns } from "@/hooks/mutations/column/use-reorder-columns"; import { useUpdateColumn } from "@/hooks/mutations/column/use-update-column"; import { useGetColumns } from "@/hooks/queries/column/use-get-columns"; import { toast } from "@/lib/toast"; type ColumnEditorProps = { projectId: string; }; export default function ColumnEditor({ projectId }: ColumnEditorProps) { const { t } = useTranslation(); const { data: columns, isLoading } = useGetColumns(projectId); const { mutateAsync: createColumn } = useCreateColumn(); const { mutateAsync: updateColumn } = useUpdateColumn(); const { mutateAsync: deleteColumn } = useDeleteColumn(); const { mutateAsync: reorderColumns } = useReorderColumns(); const [newColumnName, setNewColumnName] = useState(""); const [draggedIndex, setDraggedIndex] = useState(null); const handleCreate = async () => { if (!newColumnName.trim()) return; try { await createColumn({ projectId, data: { name: newColumnName.trim() }, }); setNewColumnName(""); toast.success(t("settings:columnEditor.toastCreated")); } catch (error) { toast.error( error instanceof Error ? error.message : t("settings:columnEditor.toastCreateError"), ); } }; const handleRename = async (id: string, name: string) => { try { await updateColumn({ id, projectId, data: { name } }); toast.success(t("settings:columnEditor.toastRenamed")); } catch (error) { toast.error( error instanceof Error ? error.message : t("settings:columnEditor.toastRenameError"), ); } }; const handleToggleFinal = async (id: string, isFinal: boolean) => { try { await updateColumn({ id, projectId, data: { isFinal } }); toast.success( isFinal ? t("settings:columnEditor.toastFinalOn") : t("settings:columnEditor.toastFinalOff"), ); } catch (error) { toast.error( error instanceof Error ? error.message : t("settings:columnEditor.toastUpdateError"), ); } }; const handleDelete = async (id: string) => { try { await deleteColumn({ id, projectId }); toast.success(t("settings:columnEditor.toastDeleted")); } catch (error) { toast.error( error instanceof Error ? error.message : t("settings:columnEditor.toastDeleteError"), ); } }; const handleDragStart = (index: number) => { setDraggedIndex(index); }; const handleDragOver = (e: React.DragEvent, index: number) => { e.preventDefault(); if (draggedIndex === null || draggedIndex === index || !columns) return; const reordered = [...columns]; const [removed] = reordered.splice(draggedIndex, 1); reordered.splice(index, 0, removed); const updates = reordered.map((col, i) => ({ id: col.id, position: i })); reorderColumns({ projectId, columns: updates }); setDraggedIndex(index); }; const handleDragEnd = () => { setDraggedIndex(null); }; if (isLoading) { return (
{t("settings:columnEditor.loading")}
); } return (
{columns?.map((col, index) => ( // biome-ignore lint/a11y/useSemanticElements: false positive for role="listitem"
handleDragStart(index)} onDragOver={(e) => handleDragOver(e, index)} onDragEnd={handleDragEnd} className="flex items-center gap-2 p-2 border border-border rounded-md bg-sidebar hover:bg-sidebar-accent/50 transition-colors" > { if (e.target.value !== col.name) { handleRename(col.id, e.target.value); } }} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); e.currentTarget.blur(); } }} />
{col.isFinal ? ( ) : ( )} {t("settings:columnEditor.doneColumn")} handleToggleFinal(col.id, checked) } aria-label={t("settings:columnEditor.markDoneAria", { name: col.name, })} className="scale-75" /> {col.isFinal ? t("settings:columnEditor.on") : t("settings:columnEditor.off")}
))}
setNewColumnName(e.target.value)} className="h-8 text-sm flex-1" onKeyDown={(e) => { if (e.key === "Enter") handleCreate(); }} />
); }