mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-01 13:13:11 +00:00
fix(work-orders): extract completed vendor dialog to pass maintainability
This commit is contained in:
parent
eeb415951c
commit
17ad0e5098
4 changed files with 127 additions and 69 deletions
|
|
@ -0,0 +1,40 @@
|
|||
import { Button } from "@mui/material";
|
||||
import type { VendorEditorState } from "./work-order-vendor-editor-types";
|
||||
import { isVendorEditorValid } from "./work-order-vendor-editor-utils";
|
||||
|
||||
type WorkOrderVendorEditorActionsProps = {
|
||||
viewOnly: boolean;
|
||||
editor: VendorEditorState | null;
|
||||
loading: boolean;
|
||||
isSaving: boolean;
|
||||
onClose: () => void;
|
||||
onSave: () => void;
|
||||
};
|
||||
|
||||
export function WorkOrderVendorEditorActions({
|
||||
viewOnly,
|
||||
editor,
|
||||
loading,
|
||||
isSaving,
|
||||
onClose,
|
||||
onSave,
|
||||
}: WorkOrderVendorEditorActionsProps) {
|
||||
if (viewOnly) {
|
||||
return <Button onClick={onClose}>Close</Button>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={onClose} disabled={isSaving}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={onSave}
|
||||
disabled={!editor || loading || isSaving || !isVendorEditorValid(editor)}
|
||||
>
|
||||
{isSaving ? "Saving..." : "Save"}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,18 +1,17 @@
|
|||
import {
|
||||
Alert,
|
||||
Box,
|
||||
Button,
|
||||
CircularProgress,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
Stack,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import type { VendorEditorState } from "./work-order-vendor-editor-types";
|
||||
import { formatPhoneMask, isVendorEditorValid } from "./work-order-vendor-editor-utils";
|
||||
import { WorkOrderVendorEditorActions } from "./work-order-vendor-editor-actions";
|
||||
import { WorkOrderVendorEditorFields } from "./work-order-vendor-editor-fields";
|
||||
|
||||
type WorkOrderVendorEditorDialogProps = {
|
||||
editor: VendorEditorState | null;
|
||||
|
|
@ -51,75 +50,23 @@ export function WorkOrderVendorEditorDialog({
|
|||
<CircularProgress size={28} />
|
||||
</Box>
|
||||
) : (
|
||||
<>
|
||||
<TextField
|
||||
label="Technician name"
|
||||
value={editor?.contactName ?? ""}
|
||||
disabled={viewOnly}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, contactName: event.target.value } : current,
|
||||
)
|
||||
}
|
||||
slotProps={{ htmlInput: { maxLength: 200 } }}
|
||||
/>
|
||||
<TextField
|
||||
label="Phone"
|
||||
value={editor?.phone ?? ""}
|
||||
disabled={viewOnly}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, phone: formatPhoneMask(event.target.value) } : current,
|
||||
)
|
||||
}
|
||||
error={Boolean(editor?.phone && !/^\(\d{3}\) \d{3}-\d{4}$/.test(editor.phone))}
|
||||
helperText="Use (XXX) XXX-XXXX"
|
||||
/>
|
||||
<TextField
|
||||
label="Email"
|
||||
type="email"
|
||||
value={editor?.email ?? ""}
|
||||
disabled={viewOnly}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, email: event.target.value } : current,
|
||||
)
|
||||
}
|
||||
/>
|
||||
<TextField
|
||||
label="Notes"
|
||||
multiline
|
||||
minRows={3}
|
||||
value={editor?.notes ?? ""}
|
||||
disabled={viewOnly}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, notes: event.target.value } : current,
|
||||
)
|
||||
}
|
||||
slotProps={{ htmlInput: { maxLength: 2000 } }}
|
||||
/>
|
||||
</>
|
||||
<WorkOrderVendorEditorFields
|
||||
editor={editor}
|
||||
disabled={viewOnly}
|
||||
onEditorChange={onEditorChange}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
{viewOnly ? (
|
||||
<Button onClick={onClose}>Close</Button>
|
||||
) : (
|
||||
<>
|
||||
<Button onClick={onClose} disabled={isSaving}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={onSave}
|
||||
disabled={!editor || loading || isSaving || !isVendorEditorValid(editor)}
|
||||
>
|
||||
{isSaving ? "Saving..." : "Save"}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<WorkOrderVendorEditorActions
|
||||
viewOnly={viewOnly}
|
||||
editor={editor}
|
||||
loading={loading}
|
||||
isSaving={isSaving}
|
||||
onClose={onClose}
|
||||
onSave={onSave}
|
||||
/>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
import { TextField } from "@mui/material";
|
||||
import type { VendorEditorState } from "./work-order-vendor-editor-types";
|
||||
import { formatPhoneMask } from "./work-order-vendor-editor-utils";
|
||||
|
||||
type VendorEditorChange = (
|
||||
updater: (current: VendorEditorState | null) => VendorEditorState | null,
|
||||
) => void;
|
||||
|
||||
type WorkOrderVendorEditorFieldsProps = {
|
||||
editor: VendorEditorState | null;
|
||||
disabled: boolean;
|
||||
onEditorChange: VendorEditorChange;
|
||||
};
|
||||
|
||||
export function WorkOrderVendorEditorFields({
|
||||
editor,
|
||||
disabled,
|
||||
onEditorChange,
|
||||
}: WorkOrderVendorEditorFieldsProps) {
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
label="Technician name"
|
||||
value={editor?.contactName ?? ""}
|
||||
disabled={disabled}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, contactName: event.target.value } : current,
|
||||
)
|
||||
}
|
||||
slotProps={{ htmlInput: { maxLength: 200 } }}
|
||||
/>
|
||||
<TextField
|
||||
label="Phone"
|
||||
value={editor?.phone ?? ""}
|
||||
disabled={disabled}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, phone: formatPhoneMask(event.target.value) } : current,
|
||||
)
|
||||
}
|
||||
error={Boolean(editor?.phone && !/^\(\d{3}\) \d{3}-\d{4}$/.test(editor.phone))}
|
||||
helperText="Use (XXX) XXX-XXXX"
|
||||
/>
|
||||
<TextField
|
||||
label="Email"
|
||||
type="email"
|
||||
value={editor?.email ?? ""}
|
||||
disabled={disabled}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, email: event.target.value } : current,
|
||||
)
|
||||
}
|
||||
/>
|
||||
<TextField
|
||||
label="Notes"
|
||||
multiline
|
||||
minRows={3}
|
||||
value={editor?.notes ?? ""}
|
||||
disabled={disabled}
|
||||
onChange={(event) =>
|
||||
onEditorChange((current) =>
|
||||
current ? { ...current, notes: event.target.value } : current,
|
||||
)
|
||||
}
|
||||
slotProps={{ htmlInput: { maxLength: 2000 } }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -117,7 +117,7 @@ function WizardVendorDetail({
|
|||
);
|
||||
}
|
||||
|
||||
type WizardApptTimeFieldsProps = Omit<WizardStepVendorTimeProps, "vendors">;
|
||||
type WizardApptTimeFieldsProps = Pick<WizardStepVendorTimeProps, "draft" | "onUpdate" | "onPatch">;
|
||||
|
||||
function WizardApptTimeFields({ draft, onUpdate, onPatch }: WizardApptTimeFieldsProps) {
|
||||
const duration = calcDuration(draft.apptStart, draft.apptEnd);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue