import { zodResolver } from "@hookform/resolvers/zod"; import { catalogApi, catalogKeys, inventoryApi, inventoryKeys } from "@metis/resources/client"; import type { CatalogItemDTO, ResourceDTO } from "@metis/resources/common"; import { Button } from "@repo/shadcn-ui/components/button"; import { ContextHelp } from "@repo/shadcn-ui/components/context-help"; import { FormActions } from "@repo/shadcn-ui/components/form-dialog"; import { Input } from "@repo/shadcn-ui/components/input"; import { Label } from "@repo/shadcn-ui/components/label"; import { SelectWithAction } from "@repo/shadcn-ui/components/select-with-action"; import { Textarea } from "@repo/shadcn-ui/components/textarea"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useEffect, useId, useRef, useState } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import type { CompanyDTO, WorkProfileDTO } from "../../common"; import { CERTIFICATE_STATE_TRANSITIONS, type CertificateConfigurationDTO, type CertificateConfigurationInput, CertificateConfigurationInputSchema, } from "../../common/certificate-configurations"; import { profileApi, profileKeys } from "../profiles/work-profile-api"; import { certificateApi, certificateKeys } from "./certificate-api"; import { CertificateFeedback } from "./certificate-feedback"; import { CertificateQuickEditor } from "./certificate-quick-editor"; export function CertificateConfigurationForm({ company, csrfToken, configuration, initialProfileId = "", onSaved, }: { company: CompanyDTO; csrfToken: string; configuration?: CertificateConfigurationDTO | undefined; initialProfileId?: string; onSaved: () => void; }) { const { t } = useTranslation("companies"); const prefix = useId(); const client = useQueryClient(); const mounted = useRef(true); useEffect(() => { mounted.current = true; return () => { mounted.current = false; }; }, []); const [quick, setQuick] = useState<"profile" | "certificate">(); const profiles = useQuery({ queryKey: profileKeys.company(company.id), queryFn: () => profileApi.get(company.id), }); const resources = useQuery({ queryKey: inventoryKeys.company(company.id), queryFn: () => inventoryApi.get(company.id), }); const catalog = useQuery({ queryKey: catalogKeys.scope(company.id), queryFn: () => catalogApi.get(company.id), }); const form = useForm({ resolver: zodResolver(CertificateConfigurationInputSchema), defaultValues: certificateDefaults(configuration, initialProfileId), }); const values = form.watch(); const ready = [profiles.data, resources.data, catalog.data].every(Boolean); const fixed = Boolean(configuration || initialProfileId); const states = certificateStates(configuration); const mutation = useMutation({ mutationFn: (input: CertificateConfigurationInput) => certificateApi.save(company.id, input, csrfToken, configuration?.id), onSuccess: async () => { await client.invalidateQueries({ queryKey: certificateKeys.company(company.id) }); if (mounted.current) { onSaved(); } }, }); return ( <>
mutation.mutate(input))}>
setQuick("profile") } } disabled={fixed || !ready} id={`${prefix}-profile`} label={t("mail.profile")} onValueChange={(id) => form.setValue("profileId", id)} options={certificateProfiles(values.profileId, profiles.data?.profiles)} placeholder={t("mail.choose")} required value={values.profileId} />
setQuick("certificate"), } } disabled={!!configuration || !ready} id={`${prefix}-resource`} label={t("certificates.resource")} onValueChange={(id) => form.setValue("resourceId", id)} options={certificateOptions( values.resourceId, resources.data?.resources, catalog.data?.items )} placeholder={t("mail.choose")} required value={values.resourceId} />
{ const parsed = CertificateConfigurationInputSchema.shape.state.safeParse(value); if (parsed.success) { form.setValue("state", parsed.data); } }} options={states.map((value) => ({ value, label: t(`mail.${value}`) }))} placeholder={t("mail.choose")} required value={values.state} />
form.setValue("location", event.target.value || null)} value={values.location ?? ""} />