2026-09-17 18:05:06 -05:00
|
|
|
import { useState } from "react";
|
|
|
|
|
import { useForm, useWatch, type UseFormReturn } from "react-hook-form";
|
|
|
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
|
|
|
import type { UseQueryResult } from "@tanstack/react-query";
|
|
|
|
|
import {
|
|
|
|
|
EMPTY_TASK_TEMPLATE_FORM,
|
|
|
|
|
NEW_TEMPLATE_ID,
|
|
|
|
|
} from "@/domain/settings/task-templates/constants/task-template-constants";
|
|
|
|
|
import { mapTaskTemplateToFormValues } from "@/domain/settings/task-templates/mappers/task-template-mapper";
|
|
|
|
|
import { taskTemplateSchema } from "@/domain/settings/task-templates/schemas/task-template-schema";
|
|
|
|
|
import type {
|
|
|
|
|
SelectedTaskTemplateId,
|
|
|
|
|
TaskTemplate,
|
|
|
|
|
TaskTemplateFormValues,
|
|
|
|
|
} from "@/domain/settings/task-templates/types/task-template";
|
|
|
|
|
import {
|
|
|
|
|
useCreateTaskTemplate,
|
|
|
|
|
useDeleteTaskTemplate,
|
|
|
|
|
useUpdateTaskTemplate,
|
|
|
|
|
} from "@/domain/settings/task-templates/use-cases/use-task-template-mutations";
|
|
|
|
|
import { useTaskTemplates } from "@/domain/settings/task-templates/use-cases/use-task-templates";
|
|
|
|
|
|
|
|
|
|
export interface UseTaskTemplateEditorResult {
|
|
|
|
|
templatesQuery: UseQueryResult<TaskTemplate[], Error>;
|
|
|
|
|
templates: TaskTemplate[];
|
|
|
|
|
selectedId: SelectedTaskTemplateId;
|
|
|
|
|
isNew: boolean;
|
|
|
|
|
isSaving: boolean;
|
|
|
|
|
isDeleting: boolean;
|
|
|
|
|
form: UseFormReturn<TaskTemplateFormValues>;
|
|
|
|
|
deleteConfirmOpen: boolean;
|
|
|
|
|
templateName: string;
|
|
|
|
|
selectTemplate: (template: TaskTemplate) => void;
|
|
|
|
|
startNewTemplate: () => void;
|
|
|
|
|
submitForm: () => void;
|
|
|
|
|
requestDelete: () => void;
|
|
|
|
|
cancelDelete: () => void;
|
|
|
|
|
confirmDelete: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useTaskTemplateEditor(): UseTaskTemplateEditorResult {
|
|
|
|
|
const templatesQuery = useTaskTemplates();
|
|
|
|
|
const createTemplate = useCreateTaskTemplate();
|
|
|
|
|
const updateTemplate = useUpdateTaskTemplate();
|
|
|
|
|
const deleteTemplate = useDeleteTaskTemplate();
|
|
|
|
|
|
|
|
|
|
const [selectedId, setSelectedId] = useState<SelectedTaskTemplateId>(null);
|
|
|
|
|
const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
|
|
|
|
|
|
|
|
|
|
const form = useForm<TaskTemplateFormValues>({
|
|
|
|
|
resolver: zodResolver(taskTemplateSchema),
|
|
|
|
|
defaultValues: EMPTY_TASK_TEMPLATE_FORM,
|
|
|
|
|
mode: "onChange",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const isNew = selectedId === NEW_TEMPLATE_ID;
|
|
|
|
|
const templateName = useWatch({ control: form.control, name: "name" });
|
|
|
|
|
|
|
|
|
|
const selectTemplate = (template: TaskTemplate) => {
|
|
|
|
|
setSelectedId(template.id);
|
|
|
|
|
form.reset(mapTaskTemplateToFormValues(template));
|
2026-09-18 10:46:16 -05:00
|
|
|
void form.trigger();
|
2026-09-17 18:05:06 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const startNewTemplate = () => {
|
|
|
|
|
setSelectedId(NEW_TEMPLATE_ID);
|
|
|
|
|
form.reset(EMPTY_TASK_TEMPLATE_FORM);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onSubmit = (values: TaskTemplateFormValues) => {
|
|
|
|
|
const normalized: TaskTemplateFormValues = {
|
|
|
|
|
...values,
|
|
|
|
|
items: values.items.map((item, index) => ({ ...item, sortOrder: index })),
|
|
|
|
|
};
|
|
|
|
|
if (isNew) {
|
|
|
|
|
createTemplate.mutate(normalized, {
|
|
|
|
|
onSuccess: (result) => setSelectedId(result.id),
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (selectedId !== null) {
|
|
|
|
|
updateTemplate.mutate({ id: selectedId, values: normalized });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const submitForm = form.handleSubmit(onSubmit);
|
|
|
|
|
|
|
|
|
|
const requestDelete = () => setDeleteConfirmOpen(true);
|
|
|
|
|
const cancelDelete = () => setDeleteConfirmOpen(false);
|
|
|
|
|
|
|
|
|
|
const confirmDelete = () => {
|
|
|
|
|
if (selectedId === null || isNew) return;
|
|
|
|
|
deleteTemplate.mutate(selectedId, {
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
setSelectedId(null);
|
|
|
|
|
form.reset(EMPTY_TASK_TEMPLATE_FORM);
|
|
|
|
|
setDeleteConfirmOpen(false);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
templatesQuery,
|
|
|
|
|
templates: templatesQuery.data ?? [],
|
|
|
|
|
selectedId,
|
|
|
|
|
isNew,
|
|
|
|
|
isSaving: createTemplate.isPending || updateTemplate.isPending,
|
|
|
|
|
isDeleting: deleteTemplate.isPending,
|
|
|
|
|
form,
|
|
|
|
|
deleteConfirmOpen,
|
|
|
|
|
templateName,
|
|
|
|
|
selectTemplate,
|
|
|
|
|
startNewTemplate,
|
|
|
|
|
submitForm,
|
|
|
|
|
requestDelete,
|
|
|
|
|
cancelDelete,
|
|
|
|
|
confirmDelete,
|
|
|
|
|
};
|
|
|
|
|
}
|