) => void;
+}) {
+ return (
+ |
+ onPatch({ type: t, severity: sev })}
+ />
+ |
+ );
+}
+
function InlineMutedDashCell() {
return (
@@ -81,9 +99,7 @@ export function WoTableInlineRowCells({
onDuplicateFound={onDuplicateFound}
/>
- |
- onPatch({ type: t })} />
- |
+
e.stopPropagation()}
>
- onPatchRow({ type: t })} />
+ onPatchRow({ type: t, severity: sev })}
+ />
|
({ id: p.id, value: p.value }))}
+ showErrors={wizard.showErrors}
svcOpen={wizard.svcOpen}
onSvcOpenChange={wizard.setSvcOpen}
svcSearch={wizard.svcSearch}
@@ -108,8 +110,15 @@ export function NewWoWizard({
onCancel={() => {
if (!wizard.isCreating) onOpenChange(false);
}}
- onBack={() => wizard.setStep((s) => s - 1)}
- onContinue={() => wizard.setStep((s) => s + 1)}
+ onBack={() => {
+ wizard.setShowErrors(false);
+ wizard.setStep((s) => s - 1);
+ }}
+ onContinue={() => {
+ wizard.setShowErrors(false);
+ wizard.setStep((s) => s + 1);
+ }}
+ onAttemptContinue={() => wizard.setShowErrors(true)}
onCreate={wizard.handleCreate}
isCreating={wizard.isCreating}
/>
diff --git a/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-draft.ts b/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-draft.ts
index a3f6a348..c0d45525 100644
--- a/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-draft.ts
+++ b/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-draft.ts
@@ -13,6 +13,7 @@ export function useNewWoWizardDraft(open: boolean) {
});
const [svcOpen, setSvcOpen] = useState(false);
const [svcSearch, setSvcSearch] = useState("");
+ const [showErrors, setShowErrors] = useState(false);
useEffect(() => {
if (open) {
@@ -20,6 +21,7 @@ export function useNewWoWizardDraft(open: boolean) {
setDraft({ ...EMPTY_WIZARD_DRAFT, status: "Incomplete" });
setSvcOpen(false);
setSvcSearch("");
+ setShowErrors(false);
}
}, [open]);
@@ -45,5 +47,7 @@ export function useNewWoWizardDraft(open: boolean) {
setSvcOpen,
svcSearch,
setSvcSearch,
+ showErrors,
+ setShowErrors,
};
}
diff --git a/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-state.ts b/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-state.ts
index 748fb3c5..8f6b1e66 100644
--- a/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-state.ts
+++ b/src/app/(protected)/workorders/_components/wizard/use-new-wo-wizard-state.ts
@@ -37,6 +37,7 @@ export function useNewWoWizardState({
}: UseNewWoWizardStateArgs) {
const mockFallback = isWoWizardMockEnabled();
const [step, setStep] = useState(1);
+ const [showErrors, setShowErrors] = useState(false);
const [draft, setDraft] = useState({
...EMPTY_WIZARD_DRAFT,
status: "Incomplete",
@@ -81,6 +82,7 @@ export function useNewWoWizardState({
useEffect(() => {
if (open) {
setStep(1);
+ setShowErrors(false);
setDraft({ ...EMPTY_WIZARD_DRAFT, status: "Incomplete" });
setPocAutoFilledFor("");
setDuplicateRow(null);
@@ -119,6 +121,8 @@ export function useNewWoWizardState({
return {
step,
setStep,
+ showErrors,
+ setShowErrors,
draft,
duplicateRow,
setDuplicateRow,
diff --git a/src/app/(protected)/workorders/_components/wizard/wizard-footer.tsx b/src/app/(protected)/workorders/_components/wizard/wizard-footer.tsx
index 4240f19a..6f01be6a 100644
--- a/src/app/(protected)/workorders/_components/wizard/wizard-footer.tsx
+++ b/src/app/(protected)/workorders/_components/wizard/wizard-footer.tsx
@@ -3,8 +3,10 @@ import { Button } from "@/components/ui/button";
import {
WIZARD_STEPS,
canContinueWizardStep1,
+ canContinueWizardStep2,
canCreateWorkOrderFromWizard,
isWizardStepValid,
+ isWizardWoNumberValid,
type WorkOrderWizardDraft,
} from "@/domain/work-orders/types/work-order-wizard";
@@ -15,9 +17,24 @@ type WizardFooterProps = {
onBack: () => void;
onContinue: () => void;
onCreate: () => void;
+ onAttemptContinue?: () => void;
isCreating: boolean;
};
+function stepHint(step: number, draft: WorkOrderWizardDraft): string | null {
+ if (step === 1 && !canContinueWizardStep1(draft)) {
+ if (!isWizardWoNumberValid(draft.woNumber)) {
+ return "Enter an alphanumeric WO number, or leave blank for SH generation";
+ }
+ return "Select severity to continue";
+ }
+ if (step === 2 && !canContinueWizardStep2(draft)) {
+ if (!draft.locationId) return "Pick a site to continue";
+ return "Enter POC name and phone to continue";
+ }
+ return null;
+}
+
export function WizardFooter({
step,
draft,
@@ -25,11 +42,12 @@ export function WizardFooter({
onBack,
onContinue,
onCreate,
+ onAttemptContinue,
isCreating,
}: WizardFooterProps) {
const stepValid = isWizardStepValid(step, draft);
const canCreate = canCreateWorkOrderFromWizard(draft);
- const canContinue1 = canContinueWizardStep1(draft);
+ const hint = stepHint(step, draft);
return (
- {step === 1 && !canContinue1 && (
+ {Boolean(hint) && (
- Pick a type to continue
+ {hint}
)}
{step < WIZARD_STEPS.length ? (
) : (
|