From 85e1bcc06f6db15171263553b823181e2a60ffff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Sat, 11 Apr 2026 08:30:33 +0200 Subject: [PATCH] refactor(web): decompose ProjectWizard into step components Extract each wizard step into its own file under project-wizard/: StepBar, DynamicFieldInput, Step1Identity, ResourcePersonPicker, Step2Timeline, Step3Staffing, Step4Suggestions, Step5Review. Main file reduced from 1,385 to 112 lines. Co-Authored-By: Claude Opus 4.6 --- .../src/components/projects/ProjectWizard.tsx | 1297 +---------------- .../project-wizard/DynamicFieldInput.tsx | 109 ++ .../project-wizard/ResourcePersonPicker.tsx | 113 ++ .../projects/project-wizard/Step1Identity.tsx | 225 +++ .../projects/project-wizard/Step2Timeline.tsx | 80 + .../projects/project-wizard/Step3Staffing.tsx | 249 ++++ .../project-wizard/Step4Suggestions.tsx | 209 +++ .../projects/project-wizard/Step5Review.tsx | 233 +++ .../projects/project-wizard/StepBar.tsx | 43 + 9 files changed, 1273 insertions(+), 1285 deletions(-) create mode 100644 apps/web/src/components/projects/project-wizard/DynamicFieldInput.tsx create mode 100644 apps/web/src/components/projects/project-wizard/ResourcePersonPicker.tsx create mode 100644 apps/web/src/components/projects/project-wizard/Step1Identity.tsx create mode 100644 apps/web/src/components/projects/project-wizard/Step2Timeline.tsx create mode 100644 apps/web/src/components/projects/project-wizard/Step3Staffing.tsx create mode 100644 apps/web/src/components/projects/project-wizard/Step4Suggestions.tsx create mode 100644 apps/web/src/components/projects/project-wizard/Step5Review.tsx create mode 100644 apps/web/src/components/projects/project-wizard/StepBar.tsx diff --git a/apps/web/src/components/projects/ProjectWizard.tsx b/apps/web/src/components/projects/ProjectWizard.tsx index be99eb2..4ff8335 100644 --- a/apps/web/src/components/projects/ProjectWizard.tsx +++ b/apps/web/src/components/projects/ProjectWizard.tsx @@ -1,1288 +1,15 @@ "use client"; -import { createPortal } from "react-dom"; -import { useState, useEffect, useMemo, useRef } from "react"; -import { clsx } from "clsx"; -import type { StaffingRequirement, BlueprintFieldDefinition } from "@capakraken/shared"; -import { BlueprintTarget, FieldType, RolePresetsSchema } from "@capakraken/shared"; -import { trpc } from "~/lib/trpc/client.js"; -import { uuid } from "~/lib/uuid.js"; -import { DateInput } from "~/components/ui/DateInput.js"; -import { SkillTagInput } from "~/components/ui/SkillTagInput.js"; -import { usePermissions } from "~/hooks/usePermissions.js"; -import { InfoTooltip } from "~/components/ui/InfoTooltip.js"; -import { formatCents } from "~/lib/format.js"; import { ConfettiBurst } from "~/components/ui/ConfettiBurst.js"; import { SuccessToast } from "~/components/ui/SuccessToast.js"; -import { useAnchoredOverlay } from "~/hooks/useAnchoredOverlay.js"; -import { - ORDER_TYPE_OPTIONS, - ALLOCATION_TYPE_OPTIONS, - BTN_PRIMARY, - BTN_SECONDARY, - STEPS, - makeReq, - type Assignment, - type WizardState, - type SuggestionItem, -} from "./project-wizard/types.js"; +import { BTN_PRIMARY, BTN_SECONDARY } from "./project-wizard/types.js"; import { useProjectWizardForm } from "./project-wizard/useProjectWizardForm.js"; - -// ─── Step indicators ───────────────────────────────────────────────────────── - -function StepBar({ current }: { current: number }) { - return ( -
- {STEPS.map((label, idx) => ( -
-
-
- {idx < current ? "✓" : idx + 1} -
- - {label} - -
- {idx < STEPS.length - 1 && ( -
- )} -
- ))} -
- ); -} - -// ─── Dynamic Field Input ────────────────────────────────────────────────────── - -function DynamicFieldInput({ - field, - value, - onChange, -}: { - field: BlueprintFieldDefinition; - value: unknown; - onChange: (key: string, val: unknown) => void; -}) { - const strVal = value !== undefined && value !== null ? String(value) : ""; - const arrVal = Array.isArray(value) ? (value as string[]) : []; - - switch (field.type) { - case FieldType.TEXTAREA: - return ( -