metis-desk/modules/companies/src/web/components/company-form.tsx
David 8386679181 feat: integrate contextual help across forms and improve user guidance
- Added contextual help to various forms including companies, people, departments, sites, assignments, and access accounts.
- Introduced EntityHelp component to provide descriptions, examples, and guidance for each entity type.
- Updated forms to include help sections before submit buttons, enhancing user understanding of each field's purpose.
- Implemented help translations in Spanish and English for consistency across the application.
- Created a new ContextHelp component for displaying help information in a structured format.
- Added automated tests to ensure help content is correctly rendered in both languages.
- Documented the new contextual help feature in ayuda-contextual.md for user reference.
2026-10-03 18:23:38 +02:00

87 lines
3.0 KiB
TypeScript

import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@repo/shadcn-ui/components/button";
import { Checkbox } from "@repo/shadcn-ui/components/checkbox";
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 { useMutation, useQueryClient } from "@tanstack/react-query";
import { useId } from "react";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import type { CompanyRequestDTO, CompanySummaryDTO } from "../../common";
import { CompanyRequestSchema } from "../../common";
import { EntityHelp } from "../access/entity-help";
import { companyApi, companyKeys } from "../api/company-api";
import { CompanyFeedback } from "./company-feedback";
export function CompanyForm({
company,
csrfToken,
onCreated,
onSaved,
showTitle = true,
}: {
company?: CompanySummaryDTO;
csrfToken: string;
onCreated?: (id: string) => void;
onSaved?: () => void;
showTitle?: boolean;
}) {
const { t } = useTranslation("companies");
const id = useId();
const client = useQueryClient();
const form = useForm<CompanyRequestDTO>({
resolver: zodResolver(CompanyRequestSchema),
defaultValues: { name: company?.name ?? "", active: company?.active ?? true },
});
const mutation = useMutation({
mutationFn: (values: CompanyRequestDTO) => companyApi.save(company?.id, values, csrfToken),
onSuccess: async (response) => {
client.setQueryData(companyKeys.detail(response.company.id), response);
await client.invalidateQueries({ queryKey: companyKeys.list });
if (company) {
form.reset({ name: response.company.name, active: response.company.active });
} else {
form.reset();
onCreated?.(response.company.id);
}
onSaved?.();
},
});
return (
<form className="space-y-4" onSubmit={form.handleSubmit((values) => mutation.mutate(values))}>
{showTitle && (
<h2 className="text-lg font-semibold">{t(company ? "editCompany" : "newCompany")}</h2>
)}
<div className="space-y-2">
<Label htmlFor={`${id}-name`}>{t("name")}</Label>
<Input id={`${id}-name`} maxLength={100} required {...form.register("name")} />
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={form.watch("active")}
id={`${id}-active`}
onCheckedChange={(checked) =>
form.setValue("active", checked === true, { shouldDirty: true })
}
/>
<Label htmlFor={`${id}-active`}>{t("activeCompany")}</Label>
</div>
<CompanyFeedback
error={mutation.error}
invalid={Object.keys(form.formState.errors).length > 0}
success={mutation.isSuccess}
/>
<EntityHelp kind="company" />
<FormActions>
<Button disabled={mutation.isPending} type="submit">
{t(mutation.isPending ? "saving" : "save")}
</Button>
</FormActions>
</form>
);
}