@burdenoff/microfe-timecampus 2026.703.7 → 2026.707.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/wspace-operations.js +1023 -1514
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js +12 -18
- package/dist/generated/wspace-types.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/timecampus/TimeCampusRoot.js +82 -150
- package/dist/timecampus/TimeCampusRoot.js.map +1 -1
- package/dist/timecampus/TimeCampusRoutes.js +96 -164
- package/dist/timecampus/TimeCampusRoutes.js.map +1 -1
- package/dist/timecampus/components/index.js +2 -2
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +7 -7
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js +6 -6
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +8 -8
- package/dist/timecampus/pages/geofencing/GeofencingPage.js +6 -6
- package/dist/timecampus/pages/lifetime/FiniteLifePage.js +91 -91
- package/dist/timecampus/pages/lifetime/FiniteLifePage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/LifeBalancePage.js +18 -18
- package/dist/timecampus/pages/lifetime/LifeTimelinePage.js +7 -7
- package/dist/timecampus/pages/lifetime/ValuesGoalsPage.js +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +6 -6
- package/dist/timecampus/pages/projects/ProjectDetailPage.js +7 -7
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +212 -212
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamMembersPage.js +4 -4
- package/dist/timecampus/pages/time/TimeTrackingPage.js +143 -143
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +1 -1
- package/dist/timecampus/pages/timeline/TimelinePage.js +1 -1
- package/dist/timecampus/pages/timeline/TimelinePage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +87 -93
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
- package/package.json +1 -1
- package/dist/timecampus/pages/applets/AppletStorePage.js +0 -167
- package/dist/timecampus/pages/applets/AppletStorePage.js.map +0 -1
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js +0 -162
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +0 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +0 -133
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +0 -1
- package/dist/timecampus/pages/channels/ChannelsPage.js +0 -418
- package/dist/timecampus/pages/channels/ChannelsPage.js.map +0 -1
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +0 -142
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +0 -1
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +0 -119
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +0 -1
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +0 -110
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +0 -1
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +0 -83
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +0 -1
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +0 -198
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +0 -1
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +0 -124
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +0 -1
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js +0 -88
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +0 -1
- package/dist/timecampus/pages/templates/TemplateDetailPage.js +0 -135
- package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +0 -1
- package/dist/timecampus/pages/templates/TemplatesPage.js +0 -191
- package/dist/timecampus/pages/templates/TemplatesPage.js.map +0 -1
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js +0 -196
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +0 -1
- package/dist/timecampus/pages/widgets/WidgetsPage.js +0 -297
- package/dist/timecampus/pages/widgets/WidgetsPage.js.map +0 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +0 -133
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +0 -1
- package/dist/timecampus/pages/workflows/WorkflowsPage.js +0 -311
- package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResourcePlanningPage.js","names":[],"sources":["../../../../src/timecampus/pages/resource-planning/ResourcePlanningPage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n CalendarRange,\n Users,\n TrendingUp,\n Plus,\n Pencil,\n Trash2,\n UserPlus,\n AlertTriangle,\n} from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { Modal } from \"../../components/Modal\";\nimport {\n ChartCard,\n DonutChart,\n RadialGauge,\n ProgressMeter,\n StatusBadge,\n type MeterTone,\n} from \"../../components\";\nimport { getInitials, formatHours } from \"../../utils/helpers\";\nimport {\n useListResourcePlansQuery,\n useGetCapacityOverviewQuery,\n useCreateResourcePlanMutation,\n useUpdateResourcePlanMutation,\n useDeleteResourcePlanMutation,\n useCreateAllocationMutation,\n useUpdateAllocationMutation,\n useDeleteAllocationMutation,\n useBulkCreateAllocationsMutation,\n type ResourcePlanFieldsFragment,\n type ResourceAllocationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst PAGE_SIZE = 25;\n\nconst inputClass =\n \"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\";\n\nconst toDateInput = (iso: string) => iso.slice(0, 10);\nconst toIso = (dateStr: string) => new Date(dateStr).toISOString();\n\ninterface PlanFormState {\n name: string;\n description: string;\n startDate: string;\n endDate: string;\n status: string;\n}\n\ninterface AllocationRow {\n userId: string;\n allocatedHours: string;\n startDate: string;\n endDate: string;\n notes: string;\n}\n\ninterface AllocationEditState {\n userId: string;\n allocatedHours: string;\n actualHours: string;\n startDate: string;\n endDate: string;\n notes: string;\n}\n\nconst emptyPlanForm = (): PlanFormState => {\n const now = new Date();\n const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const end = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7);\n return {\n name: \"\",\n description: \"\",\n startDate: toDateInput(start.toISOString()),\n endDate: toDateInput(end.toISOString()),\n status: \"active\",\n };\n};\n\nconst emptyAllocationRow = (\n plan?: ResourcePlanFieldsFragment,\n): AllocationRow => ({\n userId: \"\",\n allocatedHours: \"\",\n startDate: plan ? toDateInput(plan.startDate) : \"\",\n endDate: plan ? toDateInput(plan.endDate) : \"\",\n notes: \"\",\n});\n\nexport function ResourcePlanningPage() {\n const now = new Date();\n const startDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate(),\n ).toISOString();\n const endDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate() + 7,\n ).toISOString();\n\n const {\n data: plansData,\n loading: plansLoading,\n error: plansError,\n refetch: refetchPlans,\n fetchMore,\n } = useListResourcePlansQuery({ variables: { limit: PAGE_SIZE, offset: 0 } });\n const { data: capacityData, refetch: refetchCapacity } =\n useGetCapacityOverviewQuery({ variables: { startDate, endDate } });\n\n const [createPlan, { loading: creatingPlan, error: createPlanError }] =\n useCreateResourcePlanMutation();\n const [updatePlan, { loading: updatingPlan, error: updatePlanError }] =\n useUpdateResourcePlanMutation();\n const [deletePlan, { loading: deletingPlan }] =\n useDeleteResourcePlanMutation();\n const [createAllocation, { loading: creatingAlloc }] =\n useCreateAllocationMutation();\n const [bulkCreateAllocations, { loading: bulkCreating }] =\n useBulkCreateAllocationsMutation();\n const [\n updateAllocation,\n { loading: updatingAlloc, error: updateAllocError },\n ] = useUpdateAllocationMutation();\n const [deleteAllocation, { loading: deletingAlloc }] =\n useDeleteAllocationMutation();\n\n const [planModalOpen, setPlanModalOpen] = useState(false);\n const [editingPlan, setEditingPlan] =\n useState<ResourcePlanFieldsFragment | null>(null);\n const [planForm, setPlanForm] = useState<PlanFormState>(emptyPlanForm());\n const [confirmDeletePlan, setConfirmDeletePlan] =\n useState<ResourcePlanFieldsFragment | null>(null);\n\n const [allocModalPlan, setAllocModalPlan] =\n useState<ResourcePlanFieldsFragment | null>(null);\n const [allocRows, setAllocRows] = useState<AllocationRow[]>([]);\n const [allocError, setAllocError] = useState(false);\n\n const [editingAlloc, setEditingAlloc] =\n useState<ResourceAllocationFieldsFragment | null>(null);\n const [allocEditForm, setAllocEditForm] =\n useState<AllocationEditState | null>(null);\n const [confirmDeleteAlloc, setConfirmDeleteAlloc] =\n useState<ResourceAllocationFieldsFragment | null>(null);\n\n const [loadingMore, setLoadingMore] = useState(false);\n\n const plans = plansData?.resourcePlans?.items ?? [];\n const hasMore = plansData?.resourcePlans?.hasMore ?? false;\n const capacity = capacityData?.capacityOverview;\n\n const refetchAll = async () => {\n await Promise.all([refetchPlans(), refetchCapacity()]);\n };\n\n // -- Plan handlers --------------------------------------------------------\n const openCreatePlan = () => {\n setEditingPlan(null);\n setPlanForm(emptyPlanForm());\n setPlanModalOpen(true);\n };\n\n const openEditPlan = (plan: ResourcePlanFieldsFragment) => {\n setEditingPlan(plan);\n setPlanForm({\n name: plan.name,\n description: plan.description ?? \"\",\n startDate: toDateInput(plan.startDate),\n endDate: toDateInput(plan.endDate),\n status: plan.status,\n });\n setPlanModalOpen(true);\n };\n\n const handleSubmitPlan = async () => {\n if (!planForm.name.trim()) return;\n if (editingPlan) {\n await updatePlan({\n variables: {\n id: editingPlan.id,\n input: {\n name: planForm.name.trim(),\n description: planForm.description.trim() || undefined,\n startDate: toIso(planForm.startDate),\n endDate: toIso(planForm.endDate),\n status: planForm.status,\n },\n },\n });\n } else {\n await createPlan({\n variables: {\n input: {\n name: planForm.name.trim(),\n description: planForm.description.trim() || undefined,\n startDate: toIso(planForm.startDate),\n endDate: toIso(planForm.endDate),\n },\n },\n });\n }\n setPlanModalOpen(false);\n await refetchAll();\n };\n\n const handleDeletePlan = async () => {\n if (!confirmDeletePlan) return;\n await deletePlan({ variables: { id: confirmDeletePlan.id } });\n setConfirmDeletePlan(null);\n await refetchAll();\n };\n\n // -- Allocation handlers --------------------------------------------------\n const openAddAllocation = (plan: ResourcePlanFieldsFragment) => {\n setAllocModalPlan(plan);\n setAllocRows([emptyAllocationRow(plan)]);\n setAllocError(false);\n };\n\n const updateAllocRow = (index: number, patch: Partial<AllocationRow>) => {\n setAllocRows((rows) =>\n rows.map((r, i) => (i === index ? { ...r, ...patch } : r)),\n );\n };\n\n const addAllocRow = () => {\n setAllocRows((rows) => [\n ...rows,\n emptyAllocationRow(allocModalPlan ?? undefined),\n ]);\n };\n\n const removeAllocRow = (index: number) => {\n setAllocRows((rows) => rows.filter((_, i) => i !== index));\n };\n\n const allocRowsValid = allocRows.every(\n (r) =>\n r.userId.trim() !== \"\" &&\n r.allocatedHours.trim() !== \"\" &&\n r.startDate !== \"\" &&\n r.endDate !== \"\",\n );\n\n const handleSubmitAllocations = async () => {\n if (!allocModalPlan || !allocRowsValid || allocRows.length === 0) return;\n setAllocError(false);\n try {\n if (allocRows.length === 1) {\n const r = allocRows[0];\n await createAllocation({\n variables: {\n input: {\n resourcePlanId: allocModalPlan.id,\n userId: r.userId.trim(),\n allocatedHours: Number(r.allocatedHours),\n startDate: toIso(r.startDate),\n endDate: toIso(r.endDate),\n notes: r.notes.trim() || undefined,\n },\n },\n });\n } else {\n await bulkCreateAllocations({\n variables: {\n planId: allocModalPlan.id,\n allocations: allocRows.map((r) => ({\n userId: r.userId.trim(),\n allocatedHours: Number(r.allocatedHours),\n startDate: toIso(r.startDate),\n endDate: toIso(r.endDate),\n notes: r.notes.trim() || undefined,\n })),\n },\n });\n }\n setAllocModalPlan(null);\n await refetchAll();\n } catch {\n setAllocError(true);\n }\n };\n\n const openEditAllocation = (alloc: ResourceAllocationFieldsFragment) => {\n setEditingAlloc(alloc);\n setAllocEditForm({\n userId: alloc.userId,\n allocatedHours: String(alloc.allocatedHours),\n actualHours: String(alloc.actualHours),\n startDate: toDateInput(alloc.startDate),\n endDate: toDateInput(alloc.endDate),\n notes: alloc.notes ?? \"\",\n });\n };\n\n const handleSubmitAllocEdit = async () => {\n if (!editingAlloc || !allocEditForm) return;\n await updateAllocation({\n variables: {\n id: editingAlloc.id,\n input: {\n userId: allocEditForm.userId.trim(),\n allocatedHours: Number(allocEditForm.allocatedHours),\n actualHours: Number(allocEditForm.actualHours),\n startDate: toIso(allocEditForm.startDate),\n endDate: toIso(allocEditForm.endDate),\n notes: allocEditForm.notes.trim() || undefined,\n },\n },\n });\n setEditingAlloc(null);\n setAllocEditForm(null);\n await refetchAll();\n };\n\n const handleDeleteAllocation = async () => {\n if (!confirmDeleteAlloc) return;\n await deleteAllocation({ variables: { id: confirmDeleteAlloc.id } });\n setConfirmDeleteAlloc(null);\n await refetchAll();\n };\n\n const handleLoadMore = async () => {\n setLoadingMore(true);\n try {\n await fetchMore({\n variables: { limit: PAGE_SIZE, offset: plans.length },\n updateQuery: (prev, { fetchMoreResult }) => {\n if (!fetchMoreResult) return prev;\n return {\n resourcePlans: {\n ...fetchMoreResult.resourcePlans,\n items: [\n ...prev.resourcePlans.items,\n ...fetchMoreResult.resourcePlans.items,\n ],\n },\n };\n },\n });\n } finally {\n setLoadingMore(false);\n }\n };\n\n const newPlanButton = (\n <button\n onClick={openCreatePlan}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus className=\"h-4 w-4\" />\n New Resource Plan\n </button>\n );\n\n if (plansLoading) {\n return (\n <PageLayout\n title=\"Resource Planning\"\n description=\"Plan and optimize team resource allocation\"\n >\n <LoadingSkeleton variant=\"list\" count={5} />\n </PageLayout>\n );\n }\n\n if (plansError) {\n return (\n <PageLayout\n title=\"Resource Planning\"\n description=\"Plan and optimize team resource allocation\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load resource planning data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const utilizationRate = capacity?.utilizationRate ?? 0;\n const overallocatedUsers = capacity?.overallocatedUsers ?? [];\n const overallocatedCount = overallocatedUsers.length;\n const availableHours = capacity?.availableCapacity ?? 0;\n const allocatedHours = capacity?.allocatedCapacity ?? 0;\n const totalHours = capacity?.totalCapacity ?? 0;\n const hasCapacity =\n !!capacity &&\n (totalHours > 0 || allocatedHours > 0 || overallocatedCount > 0);\n\n return (\n <PageLayout\n title=\"Resource Planning\"\n description=\"Plan and optimize team resource allocation\"\n purpose=\"Match the work ahead to the people you have — see who's over- or under-booked and how much capacity is free this week — so you can commit to deadlines you can actually hit without burning anyone out.\"\n actions={newPlanButton}\n >\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Team Utilization\"\n value={`${Math.round(utilizationRate)}%`}\n icon={<TrendingUp className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Over-allocated\"\n value={String(overallocatedCount)}\n icon={<Users className=\"h-5 w-5\" />}\n iconBgColor=\"bg-status-error-bg text-status-error-text\"\n />\n <StatCard\n title=\"Active Plans\"\n value={String(plans.length)}\n icon={<Users className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Available Capacity\"\n value={`${Math.round(availableHours)}h`}\n icon={<CalendarRange className=\"h-5 w-5\" />}\n description=\"This week\"\n />\n </div>\n\n {hasCapacity && (\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <ChartCard\n title=\"Capacity split\"\n description=\"Allocated vs available hours this week\"\n >\n <DonutChart\n data={[\n { name: \"Allocated\", value: allocatedHours },\n { name: \"Available\", value: availableHours },\n ]}\n centerLabel=\"Total\"\n centerValue={`${Math.round(totalHours)}h`}\n valueFormat={(v) => `${Math.round(v)}h`}\n emptyLabel=\"No capacity data yet\"\n />\n </ChartCard>\n <ChartCard\n title=\"Utilization & over-allocation\"\n description=\"Team utilization and who is over-booked this week\"\n >\n <RadialGauge\n value={Math.round(utilizationRate)}\n max={100}\n label=\"Utilization\"\n sublabel=\"this week\"\n format={(v) => `${Math.round(v)}%`}\n />\n <div className=\"mt-4\">\n <p className=\"mb-2 text-xs font-medium text-text-secondary\">\n Over-allocated ({overallocatedCount})\n </p>\n {overallocatedCount === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n No one is over-allocated this week.\n </p>\n ) : (\n <div className=\"flex flex-wrap gap-2\">\n {overallocatedUsers.map((userId: string) => (\n <span\n key={userId}\n className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg px-2.5 py-0.5 text-xs font-medium text-status-warning-text\"\n >\n <AlertTriangle className=\"h-3.5 w-3.5\" />\n {userId}\n </span>\n ))}\n </div>\n )}\n </div>\n </ChartCard>\n </div>\n )}\n\n {plans.length === 0 ? (\n <EmptyState\n illustration=\"empty-people\"\n title=\"No resource plans yet\"\n description=\"Create a resource plan to start allocating team members and balancing workload across the week.\"\n action={newPlanButton}\n />\n ) : (\n <div className=\"space-y-6\">\n {plans.map((plan: ResourcePlanFieldsFragment) => (\n <GlassCard\n key={plan.id}\n treatment=\"glass\"\n className=\"overflow-hidden\"\n >\n <div className=\"flex flex-col gap-3 border-b border-border-seam p-5 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {plan.name}\n </p>\n <StatusBadge label={plan.status} status={plan.status} />\n </div>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {plan.startDate.slice(0, 10)} to{\" \"}\n {plan.endDate.slice(0, 10)} ·{\" \"}\n {plan.allocations.length}{\" \"}\n {plan.allocations.length === 1 ? \"person\" : \"people\"}\n </p>\n <div className=\"mt-3 max-w-sm\">\n <ProgressMeter\n size=\"sm\"\n label=\"Logged vs allocated\"\n value={plan.totalActualHours}\n max={\n plan.totalAllocatedHours > 0\n ? plan.totalAllocatedHours\n : Math.max(plan.totalActualHours, 1)\n }\n format={(v) => formatHours(v)}\n />\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={() => openAddAllocation(plan)}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-2.5 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <UserPlus className=\"h-3.5 w-3.5\" />\n Add Allocation\n </button>\n <button\n onClick={() => openEditPlan(plan)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-2.5 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n Edit\n </button>\n <button\n onClick={() => setConfirmDeletePlan(plan)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-2.5 py-1.5 text-xs font-medium text-status-error-text hover:bg-status-error-bg\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n Delete\n </button>\n </div>\n </div>\n\n {plan.allocations.length === 0 ? (\n <div className=\"p-5 text-sm text-text-secondary\">\n No allocations yet. Use “Add Allocation” to\n assign team members.\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-xs text-text-secondary\">\n <th className=\"whitespace-nowrap px-5 py-2.5 font-medium\">\n Member\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 font-medium\">\n Window\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 text-right font-medium\">\n Allocated\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 text-right font-medium\">\n Actual\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 font-medium\">\n Utilization\n </th>\n <th className=\"whitespace-nowrap px-5 py-2.5 text-right font-medium\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-seam\">\n {plan.allocations.map(\n (alloc: ResourceAllocationFieldsFragment) => {\n const utilization =\n alloc.utilizationRate ??\n (alloc.allocatedHours > 0\n ? Math.round(\n (alloc.actualHours / alloc.allocatedHours) *\n 100,\n )\n : 0);\n const tone: MeterTone =\n utilization > 100\n ? \"danger\"\n : utilization < 70\n ? \"warning\"\n : \"success\";\n const toneText =\n tone === \"danger\"\n ? \"text-status-error-text\"\n : tone === \"warning\"\n ? \"text-status-warning-text\"\n : \"text-status-success-text\";\n return (\n <tr\n key={alloc.id}\n className=\"transition-colors hover:bg-bg-sunken/50\"\n >\n <td className=\"whitespace-nowrap px-5 py-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-action-primary-bg/10 text-sm font-medium text-primary\">\n {getInitials(alloc.userId)}\n </div>\n <span className=\"font-medium text-text-primary\">\n {alloc.userId}\n </span>\n </div>\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-text-secondary\">\n {alloc.startDate.slice(0, 10)} to{\" \"}\n {alloc.endDate.slice(0, 10)}\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-right font-medium text-text-primary\">\n {formatHours(alloc.allocatedHours)}\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-right text-text-secondary\">\n {formatHours(alloc.actualHours)}\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"flex w-40 items-center gap-2\">\n <ProgressMeter\n size=\"sm\"\n value={utilization}\n max={100}\n tone={tone}\n showValue={false}\n className=\"flex-1\"\n />\n <span\n className={`shrink-0 text-xs font-medium tabular-nums ${toneText}`}\n >\n {utilization}%\n </span>\n </div>\n </td>\n <td className=\"whitespace-nowrap px-5 py-3\">\n <div className=\"flex items-center justify-end gap-1\">\n <button\n onClick={() => openEditAllocation(alloc)}\n aria-label=\"Edit allocation\"\n className=\"rounded-md border border-border-subtle p-1.5 text-text-primary hover:bg-bg-sunken/50\"\n >\n <Pencil className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() =>\n setConfirmDeleteAlloc(alloc)\n }\n aria-label=\"Delete allocation\"\n className=\"rounded-md border border-border-subtle p-1.5 text-status-error-text hover:bg-status-error-bg\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n </td>\n </tr>\n );\n },\n )}\n </tbody>\n </table>\n </div>\n )}\n </GlassCard>\n ))}\n {hasMore && (\n <div className=\"flex justify-center\">\n <button\n onClick={handleLoadMore}\n disabled={loadingMore}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50 disabled:opacity-50\"\n >\n {loadingMore ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Plan create/edit modal */}\n <Modal\n open={planModalOpen}\n onClose={() => setPlanModalOpen(false)}\n title={editingPlan ? \"Edit Resource Plan\" : \"New Resource Plan\"}\n description=\"Set the window this plan covers, then allocate people to it.\"\n size=\"lg\"\n footer={\n <>\n <button\n onClick={() => setPlanModalOpen(false)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleSubmitPlan}\n disabled={creatingPlan || updatingPlan || !planForm.name.trim()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {creatingPlan || updatingPlan\n ? \"Saving...\"\n : editingPlan\n ? \"Save Changes\"\n : \"Create Plan\"}\n </button>\n </>\n }\n >\n {(createPlanError || updatePlanError) && (\n <div className=\"mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text\">\n Failed to save resource plan. Please try again.\n </div>\n )}\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Plan Name\n </label>\n <input\n type=\"text\"\n placeholder=\"e.g. Q3 Delivery\"\n value={planForm.name}\n onChange={(e) =>\n setPlanForm({ ...planForm, name: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Description (optional)\n </label>\n <textarea\n rows={2}\n placeholder=\"What this plan covers\"\n value={planForm.description}\n onChange={(e) =>\n setPlanForm({ ...planForm, description: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Start Date\n </label>\n <input\n type=\"date\"\n value={planForm.startDate}\n onChange={(e) =>\n setPlanForm({ ...planForm, startDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n End Date\n </label>\n <input\n type=\"date\"\n value={planForm.endDate}\n onChange={(e) =>\n setPlanForm({ ...planForm, endDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n </div>\n {editingPlan && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Status\n </label>\n <select\n value={planForm.status}\n onChange={(e) =>\n setPlanForm({ ...planForm, status: e.target.value })\n }\n className={inputClass}\n >\n <option value=\"active\">Active</option>\n <option value=\"draft\">Draft</option>\n <option value=\"completed\">Completed</option>\n <option value=\"archived\">Archived</option>\n </select>\n </div>\n )}\n </div>\n </Modal>\n\n {/* Add allocation(s) modal */}\n <Modal\n open={allocModalPlan !== null}\n onClose={() => setAllocModalPlan(null)}\n title=\"Add Allocation\"\n description={\n allocModalPlan\n ? `Assign team members to \"${allocModalPlan.name}\".`\n : undefined\n }\n size=\"xl\"\n footer={\n <>\n <button\n onClick={() => setAllocModalPlan(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleSubmitAllocations}\n disabled={creatingAlloc || bulkCreating || !allocRowsValid}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {creatingAlloc || bulkCreating\n ? \"Saving...\"\n : allocRows.length > 1\n ? `Add ${allocRows.length} Allocations`\n : \"Add Allocation\"}\n </button>\n </>\n }\n >\n {allocError && (\n <div className=\"mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text\">\n Failed to add allocations. Please check the values and try again.\n </div>\n )}\n <div className=\"space-y-4\">\n {allocRows.map((row, index) => (\n <div\n key={index}\n className=\"rounded-lg border border-border-subtle p-3\"\n >\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"text-xs font-medium text-text-secondary\">\n Allocation {index + 1}\n </span>\n {allocRows.length > 1 && (\n <button\n onClick={() => removeAllocRow(index)}\n className=\"text-xs font-medium text-status-error-text hover:underline\"\n >\n Remove\n </button>\n )}\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n User ID\n </label>\n <input\n type=\"text\"\n placeholder=\"User identifier\"\n value={row.userId}\n onChange={(e) =>\n updateAllocRow(index, { userId: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n Allocated Hours\n </label>\n <input\n type=\"number\"\n placeholder=\"0\"\n value={row.allocatedHours}\n onChange={(e) =>\n updateAllocRow(index, {\n allocatedHours: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n Start Date\n </label>\n <input\n type=\"date\"\n value={row.startDate}\n onChange={(e) =>\n updateAllocRow(index, { startDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n End Date\n </label>\n <input\n type=\"date\"\n value={row.endDate}\n onChange={(e) =>\n updateAllocRow(index, { endDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div className=\"sm:col-span-2\">\n <label className=\"block text-xs font-medium text-text-primary\">\n Notes (optional)\n </label>\n <input\n type=\"text\"\n placeholder=\"Context for this allocation\"\n value={row.notes}\n onChange={(e) =>\n updateAllocRow(index, { notes: e.target.value })\n }\n className={inputClass}\n />\n </div>\n </div>\n </div>\n ))}\n <button\n onClick={addAllocRow}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <Plus className=\"h-4 w-4\" />\n Add another person\n </button>\n </div>\n </Modal>\n\n {/* Edit allocation modal */}\n <Modal\n open={editingAlloc !== null && allocEditForm !== null}\n onClose={() => {\n setEditingAlloc(null);\n setAllocEditForm(null);\n }}\n title=\"Edit Allocation\"\n size=\"lg\"\n footer={\n <>\n <button\n onClick={() => {\n setEditingAlloc(null);\n setAllocEditForm(null);\n }}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleSubmitAllocEdit}\n disabled={updatingAlloc}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {updatingAlloc ? \"Saving...\" : \"Save Changes\"}\n </button>\n </>\n }\n >\n {updateAllocError && (\n <div className=\"mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text\">\n Failed to update allocation. Please try again.\n </div>\n )}\n {allocEditForm && (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n User ID\n </label>\n <input\n type=\"text\"\n value={allocEditForm.userId}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n userId: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Allocated Hours\n </label>\n <input\n type=\"number\"\n value={allocEditForm.allocatedHours}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n allocatedHours: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Actual Hours\n </label>\n <input\n type=\"number\"\n value={allocEditForm.actualHours}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n actualHours: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div />\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Start Date\n </label>\n <input\n type=\"date\"\n value={allocEditForm.startDate}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n startDate: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n End Date\n </label>\n <input\n type=\"date\"\n value={allocEditForm.endDate}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n endDate: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div className=\"sm:col-span-2\">\n <label className=\"block text-sm font-medium text-text-primary\">\n Notes (optional)\n </label>\n <input\n type=\"text\"\n value={allocEditForm.notes}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n notes: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n </div>\n )}\n </Modal>\n\n {/* Delete plan confirm */}\n <Modal\n open={confirmDeletePlan !== null}\n onClose={() => setConfirmDeletePlan(null)}\n title=\"Delete Resource Plan\"\n description=\"This action cannot be undone.\"\n footer={\n <>\n <button\n onClick={() => setConfirmDeletePlan(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleDeletePlan}\n disabled={deletingPlan}\n className=\"rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/80 disabled:opacity-50\"\n >\n {deletingPlan ? \"Deleting...\" : \"Delete\"}\n </button>\n </>\n }\n >\n <p className=\"text-sm text-text-secondary\">\n Are you sure you want to delete{\" \"}\n <span className=\"font-medium text-text-primary\">\n {confirmDeletePlan?.name}\n </span>\n ? All its allocations will be removed.\n </p>\n </Modal>\n\n {/* Delete allocation confirm */}\n <Modal\n open={confirmDeleteAlloc !== null}\n onClose={() => setConfirmDeleteAlloc(null)}\n title=\"Delete Allocation\"\n description=\"This action cannot be undone.\"\n footer={\n <>\n <button\n onClick={() => setConfirmDeleteAlloc(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleDeleteAllocation}\n disabled={deletingAlloc}\n className=\"rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/80 disabled:opacity-50\"\n >\n {deletingAlloc ? \"Deleting...\" : \"Delete\"}\n </button>\n </>\n }\n >\n <p className=\"text-sm text-text-secondary\">\n Remove the allocation for{\" \"}\n <span className=\"font-medium text-text-primary\">\n {confirmDeleteAlloc?.userId}\n </span>\n ?\n </p>\n </Modal>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ResourcePlanningPage.js","names":[],"sources":["../../../../src/timecampus/pages/resource-planning/ResourcePlanningPage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n CalendarRange,\n Users,\n TrendingUp,\n Plus,\n Pencil,\n Trash2,\n UserPlus,\n AlertTriangle,\n} from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { Modal } from \"../../components/Modal\";\nimport {\n ChartCard,\n DonutChart,\n RadialGauge,\n ProgressMeter,\n StatusBadge,\n type MeterTone,\n} from \"../../components\";\nimport { getInitials, formatHours } from \"../../utils/helpers\";\nimport {\n useListResourcePlansQuery,\n useGetCapacityOverviewQuery,\n useCreateResourcePlanMutation,\n useUpdateResourcePlanMutation,\n useDeleteResourcePlanMutation,\n useCreateAllocationMutation,\n useUpdateAllocationMutation,\n useDeleteAllocationMutation,\n useBulkCreateAllocationsMutation,\n type ResourcePlanFieldsFragment,\n type ResourceAllocationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst PAGE_SIZE = 25;\n\nconst inputClass =\n \"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\";\n\nconst toDateInput = (iso: string) => iso.slice(0, 10);\nconst toIso = (dateStr: string) => new Date(dateStr).toISOString();\n\ninterface PlanFormState {\n name: string;\n description: string;\n startDate: string;\n endDate: string;\n status: string;\n}\n\ninterface AllocationRow {\n userId: string;\n allocatedHours: string;\n startDate: string;\n endDate: string;\n notes: string;\n}\n\ninterface AllocationEditState {\n userId: string;\n allocatedHours: string;\n actualHours: string;\n startDate: string;\n endDate: string;\n notes: string;\n}\n\nconst emptyPlanForm = (): PlanFormState => {\n const now = new Date();\n const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const end = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7);\n return {\n name: \"\",\n description: \"\",\n startDate: toDateInput(start.toISOString()),\n endDate: toDateInput(end.toISOString()),\n status: \"active\",\n };\n};\n\nconst emptyAllocationRow = (\n plan?: ResourcePlanFieldsFragment,\n): AllocationRow => ({\n userId: \"\",\n allocatedHours: \"\",\n startDate: plan ? toDateInput(plan.startDate) : \"\",\n endDate: plan ? toDateInput(plan.endDate) : \"\",\n notes: \"\",\n});\n\nexport function ResourcePlanningPage() {\n const now = new Date();\n const startDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate(),\n ).toISOString();\n const endDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate() + 7,\n ).toISOString();\n\n const {\n data: plansData,\n loading: plansLoading,\n error: plansError,\n refetch: refetchPlans,\n fetchMore,\n } = useListResourcePlansQuery({ variables: { limit: PAGE_SIZE, offset: 0 } });\n const { data: capacityData, refetch: refetchCapacity } =\n useGetCapacityOverviewQuery({ variables: { startDate, endDate } });\n\n const [createPlan, { loading: creatingPlan, error: createPlanError }] =\n useCreateResourcePlanMutation();\n const [updatePlan, { loading: updatingPlan, error: updatePlanError }] =\n useUpdateResourcePlanMutation();\n const [deletePlan, { loading: deletingPlan }] =\n useDeleteResourcePlanMutation();\n const [createAllocation, { loading: creatingAlloc }] =\n useCreateAllocationMutation();\n const [bulkCreateAllocations, { loading: bulkCreating }] =\n useBulkCreateAllocationsMutation();\n const [\n updateAllocation,\n { loading: updatingAlloc, error: updateAllocError },\n ] = useUpdateAllocationMutation();\n const [deleteAllocation, { loading: deletingAlloc }] =\n useDeleteAllocationMutation();\n\n const [planModalOpen, setPlanModalOpen] = useState(false);\n const [editingPlan, setEditingPlan] =\n useState<ResourcePlanFieldsFragment | null>(null);\n const [planForm, setPlanForm] = useState<PlanFormState>(emptyPlanForm());\n const [confirmDeletePlan, setConfirmDeletePlan] =\n useState<ResourcePlanFieldsFragment | null>(null);\n\n const [allocModalPlan, setAllocModalPlan] =\n useState<ResourcePlanFieldsFragment | null>(null);\n const [allocRows, setAllocRows] = useState<AllocationRow[]>([]);\n const [allocError, setAllocError] = useState(false);\n\n const [editingAlloc, setEditingAlloc] =\n useState<ResourceAllocationFieldsFragment | null>(null);\n const [allocEditForm, setAllocEditForm] =\n useState<AllocationEditState | null>(null);\n const [confirmDeleteAlloc, setConfirmDeleteAlloc] =\n useState<ResourceAllocationFieldsFragment | null>(null);\n\n const [loadingMore, setLoadingMore] = useState(false);\n\n const plans = plansData?.resourcePlans?.items ?? [];\n const hasMore = plansData?.resourcePlans?.hasMore ?? false;\n const capacity = capacityData?.capacityOverview;\n\n const refetchAll = async () => {\n await Promise.all([refetchPlans(), refetchCapacity()]);\n };\n\n // -- Plan handlers --------------------------------------------------------\n const openCreatePlan = () => {\n setEditingPlan(null);\n setPlanForm(emptyPlanForm());\n setPlanModalOpen(true);\n };\n\n const openEditPlan = (plan: ResourcePlanFieldsFragment) => {\n setEditingPlan(plan);\n setPlanForm({\n name: plan.name,\n description: plan.description ?? \"\",\n startDate: toDateInput(plan.startDate),\n endDate: toDateInput(plan.endDate),\n status: plan.status,\n });\n setPlanModalOpen(true);\n };\n\n const handleSubmitPlan = async () => {\n if (!planForm.name.trim()) return;\n if (editingPlan) {\n await updatePlan({\n variables: {\n id: editingPlan.id,\n input: {\n name: planForm.name.trim(),\n description: planForm.description.trim() || undefined,\n startDate: toIso(planForm.startDate),\n endDate: toIso(planForm.endDate),\n status: planForm.status,\n },\n },\n });\n } else {\n await createPlan({\n variables: {\n input: {\n name: planForm.name.trim(),\n description: planForm.description.trim() || undefined,\n startDate: toIso(planForm.startDate),\n endDate: toIso(planForm.endDate),\n },\n },\n });\n }\n setPlanModalOpen(false);\n await refetchAll();\n };\n\n const handleDeletePlan = async () => {\n if (!confirmDeletePlan) return;\n await deletePlan({ variables: { id: confirmDeletePlan.id } });\n setConfirmDeletePlan(null);\n await refetchAll();\n };\n\n // -- Allocation handlers --------------------------------------------------\n const openAddAllocation = (plan: ResourcePlanFieldsFragment) => {\n setAllocModalPlan(plan);\n setAllocRows([emptyAllocationRow(plan)]);\n setAllocError(false);\n };\n\n const updateAllocRow = (index: number, patch: Partial<AllocationRow>) => {\n setAllocRows((rows) =>\n rows.map((r, i) => (i === index ? { ...r, ...patch } : r)),\n );\n };\n\n const addAllocRow = () => {\n setAllocRows((rows) => [\n ...rows,\n emptyAllocationRow(allocModalPlan ?? undefined),\n ]);\n };\n\n const removeAllocRow = (index: number) => {\n setAllocRows((rows) => rows.filter((_, i) => i !== index));\n };\n\n const allocRowsValid = allocRows.every(\n (r) =>\n r.userId.trim() !== \"\" &&\n r.allocatedHours.trim() !== \"\" &&\n r.startDate !== \"\" &&\n r.endDate !== \"\",\n );\n\n const handleSubmitAllocations = async () => {\n if (!allocModalPlan || !allocRowsValid || allocRows.length === 0) return;\n setAllocError(false);\n try {\n if (allocRows.length === 1) {\n const r = allocRows[0];\n await createAllocation({\n variables: {\n input: {\n resourcePlanId: allocModalPlan.id,\n userId: r.userId.trim(),\n allocatedHours: Number(r.allocatedHours),\n startDate: toIso(r.startDate),\n endDate: toIso(r.endDate),\n notes: r.notes.trim() || undefined,\n },\n },\n });\n } else {\n await bulkCreateAllocations({\n variables: {\n planId: allocModalPlan.id,\n allocations: allocRows.map((r) => ({\n userId: r.userId.trim(),\n allocatedHours: Number(r.allocatedHours),\n startDate: toIso(r.startDate),\n endDate: toIso(r.endDate),\n notes: r.notes.trim() || undefined,\n })),\n },\n });\n }\n setAllocModalPlan(null);\n await refetchAll();\n } catch {\n setAllocError(true);\n }\n };\n\n const openEditAllocation = (alloc: ResourceAllocationFieldsFragment) => {\n setEditingAlloc(alloc);\n setAllocEditForm({\n userId: alloc.userId,\n allocatedHours: String(alloc.allocatedHours),\n actualHours: String(alloc.actualHours),\n startDate: toDateInput(alloc.startDate),\n endDate: toDateInput(alloc.endDate),\n notes: alloc.notes ?? \"\",\n });\n };\n\n const handleSubmitAllocEdit = async () => {\n if (!editingAlloc || !allocEditForm) return;\n await updateAllocation({\n variables: {\n id: editingAlloc.id,\n input: {\n userId: allocEditForm.userId.trim(),\n allocatedHours: Number(allocEditForm.allocatedHours),\n actualHours: Number(allocEditForm.actualHours),\n startDate: toIso(allocEditForm.startDate),\n endDate: toIso(allocEditForm.endDate),\n notes: allocEditForm.notes.trim() || undefined,\n },\n },\n });\n setEditingAlloc(null);\n setAllocEditForm(null);\n await refetchAll();\n };\n\n const handleDeleteAllocation = async () => {\n if (!confirmDeleteAlloc) return;\n await deleteAllocation({ variables: { id: confirmDeleteAlloc.id } });\n setConfirmDeleteAlloc(null);\n await refetchAll();\n };\n\n const handleLoadMore = async () => {\n setLoadingMore(true);\n try {\n await fetchMore({\n variables: { limit: PAGE_SIZE, offset: plans.length },\n updateQuery: (prev, { fetchMoreResult }) => {\n if (!fetchMoreResult) return prev;\n return {\n resourcePlans: {\n ...fetchMoreResult.resourcePlans,\n items: [\n ...prev.resourcePlans.items,\n ...fetchMoreResult.resourcePlans.items,\n ],\n },\n };\n },\n });\n } finally {\n setLoadingMore(false);\n }\n };\n\n const newPlanButton = (\n <button\n onClick={openCreatePlan}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus className=\"h-4 w-4\" />\n New Resource Plan\n </button>\n );\n\n if (plansLoading) {\n return (\n <PageLayout\n title=\"Resource Planning\"\n description=\"Plan and optimize team resource allocation\"\n >\n <LoadingSkeleton variant=\"list\" count={5} />\n </PageLayout>\n );\n }\n\n if (plansError) {\n return (\n <PageLayout\n title=\"Resource Planning\"\n description=\"Plan and optimize team resource allocation\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load resource planning data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const utilizationRate = capacity?.utilizationRate ?? 0;\n const overallocatedUsers = capacity?.overallocatedUsers ?? [];\n const overallocatedCount = overallocatedUsers.length;\n const availableHours = capacity?.availableCapacity ?? 0;\n const allocatedHours = capacity?.allocatedCapacity ?? 0;\n const totalHours = capacity?.totalCapacity ?? 0;\n const hasCapacity =\n !!capacity &&\n (totalHours > 0 || allocatedHours > 0 || overallocatedCount > 0);\n\n return (\n <PageLayout\n title=\"Resource Planning\"\n description=\"Plan and optimize team resource allocation\"\n purpose=\"Match the work ahead to the people you have — see who's over- or under-booked and how much capacity is free this week — so you can commit to deadlines you can actually hit without burning anyone out.\"\n actions={newPlanButton}\n >\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Team Utilization\"\n value={`${Math.round(utilizationRate)}%`}\n icon={<TrendingUp className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Over-allocated\"\n value={String(overallocatedCount)}\n icon={<Users className=\"h-5 w-5\" />}\n iconBgColor=\"bg-status-error-bg text-status-error-text\"\n />\n <StatCard\n title=\"Active Plans\"\n value={String(plans.length)}\n icon={<Users className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Available Capacity\"\n value={`${Math.round(availableHours)}h`}\n icon={<CalendarRange className=\"h-5 w-5\" />}\n description=\"This week\"\n />\n </div>\n\n {hasCapacity && (\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <ChartCard\n title=\"Capacity split\"\n description=\"Allocated vs available hours this week\"\n >\n <DonutChart\n data={[\n { name: \"Allocated\", value: allocatedHours },\n { name: \"Available\", value: availableHours },\n ]}\n centerLabel=\"Total\"\n centerValue={`${Math.round(totalHours)}h`}\n valueFormat={(v) => `${Math.round(v)}h`}\n emptyLabel=\"No capacity data yet\"\n />\n </ChartCard>\n <ChartCard\n title=\"Utilization & over-allocation\"\n description=\"Team utilization and who is over-booked this week\"\n >\n <RadialGauge\n value={Math.round(utilizationRate)}\n max={100}\n label=\"Utilization\"\n sublabel=\"this week\"\n format={(v) => `${Math.round(v)}%`}\n />\n <div className=\"mt-4\">\n <p className=\"mb-2 text-xs font-medium text-text-secondary\">\n Over-allocated ({overallocatedCount})\n </p>\n {overallocatedCount === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n No one is over-allocated this week.\n </p>\n ) : (\n <div className=\"flex flex-wrap gap-2\">\n {overallocatedUsers.map((userId: string) => (\n <span\n key={userId}\n className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg px-2.5 py-0.5 text-xs font-medium text-status-warning-text\"\n >\n <AlertTriangle className=\"h-3.5 w-3.5\" />\n {userId}\n </span>\n ))}\n </div>\n )}\n </div>\n </ChartCard>\n </div>\n )}\n\n {plans.length === 0 ? (\n <EmptyState\n illustration=\"empty-people\"\n title=\"No resource plans yet\"\n description=\"Create a resource plan to start allocating team members and balancing workload across the week.\"\n action={newPlanButton}\n />\n ) : (\n <div className=\"space-y-6\">\n {plans.map((plan: ResourcePlanFieldsFragment) => (\n <GlassCard\n key={plan.id}\n treatment=\"glass\"\n className=\"overflow-hidden\"\n >\n <div className=\"flex flex-col gap-3 border-b border-border-seam p-5 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {plan.name}\n </p>\n <StatusBadge label={plan.status} status={plan.status} />\n </div>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {plan.startDate.slice(0, 10)} to{\" \"}\n {plan.endDate.slice(0, 10)} ·{\" \"}\n {plan.allocations.length}{\" \"}\n {plan.allocations.length === 1 ? \"person\" : \"people\"}\n </p>\n <div className=\"mt-3 max-w-sm\">\n <ProgressMeter\n size=\"sm\"\n label=\"Logged vs allocated\"\n value={plan.totalActualHours}\n max={\n plan.totalAllocatedHours > 0\n ? plan.totalAllocatedHours\n : Math.max(plan.totalActualHours, 1)\n }\n format={(v) => formatHours(v)}\n />\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={() => openAddAllocation(plan)}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-2.5 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <UserPlus className=\"h-3.5 w-3.5\" />\n Add Allocation\n </button>\n <button\n onClick={() => openEditPlan(plan)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-2.5 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n Edit\n </button>\n <button\n onClick={() => setConfirmDeletePlan(plan)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-2.5 py-1.5 text-xs font-medium text-status-error-text hover:bg-status-error-bg\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n Delete\n </button>\n </div>\n </div>\n\n {plan.allocations.length === 0 ? (\n <div className=\"p-5 text-sm text-text-secondary\">\n No allocations yet. Use “Add Allocation” to\n assign team members.\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-xs text-text-secondary\">\n <th className=\"whitespace-nowrap px-5 py-2.5 font-medium\">\n Member\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 font-medium\">\n Window\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 text-right font-medium\">\n Allocated\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 text-right font-medium\">\n Actual\n </th>\n <th className=\"whitespace-nowrap px-4 py-2.5 font-medium\">\n Utilization\n </th>\n <th className=\"whitespace-nowrap px-5 py-2.5 text-right font-medium\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-seam\">\n {plan.allocations.map(\n (alloc: ResourceAllocationFieldsFragment) => {\n const utilization =\n alloc.utilizationRate ??\n (alloc.allocatedHours > 0\n ? Math.round(\n (alloc.actualHours / alloc.allocatedHours) *\n 100,\n )\n : 0);\n const tone: MeterTone =\n utilization > 100\n ? \"danger\"\n : utilization < 70\n ? \"warning\"\n : \"success\";\n const toneText =\n tone === \"danger\"\n ? \"text-status-error-text\"\n : tone === \"warning\"\n ? \"text-status-warning-text\"\n : \"text-status-success-text\";\n return (\n <tr\n key={alloc.id}\n className=\"transition-colors hover:bg-bg-sunken/50\"\n >\n <td className=\"whitespace-nowrap px-5 py-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-action-primary-bg/10 text-sm font-medium text-primary\">\n {getInitials(alloc.userId)}\n </div>\n <span className=\"font-medium text-text-primary\">\n {alloc.userId}\n </span>\n </div>\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-text-secondary\">\n {alloc.startDate.slice(0, 10)} to{\" \"}\n {alloc.endDate.slice(0, 10)}\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-right font-medium text-text-primary\">\n {formatHours(alloc.allocatedHours)}\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-right text-text-secondary\">\n {formatHours(alloc.actualHours)}\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"flex w-40 items-center gap-2\">\n <ProgressMeter\n size=\"sm\"\n value={utilization}\n max={100}\n tone={tone}\n showValue={false}\n className=\"flex-1\"\n />\n <span\n className={`shrink-0 text-xs font-medium tabular-nums ${toneText}`}\n >\n {utilization}%\n </span>\n </div>\n </td>\n <td className=\"whitespace-nowrap px-5 py-3\">\n <div className=\"flex items-center justify-end gap-1\">\n <button\n onClick={() => openEditAllocation(alloc)}\n aria-label=\"Edit allocation\"\n className=\"rounded-md border border-border-subtle p-1.5 text-text-primary hover:bg-bg-sunken/50\"\n >\n <Pencil className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() =>\n setConfirmDeleteAlloc(alloc)\n }\n aria-label=\"Delete allocation\"\n className=\"rounded-md border border-border-subtle p-1.5 text-status-error-text hover:bg-status-error-bg\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n </td>\n </tr>\n );\n },\n )}\n </tbody>\n </table>\n </div>\n )}\n </GlassCard>\n ))}\n {hasMore && (\n <div className=\"flex justify-center\">\n <button\n onClick={handleLoadMore}\n disabled={loadingMore}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50 disabled:opacity-50\"\n >\n {loadingMore ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Plan create/edit modal */}\n <Modal\n open={planModalOpen}\n onClose={() => setPlanModalOpen(false)}\n title={editingPlan ? \"Edit Resource Plan\" : \"New Resource Plan\"}\n description=\"Set the window this plan covers, then allocate people to it.\"\n size=\"lg\"\n footer={\n <>\n <button\n onClick={() => setPlanModalOpen(false)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleSubmitPlan}\n disabled={creatingPlan || updatingPlan || !planForm.name.trim()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {creatingPlan || updatingPlan\n ? \"Saving...\"\n : editingPlan\n ? \"Save Changes\"\n : \"Create Plan\"}\n </button>\n </>\n }\n >\n {(createPlanError || updatePlanError) && (\n <div className=\"mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text\">\n Failed to save resource plan. Please try again.\n </div>\n )}\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Plan Name\n </label>\n <input\n type=\"text\"\n placeholder=\"e.g. Q3 Delivery\"\n value={planForm.name}\n onChange={(e) =>\n setPlanForm({ ...planForm, name: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Description (optional)\n </label>\n <textarea\n rows={2}\n placeholder=\"What this plan covers\"\n value={planForm.description}\n onChange={(e) =>\n setPlanForm({ ...planForm, description: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Start Date\n </label>\n <input\n type=\"date\"\n value={planForm.startDate}\n onChange={(e) =>\n setPlanForm({ ...planForm, startDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n End Date\n </label>\n <input\n type=\"date\"\n value={planForm.endDate}\n onChange={(e) =>\n setPlanForm({ ...planForm, endDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n </div>\n {editingPlan && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Status\n </label>\n <select\n value={planForm.status}\n onChange={(e) =>\n setPlanForm({ ...planForm, status: e.target.value })\n }\n className={inputClass}\n >\n <option value=\"active\">Active</option>\n <option value=\"draft\">Draft</option>\n <option value=\"completed\">Completed</option>\n <option value=\"archived\">Archived</option>\n </select>\n </div>\n )}\n </div>\n </Modal>\n\n {/* Add allocation(s) modal */}\n <Modal\n open={allocModalPlan !== null}\n onClose={() => setAllocModalPlan(null)}\n title=\"Add Allocation\"\n description={\n allocModalPlan\n ? `Assign team members to \"${allocModalPlan.name}\".`\n : undefined\n }\n size=\"xl\"\n footer={\n <>\n <button\n onClick={() => setAllocModalPlan(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleSubmitAllocations}\n disabled={creatingAlloc || bulkCreating || !allocRowsValid}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {creatingAlloc || bulkCreating\n ? \"Saving...\"\n : allocRows.length > 1\n ? `Add ${allocRows.length} Allocations`\n : \"Add Allocation\"}\n </button>\n </>\n }\n >\n {allocError && (\n <div className=\"mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text\">\n Failed to add allocations. Please check the values and try again.\n </div>\n )}\n <div className=\"space-y-4\">\n {allocRows.map((row, index) => (\n <div\n key={index}\n className=\"rounded-lg border border-border-subtle p-3\"\n >\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"text-xs font-medium text-text-secondary\">\n Allocation {index + 1}\n </span>\n {allocRows.length > 1 && (\n <button\n onClick={() => removeAllocRow(index)}\n className=\"text-xs font-medium text-status-error-text hover:underline\"\n >\n Remove\n </button>\n )}\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n User ID\n </label>\n <input\n type=\"text\"\n placeholder=\"User identifier\"\n value={row.userId}\n onChange={(e) =>\n updateAllocRow(index, { userId: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n Allocated Hours\n </label>\n <input\n type=\"number\"\n placeholder=\"0\"\n value={row.allocatedHours}\n onChange={(e) =>\n updateAllocRow(index, {\n allocatedHours: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n Start Date\n </label>\n <input\n type=\"date\"\n value={row.startDate}\n onChange={(e) =>\n updateAllocRow(index, { startDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-primary\">\n End Date\n </label>\n <input\n type=\"date\"\n value={row.endDate}\n onChange={(e) =>\n updateAllocRow(index, { endDate: e.target.value })\n }\n className={inputClass}\n />\n </div>\n <div className=\"sm:col-span-2\">\n <label className=\"block text-xs font-medium text-text-primary\">\n Notes (optional)\n </label>\n <input\n type=\"text\"\n placeholder=\"Context for this allocation\"\n value={row.notes}\n onChange={(e) =>\n updateAllocRow(index, { notes: e.target.value })\n }\n className={inputClass}\n />\n </div>\n </div>\n </div>\n ))}\n <button\n onClick={addAllocRow}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <Plus className=\"h-4 w-4\" />\n Add another person\n </button>\n </div>\n </Modal>\n\n {/* Edit allocation modal */}\n <Modal\n open={editingAlloc !== null && allocEditForm !== null}\n onClose={() => {\n setEditingAlloc(null);\n setAllocEditForm(null);\n }}\n title=\"Edit Allocation\"\n size=\"lg\"\n footer={\n <>\n <button\n onClick={() => {\n setEditingAlloc(null);\n setAllocEditForm(null);\n }}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleSubmitAllocEdit}\n disabled={updatingAlloc}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {updatingAlloc ? \"Saving...\" : \"Save Changes\"}\n </button>\n </>\n }\n >\n {updateAllocError && (\n <div className=\"mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text\">\n Failed to update allocation. Please try again.\n </div>\n )}\n {allocEditForm && (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n User ID\n </label>\n <input\n type=\"text\"\n value={allocEditForm.userId}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n userId: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Allocated Hours\n </label>\n <input\n type=\"number\"\n value={allocEditForm.allocatedHours}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n allocatedHours: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Actual Hours\n </label>\n <input\n type=\"number\"\n value={allocEditForm.actualHours}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n actualHours: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div />\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Start Date\n </label>\n <input\n type=\"date\"\n value={allocEditForm.startDate}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n startDate: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n End Date\n </label>\n <input\n type=\"date\"\n value={allocEditForm.endDate}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n endDate: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n <div className=\"sm:col-span-2\">\n <label className=\"block text-sm font-medium text-text-primary\">\n Notes (optional)\n </label>\n <input\n type=\"text\"\n value={allocEditForm.notes}\n onChange={(e) =>\n setAllocEditForm({\n ...allocEditForm,\n notes: e.target.value,\n })\n }\n className={inputClass}\n />\n </div>\n </div>\n )}\n </Modal>\n\n {/* Delete plan confirm */}\n <Modal\n open={confirmDeletePlan !== null}\n onClose={() => setConfirmDeletePlan(null)}\n title=\"Delete Resource Plan\"\n description=\"This action cannot be undone.\"\n footer={\n <>\n <button\n onClick={() => setConfirmDeletePlan(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleDeletePlan}\n disabled={deletingPlan}\n className=\"rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/80 disabled:opacity-50\"\n >\n {deletingPlan ? \"Deleting...\" : \"Delete\"}\n </button>\n </>\n }\n >\n <p className=\"text-sm text-text-secondary\">\n Are you sure you want to delete{\" \"}\n <span className=\"font-medium text-text-primary\">\n {confirmDeletePlan?.name}\n </span>\n ? All its allocations will be removed.\n </p>\n </Modal>\n\n {/* Delete allocation confirm */}\n <Modal\n open={confirmDeleteAlloc !== null}\n onClose={() => setConfirmDeleteAlloc(null)}\n title=\"Delete Allocation\"\n description=\"This action cannot be undone.\"\n footer={\n <>\n <button\n onClick={() => setConfirmDeleteAlloc(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleDeleteAllocation}\n disabled={deletingAlloc}\n className=\"rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/80 disabled:opacity-50\"\n >\n {deletingAlloc ? \"Deleting...\" : \"Delete\"}\n </button>\n </>\n }\n >\n <p className=\"text-sm text-text-secondary\">\n Remove the allocation for{\" \"}\n <span className=\"font-medium text-text-primary\">\n {confirmDeleteAlloc?.userId}\n </span>\n ?\n </p>\n </Modal>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -5,8 +5,8 @@ import { LoadingSkeleton as a } from "../../components/LoadingSkeleton.js";
|
|
|
5
5
|
import { useListTimeEntriesQuery as o } from "../../../generated/wspace-operations.js";
|
|
6
6
|
import { PageLayout as s } from "../../components/PageLayout.js";
|
|
7
7
|
import { EmptyState as c } from "../../components/EmptyState.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { Modal as l } from "../../components/Modal.js";
|
|
9
|
+
import { ChartCard as u } from "../../components/ChartCard.js";
|
|
10
10
|
import { BarsChart as d } from "../../components/charts/BarsChart.js";
|
|
11
11
|
import "../../components/index.js";
|
|
12
12
|
import { useState as f } from "react";
|
|
@@ -89,7 +89,7 @@ function S() {
|
|
|
89
89
|
})
|
|
90
90
|
]
|
|
91
91
|
}),
|
|
92
|
-
/* @__PURE__ */ v(
|
|
92
|
+
/* @__PURE__ */ v(u, {
|
|
93
93
|
title: "Hours by Project",
|
|
94
94
|
description: "Where the team's tracked time is concentrated.",
|
|
95
95
|
children: /* @__PURE__ */ v(d, {
|
|
@@ -159,7 +159,7 @@ function S() {
|
|
|
159
159
|
})
|
|
160
160
|
})
|
|
161
161
|
] })]
|
|
162
|
-
}), /* @__PURE__ */ v(
|
|
162
|
+
}), /* @__PURE__ */ v(l, {
|
|
163
163
|
open: w,
|
|
164
164
|
onClose: () => T(!1),
|
|
165
165
|
title: "Managing Team Members",
|