shoc-frontend-new/src/app/(protected)/vendors/_components/vendor-create-modal.tsx
2026-07-24 11:32:58 -03:00

146 lines
4 KiB
TypeScript

import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Alert,
Box,
Button,
CircularProgress,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Stack,
Typography,
} from "@mui/material";
import { VendorFormFields } from "./vendor-form-fields";
import { vendorSchema, type VendorFormValues } from "@/domain/vendors/schemas/vendor-schema";
import { useCreateVendor } from "@/domain/vendors/use-cases/use-create-vendor";
import { useVendorFacets } from "@/domain/vendors/use-cases/use-vendor-facets";
import type { VendorFacetCompany } from "@/domain/vendors/types/vendor";
interface VendorCreateModalProps {
open: boolean;
onClose: () => void;
tradeOptions: string[];
}
const defaultValues: VendorFormValues = {
companyName: "",
contactName: "",
email: "",
phone: "",
companyPhone: "",
googleMapsUrl: "",
notes: "",
totalJobs: 0,
address: "",
city: "",
state: "",
zip: "",
tradeSpecialties: "",
isActive: true,
};
export function VendorCreateModal({ open, onClose, tradeOptions }: VendorCreateModalProps) {
const { data: facets, isLoading: isLoadingFacets, error: facetsError } = useVendorFacets();
const createVendor = useCreateVendor();
const [submitError, setSubmitError] = useState<string | null>(null);
const {
control,
handleSubmit,
reset,
setValue,
formState: { errors },
} = useForm<VendorFormValues>({
resolver: zodResolver(vendorSchema),
defaultValues,
});
useEffect(() => {
if (open) {
reset(defaultValues);
setSubmitError(null);
}
}, [open, reset]);
const onCompanySelected = (company: VendorFacetCompany | null) => {
if (!company) return;
setValue("companyPhone", company.companyPhone);
setValue("email", company.email);
setValue("address", company.address);
setValue("city", company.city);
setValue("state", company.state);
setValue("zip", company.zip);
setValue("googleMapsUrl", company.googleMapsUrl);
};
const onSubmit = (values: VendorFormValues) => {
setSubmitError(null);
createVendor.mutate(values, {
onSuccess: () => {
onClose();
},
onError: (error: Error) => {
setSubmitError(error.message || "Failed to create vendor");
},
});
};
const companies = facets?.companies ?? [];
return (
<Dialog
open={open}
onClose={createVendor.isPending ? undefined : onClose}
fullWidth
maxWidth="sm"
aria-labelledby="vendor-create-dialog-title"
slotProps={{ paper: { role: "dialog" } }}
>
<DialogTitle id="vendor-create-dialog-title">
Add Vendor
<Typography variant="body2" sx={{ color: "text.secondary", mt: 0.5 }}>
Register a technician and their vendor company.
</Typography>
</DialogTitle>
<DialogContent>
<Stack spacing={2} className="mt-1">
{Boolean(facetsError) && (
<Alert severity="warning">
Company autocomplete unavailable. You can still type a company manually.
</Alert>
)}
{Boolean(submitError) && <Alert severity="error">{submitError}</Alert>}
{isLoadingFacets ? (
<CircularProgress size={24} />
) : (
<Box>
<VendorFormFields
control={control}
errors={errors}
companies={companies}
tradeOptions={tradeOptions}
onCompanySelected={onCompanySelected}
/>
</Box>
)}
</Stack>
</DialogContent>
<DialogActions>
<Button onClick={onClose} disabled={createVendor.isPending}>
Cancel
</Button>
<Button
color="primary"
variant="contained"
onClick={handleSubmit(onSubmit)}
disabled={createVendor.isPending}
>
{createVendor.isPending ? "Saving..." : "Add Vendor"}
</Button>
</DialogActions>
</Dialog>
);
}