mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-04 18:22:05 +00:00
Some checks are pending
* feat(locations): derive site areas from state * chore(locations): keep ticket keys out of source comments * feat(locations): manage ordered site contacts --------- Co-authored-by: Codex Review Integration <codex-review@local.invalid>
143 lines
4.5 KiB
TypeScript
143 lines
4.5 KiB
TypeScript
import { Controller, type Control, type FieldErrors, type UseFormRegister } from "react-hook-form";
|
|
import {
|
|
Autocomplete,
|
|
FormControl,
|
|
InputLabel,
|
|
MenuItem,
|
|
Select,
|
|
Stack,
|
|
TextField,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import type { AccountListItem } from "@/domain/accounts/types/account";
|
|
import type { LocationFormValues } from "@/domain/locations/schemas/location-schema";
|
|
import { LOCATION_STATUS_OPTIONS } from "@/domain/locations/types/location";
|
|
import { LocationContactsFieldArray } from "./location-contacts-field-array";
|
|
import { StateSelect } from "./state-select";
|
|
|
|
interface SharedFieldsProps {
|
|
control: Control<LocationFormValues>;
|
|
errors: FieldErrors<LocationFormValues>;
|
|
register: UseFormRegister<LocationFormValues>;
|
|
}
|
|
|
|
interface LocationDetailsFieldsProps extends SharedFieldsProps {
|
|
accountOptions: AccountListItem[];
|
|
isLoadingAccounts: boolean;
|
|
onAccountSearchChange: (value: string) => void;
|
|
}
|
|
|
|
export function LocationDetailsFields({
|
|
accountOptions,
|
|
control,
|
|
errors,
|
|
isLoadingAccounts,
|
|
onAccountSearchChange,
|
|
register,
|
|
}: LocationDetailsFieldsProps) {
|
|
return (
|
|
<Stack spacing={2}>
|
|
<Typography variant="subtitle1" className="font-semibold">
|
|
Location Information
|
|
</Typography>
|
|
<Stack direction={{ xs: "column", md: "row" }} spacing={2}>
|
|
<TextField
|
|
{...register("name")}
|
|
label="Name"
|
|
required
|
|
error={Boolean(errors.name)}
|
|
helperText={errors.name?.message}
|
|
fullWidth
|
|
/>
|
|
<Controller
|
|
name="accountId"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<Autocomplete
|
|
options={accountOptions}
|
|
loading={isLoadingAccounts}
|
|
getOptionLabel={(option: AccountListItem) => option.name || String(option.id)}
|
|
isOptionEqualToValue={(option, value) => String(option.id) === String(value.id)}
|
|
value={accountOptions.find((account) => String(account.id) === field.value) ?? null}
|
|
onChange={(_event, option) => field.onChange(option ? String(option.id) : "")}
|
|
onInputChange={(_event, value, reason) => {
|
|
if (reason === "input") {
|
|
onAccountSearchChange(value);
|
|
}
|
|
}}
|
|
renderInput={(params) => (
|
|
<TextField {...params} label="Account" placeholder="Search accounts..." />
|
|
)}
|
|
className="flex-1"
|
|
/>
|
|
)}
|
|
/>
|
|
</Stack>
|
|
<TextField
|
|
{...register("address")}
|
|
label="Address"
|
|
required
|
|
error={Boolean(errors.address)}
|
|
helperText={errors.address?.message}
|
|
fullWidth
|
|
/>
|
|
<Stack direction={{ xs: "column", md: "row" }} spacing={2}>
|
|
<TextField
|
|
{...register("city")}
|
|
label="City"
|
|
required
|
|
error={Boolean(errors.city)}
|
|
helperText={errors.city?.message}
|
|
fullWidth
|
|
/>
|
|
<StateSelect control={control} error={errors.state} />
|
|
<TextField
|
|
{...register("zipCode")}
|
|
label="Zip Code"
|
|
required
|
|
error={Boolean(errors.zipCode)}
|
|
helperText={errors.zipCode?.message}
|
|
fullWidth
|
|
/>
|
|
</Stack>
|
|
</Stack>
|
|
);
|
|
}
|
|
|
|
export function LocationContactFields({ control, errors, register }: SharedFieldsProps) {
|
|
return (
|
|
<Stack spacing={2}>
|
|
<Typography variant="subtitle1" className="font-semibold">
|
|
Contact Information
|
|
</Typography>
|
|
<LocationContactsFieldArray control={control} errors={errors} register={register} />
|
|
<Stack direction={{ xs: "column", md: "row" }} spacing={2}>
|
|
<TextField
|
|
{...register("contactEmail")}
|
|
label="Contact Email"
|
|
type="email"
|
|
required
|
|
error={Boolean(errors.contactEmail)}
|
|
helperText={errors.contactEmail?.message}
|
|
fullWidth
|
|
/>
|
|
<Controller
|
|
name="status"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<FormControl fullWidth required error={Boolean(errors.status)}>
|
|
<InputLabel id="status-label">Status</InputLabel>
|
|
<Select {...field} labelId="status-label" label="Status" value={field.value}>
|
|
{LOCATION_STATUS_OPTIONS.map((status) => (
|
|
<MenuItem key={status} value={status}>
|
|
{status}
|
|
</MenuItem>
|
|
))}
|
|
</Select>
|
|
</FormControl>
|
|
)}
|
|
/>
|
|
</Stack>
|
|
</Stack>
|
|
);
|
|
}
|