import { zodResolver } from "@hookform/resolvers/zod"; import { inventoryApi, inventoryKeys } from "@metis/assets/client"; 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 } from "../../common"; import { type WorkProfileDTO, type WorkProfileInput, WorkProfileInputSchema, } from "../../common/work-profiles"; import { accessApi, accessKeys } from "../access/access-api"; import { accessLabel } from "../access/access-labels"; import { ConfigurationQuickEditor, type ConfigurationQuickKind, } from "../components/configuration-quick-editor"; import { ProfileFeedback } from "./profile-feedback"; import { profileApi, profileKeys } from "./work-profile-api"; export function WorkProfileForm({ company, csrfToken, profile, onSaved, }: { company: CompanyDTO; csrfToken: string; profile?: WorkProfileDTO | undefined; onSaved: () => void; }) { const { t } = useTranslation("companies"); const client = useQueryClient(); const prefix = useId(); const mounted = useRef(true); useEffect(() => { mounted.current = true; return () => { mounted.current = false; }; }, []); const [quick, setQuick] = useState(); const access = useQuery({ queryKey: accessKeys.scope(company.id), queryFn: () => accessApi.request(company.id), }); const inventory = useQuery({ queryKey: inventoryKeys.company(company.id), queryFn: () => inventoryApi.get(company.id), }); const form = useForm({ resolver: zodResolver(WorkProfileInputSchema), defaultValues: profile?.values ?? { name: "", personId: "", assetId: "", accountId: null, active: true, notes: null, }, }); const values = form.watch(); const items = access.data?.items ?? []; const today = new Date().toISOString().slice(0, 10); const authorized = !values.accountId || items.some((item) => { const link = item.values; return ( link.kind === "account_person" && link.personId === values.personId && link.accountId === values.accountId && link.startDate <= today && (link.endDate === null || today < link.endDate) && (link.configuration === "pending" || link.configuration === "configured") ); }); const mutation = useMutation({ mutationFn: (input: WorkProfileInput) => profileApi.save(company.id, input, csrfToken, profile?.id), onSuccess: async () => { await client.invalidateQueries({ queryKey: profileKeys.company(company.id) }); if (mounted.current) { onSaved(); } }, }); const disabled = mutation.isPending; const selectors = [ { field: "personId", label: "person", create: "newPerson", kind: "person", options: company.people .filter((item) => item.active || item.id === values.personId) .map((item) => ({ value: item.id, label: item.name })), }, { field: "assetId", label: "asset", create: "newAsset", kind: "asset", options: (inventory.data?.assets ?? []) .filter((item) => item.values.status !== "retired" || item.id === values.assetId) .map((item) => ({ value: item.id, label: item.values.name })), }, { field: "accountId", label: "account", create: "newAccount", kind: "account", options: items .filter( (item) => item.values.kind === "account" && ((item.values.active && item.values.usage !== "technical") || item.id === values.accountId) ) .map((item) => ({ value: item.id, label: accessLabel(item, items, company.people) })), }, ] as const; return ( <>
mutation.mutate(input))}>
{selectors.map((selector) => { const fixed = !!profile && selector.field !== "accountId"; return (
setQuick(selector.kind), } } disabled={disabled || fixed || !inventory.data || !access.data} id={`${prefix}-${selector.field}`} label={t(`profiles.${selector.label}`)} onValueChange={(id) => form.setValue( selector.field, selector.field === "accountId" ? id || null : id ) } options={selector.options} placeholder={t( selector.field === "accountId" ? "profiles.noAccount" : "profiles.choose" )} required={selector.field !== "accountId"} value={values[selector.field] ?? ""} />
); })}

{t("profiles.accountHint")}

{values.personId && values.accountId && !authorized && (

{t("mail.noAuthorization")}

)}