@open-mercato/core 0.6.8-develop.7101.1.bd9356828a → 0.7.1-develop.7102.1.b41f7e3e51

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.
Files changed (159) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/api/login.js +19 -0
  3. package/dist/modules/auth/api/login.js.map +2 -2
  4. package/dist/modules/auth/api/routeError.js +11 -0
  5. package/dist/modules/auth/api/routeError.js.map +7 -0
  6. package/dist/modules/auth/api/users/acl/route.js +23 -7
  7. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  8. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js +6 -1
  9. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js.map +2 -2
  10. package/dist/modules/business_rules/backend/rules/create/page.meta.js +5 -1
  11. package/dist/modules/business_rules/backend/rules/create/page.meta.js.map +2 -2
  12. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js +6 -1
  13. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js.map +2 -2
  14. package/dist/modules/business_rules/backend/sets/create/page.meta.js +5 -1
  15. package/dist/modules/business_rules/backend/sets/create/page.meta.js.map +2 -2
  16. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js +84 -0
  17. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js.map +7 -0
  18. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js +7 -81
  19. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js.map +2 -2
  20. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +525 -0
  21. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +7 -0
  22. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js +731 -0
  23. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js.map +7 -0
  24. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +7 -727
  25. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  26. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +7 -521
  27. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  28. package/dist/modules/customer_accounts/extension-points.js +1 -1
  29. package/dist/modules/customer_accounts/extension-points.js.map +2 -2
  30. package/dist/modules/customer_accounts/lib/portalUrl.js +69 -0
  31. package/dist/modules/customer_accounts/lib/portalUrl.js.map +7 -0
  32. package/dist/modules/customers/backend/customers/companies/page.js +2 -2
  33. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  34. package/dist/modules/customers/backend/customers/deals/page.js +2 -2
  35. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  36. package/dist/modules/customers/backend/customers/people/page.js +2 -2
  37. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  38. package/dist/modules/customers/components/detail/AssignRoleDialog.js +33 -28
  39. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +2 -2
  40. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js +3 -1
  41. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js.map +2 -2
  42. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js +1 -0
  43. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js.map +2 -2
  44. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js +4 -1
  45. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js.map +2 -2
  46. package/dist/modules/eudr/backend/eudr/page.meta.js +2 -2
  47. package/dist/modules/eudr/backend/eudr/page.meta.js.map +2 -2
  48. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +8 -2
  49. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +2 -2
  50. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js +3 -1
  51. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js.map +2 -2
  52. package/dist/modules/eudr/backend/eudr/plots/create/page.js +8 -2
  53. package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +2 -2
  54. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js +1 -0
  55. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js.map +2 -2
  56. package/dist/modules/eudr/backend/eudr/plots/page.meta.js +4 -1
  57. package/dist/modules/eudr/backend/eudr/plots/page.meta.js.map +2 -2
  58. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js +3 -1
  59. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js.map +2 -2
  60. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js +1 -0
  61. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js.map +2 -2
  62. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js +4 -1
  63. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js.map +2 -2
  64. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js +3 -1
  65. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js.map +2 -2
  66. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js +1 -0
  67. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js.map +2 -2
  68. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js +4 -1
  69. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js.map +2 -2
  70. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +2 -0
  71. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +2 -2
  72. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js +3 -1
  73. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js.map +2 -2
  74. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js +1 -0
  75. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js.map +2 -2
  76. package/dist/modules/eudr/backend/eudr/statements/page.js +30 -25
  77. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  78. package/dist/modules/eudr/backend/eudr/statements/page.meta.js +4 -1
  79. package/dist/modules/eudr/backend/eudr/statements/page.meta.js.map +2 -2
  80. package/dist/modules/eudr/commands/statements.js +5 -3
  81. package/dist/modules/eudr/commands/statements.js.map +2 -2
  82. package/dist/modules/eudr/components/crudErrorI18n.js +21 -1
  83. package/dist/modules/eudr/components/crudErrorI18n.js.map +2 -2
  84. package/dist/modules/eudr/components/formConfig.js +6 -2
  85. package/dist/modules/eudr/components/formConfig.js.map +2 -2
  86. package/dist/modules/eudr/lib/statement-lifecycle.js +9 -1
  87. package/dist/modules/eudr/lib/statement-lifecycle.js.map +2 -2
  88. package/dist/modules/sales/components/documents/LineItemDialog.js +1 -1
  89. package/dist/modules/sales/components/documents/LineItemDialog.js.map +1 -1
  90. package/dist/modules/sales/widgets/injection/document-history/widget.client.js +44 -2
  91. package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
  92. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +20 -16
  93. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  94. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +10 -6
  95. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  96. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +11 -7
  97. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
  98. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +10 -6
  99. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  100. package/package.json +8 -8
  101. package/src/modules/auth/api/login.ts +23 -0
  102. package/src/modules/auth/api/routeError.ts +30 -0
  103. package/src/modules/auth/api/users/acl/route.ts +49 -9
  104. package/src/modules/business_rules/backend/rules/[id]/page.meta.ts +5 -0
  105. package/src/modules/business_rules/backend/rules/create/page.meta.ts +5 -1
  106. package/src/modules/business_rules/backend/sets/[id]/page.meta.ts +5 -0
  107. package/src/modules/business_rules/backend/sets/create/page.meta.ts +5 -1
  108. package/src/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.tsx +138 -0
  109. package/src/modules/customer_accounts/backend/customer_accounts/settings/page.tsx +8 -132
  110. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +601 -0
  111. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.tsx +838 -0
  112. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +6 -838
  113. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +6 -590
  114. package/src/modules/customer_accounts/extension-points.ts +1 -1
  115. package/src/modules/customer_accounts/lib/portalUrl.ts +112 -0
  116. package/src/modules/customers/backend/customers/companies/page.tsx +2 -2
  117. package/src/modules/customers/backend/customers/deals/page.tsx +2 -2
  118. package/src/modules/customers/backend/customers/people/page.tsx +2 -2
  119. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +12 -7
  120. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.ts +2 -0
  121. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.ts +1 -0
  122. package/src/modules/eudr/backend/eudr/evidence-submissions/page.meta.ts +4 -1
  123. package/src/modules/eudr/backend/eudr/page.meta.ts +2 -2
  124. package/src/modules/eudr/backend/eudr/plots/[id]/page.meta.ts +2 -0
  125. package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +8 -2
  126. package/src/modules/eudr/backend/eudr/plots/create/page.meta.ts +1 -0
  127. package/src/modules/eudr/backend/eudr/plots/create/page.tsx +8 -2
  128. package/src/modules/eudr/backend/eudr/plots/page.meta.ts +4 -1
  129. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.ts +2 -0
  130. package/src/modules/eudr/backend/eudr/product-mappings/create/page.meta.ts +1 -0
  131. package/src/modules/eudr/backend/eudr/product-mappings/page.meta.ts +4 -1
  132. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.ts +2 -0
  133. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.meta.ts +1 -0
  134. package/src/modules/eudr/backend/eudr/risk-assessments/page.meta.ts +4 -1
  135. package/src/modules/eudr/backend/eudr/statements/[id]/page.meta.ts +2 -0
  136. package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +2 -0
  137. package/src/modules/eudr/backend/eudr/statements/create/page.meta.ts +1 -0
  138. package/src/modules/eudr/backend/eudr/statements/page.meta.ts +4 -1
  139. package/src/modules/eudr/backend/eudr/statements/page.tsx +32 -26
  140. package/src/modules/eudr/commands/statements.ts +4 -2
  141. package/src/modules/eudr/components/crudErrorI18n.ts +31 -0
  142. package/src/modules/eudr/components/formConfig.tsx +9 -1
  143. package/src/modules/eudr/i18n/de.json +3 -2
  144. package/src/modules/eudr/i18n/en.json +3 -2
  145. package/src/modules/eudr/i18n/es.json +3 -2
  146. package/src/modules/eudr/i18n/ko.json +3 -2
  147. package/src/modules/eudr/i18n/pl.json +3 -2
  148. package/src/modules/eudr/lib/statement-lifecycle.ts +8 -0
  149. package/src/modules/sales/components/documents/LineItemDialog.tsx +1 -1
  150. package/src/modules/sales/i18n/de.json +37 -0
  151. package/src/modules/sales/i18n/en.json +37 -0
  152. package/src/modules/sales/i18n/es.json +37 -0
  153. package/src/modules/sales/i18n/ko.json +37 -0
  154. package/src/modules/sales/i18n/pl.json +37 -0
  155. package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +42 -2
  156. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +30 -26
  157. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +21 -17
  158. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +17 -13
  159. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +16 -12
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useQuery } from '@tanstack/react-query'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport {\n ArrowDown,\n ClipboardList,\n ExternalLink,\n MapPin,\n Package,\n RefreshCw,\n SlidersHorizontal,\n Warehouse as WarehouseIcon2,\n} from 'lucide-react'\nimport { Page, PageBody, PageHeader } from '@open-mercato/ui/backend/Page'\nimport { BarChart } from '@open-mercato/ui/backend/charts'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { LinkButton } from '@open-mercato/ui/primitives/link-button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { StatusBadge, type StatusBadgeVariant } from '@open-mercato/ui/primitives/status-badge'\nimport type {\n OperationalDashboardActivityRow,\n OperationalDashboardExpiryLotRow,\n OperationalDashboardKpi,\n OperationalDashboardPayload,\n} from '../../lib/loadOperationalDashboard'\nimport {\n inventoryMovementReasonLabel,\n type InventoryDisplayTranslator,\n} from '../../lib/inventoryDisplayUi'\nimport { AdjustInventoryDialog } from './AdjustInventoryDialog'\nimport { ChangeLotStatusDialog } from './ChangeLotStatusDialog'\nimport { CycleCountWizardDialog } from './CycleCountWizardDialog'\nimport { MoveInventoryDialog } from './MoveInventoryDialog'\nimport { ReceiveInventoryDialog } from './ReceiveInventoryDialog'\nimport { useWmsInventoryMutationAccess } from './useWmsInventoryMutationAccess'\n\ntype WarehouseOption = {\n id: string\n name?: string | null\n code?: string | null\n}\n\ntype PagedWarehouses = {\n items: WarehouseOption[]\n}\n\nconst AUTO_REFRESH_MS = 60_000\n\nfunction Sparkline({ values, className }: { values: number[]; className?: string }) {\n const width = 160\n const height = 36\n const max = Math.max(...values, 1)\n const points = values.map((value, index) => {\n const x = values.length <= 1 ? width / 2 : (index / (values.length - 1)) * width\n const y = height - (value / max) * (height - 4) - 2\n return `${x},${y}`\n })\n\n return (\n <svg\n viewBox={`0 0 ${width} ${height}`}\n className={className}\n aria-hidden=\"true\"\n preserveAspectRatio=\"none\"\n >\n <polyline\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n points={points.join(' ')}\n className=\"text-status-info-icon\"\n />\n </svg>\n )\n}\n\nfunction formatActivityTitle(\n row: OperationalDashboardActivityRow,\n t: ReturnType<typeof useT>,\n): string {\n const sku = row.variantSku?.trim() || row.variantId\n const quantity = Math.abs(row.quantity)\n const signedQuantity = row.quantity\n switch (row.movementType) {\n case 'receipt':\n case 'return_receive':\n return t('wms.backend.dashboard.activity.titles.received', 'Received {quantity}\u00D7 {sku}', {\n quantity,\n sku,\n })\n case 'adjust':\n return t('wms.backend.dashboard.activity.titles.adjusted', 'Adjusted {quantity}\u00D7 {sku}', {\n quantity: `${signedQuantity >= 0 ? '+' : ''}${signedQuantity}`,\n sku,\n })\n case 'transfer':\n return t('wms.backend.dashboard.activity.titles.moved', 'Moved {quantity}\u00D7 {sku}', {\n quantity,\n sku,\n })\n case 'pick':\n case 'pack':\n return t('wms.backend.dashboard.activity.titles.allocated', 'Allocated {quantity}\u00D7 {sku}', {\n quantity,\n sku,\n })\n case 'cycle_count':\n return t('wms.backend.dashboard.activity.titles.reconciled', 'Inventory reconciled \u2014 {sku}', {\n sku,\n })\n default:\n return t('wms.backend.dashboard.activity.titles.generic', '{type} {quantity}\u00D7 {sku}', {\n type: row.movementType,\n quantity,\n sku,\n })\n }\n}\n\nfunction formatActivitySubtitle(\n row: OperationalDashboardActivityRow,\n t: InventoryDisplayTranslator,\n): string | null {\n const reasonLabel = inventoryMovementReasonLabel(\n {\n reasonCode: row.reasonCode,\n reason: row.reason,\n movementType: row.movementType,\n },\n t,\n )\n if (reasonLabel) return reasonLabel\n if (row.referenceType && row.referenceId) return `${row.referenceType} \u00B7 ${row.referenceId}`\n return null\n}\n\nfunction createDateTimeFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return new Intl.DateTimeFormat(locale, options)\n}\n\nexport function resolveDashboardFirstRunMode(input: {\n warehousesLoading: boolean\n warehousesError: boolean\n hasWarehouses: boolean\n locationsLoading: boolean\n locationsError: boolean\n locationsCount: number\n}): 'no-warehouses' | 'no-locations' | null {\n if (input.warehousesLoading || input.warehousesError) return null\n if (!input.hasWarehouses) return 'no-warehouses'\n if (input.locationsLoading || input.locationsError) return null\n if (input.locationsCount === 0) return 'no-locations'\n return null\n}\n\ntype DashboardKpiCardProps = {\n kpi: OperationalDashboardKpi\n title: string\n caption: string\n badgeLabel: string | null\n badgeVariant: StatusBadgeVariant\n ctaLabel: string\n href: string\n}\n\nfunction DashboardKpiCard({\n kpi,\n title,\n caption,\n badgeLabel,\n badgeVariant,\n ctaLabel,\n href,\n}: DashboardKpiCardProps) {\n return (\n <section className=\"flex min-h-52 flex-col rounded-lg border bg-card p-5 text-card-foreground shadow-sm\">\n <p className=\"text-sm font-medium\">{title}</p>\n <p className=\"mt-3 text-xs text-muted-foreground\">{caption}</p>\n <div className=\"mt-2 flex items-end gap-3\">\n <p className=\"text-3xl font-semibold tracking-tight\">{kpi.count}</p>\n {badgeLabel ? (\n <StatusBadge variant={badgeVariant} dot>\n {badgeLabel}\n </StatusBadge>\n ) : null}\n </div>\n <Sparkline values={kpi.sparkline} className=\"mt-3 h-9 w-full max-w-40\" />\n <LinkButton asChild variant=\"primary\" size=\"sm\" className=\"mt-4 w-fit\">\n <Link href={href}>{ctaLabel}</Link>\n </LinkButton>\n </section>\n )\n}\n\ntype ExpiryLotListProps = {\n title: string\n emptyLabel: string\n viewAllLabel: string\n viewAllHref: string\n rows: OperationalDashboardExpiryLotRow[]\n expiryFormatter: Intl.DateTimeFormat\n quantityFormatter: Intl.NumberFormat\n canAdjust: boolean\n onChangeStatus: (row: OperationalDashboardExpiryLotRow) => void\n onMove: (row: OperationalDashboardExpiryLotRow) => void\n t: ReturnType<typeof useT>\n}\n\nfunction ExpiryLotList({\n title,\n emptyLabel,\n viewAllLabel,\n viewAllHref,\n rows,\n expiryFormatter,\n quantityFormatter,\n canAdjust,\n onChangeStatus,\n onMove,\n t,\n}: ExpiryLotListProps) {\n return (\n <div className=\"min-w-0\">\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"text-sm font-semibold\">{title}</h3>\n <LinkButton asChild variant=\"gray\" size=\"sm\" className=\"h-8 px-2\">\n <Link href={viewAllHref}>{viewAllLabel}</Link>\n </LinkButton>\n </div>\n {rows.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">{emptyLabel}</p>\n ) : (\n <ul className=\"divide-y divide-border\">\n {rows.map((row) => {\n const badgeVariant: StatusBadgeVariant = row.category === 'pastDue' ? 'error' : 'warning'\n return (\n <li key={row.id} className=\"flex items-start justify-between gap-3 py-3 first:pt-0 last:pb-0\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium\">{row.lotNumber}</p>\n <p className=\"truncate text-xs text-muted-foreground\">{row.sku}</p>\n <div className=\"mt-1 flex flex-wrap items-center gap-2\">\n <StatusBadge variant={badgeVariant} dot>\n {expiryFormatter.format(new Date(row.expiresAt))}\n </StatusBadge>\n <span className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.expiry.available',\n '{quantity} available',\n { quantity: quantityFormatter.format(row.availableQuantity) },\n )}\n </span>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {canAdjust ? (\n <RowActions\n items={[\n {\n id: 'change-status',\n label: t('wms.backend.lots.actions.changeStatus', 'Change status'),\n onSelect: () => onChangeStatus(row),\n },\n {\n id: 'move',\n label: t('wms.backend.lots.actions.move', 'Move'),\n onSelect: () => onMove(row),\n },\n ]}\n />\n ) : null}\n <Button asChild type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7 shrink-0\">\n <Link\n href={`/backend/wms/lot/${row.id}`}\n aria-label={t('wms.backend.dashboard.expiry.openLot', 'Open lot')}\n >\n <ExternalLink className=\"size-3.5\" />\n </Link>\n </Button>\n </div>\n </li>\n )\n })}\n </ul>\n )}\n </div>\n )\n}\n\nconst movementStatusMap: Record<string, StatusBadgeVariant> = {\n receipt: 'success',\n return_receive: 'success',\n adjust: 'warning',\n transfer: 'info',\n pick: 'info',\n pack: 'info',\n cycle_count: 'neutral',\n putaway: 'info',\n ship: 'success',\n}\n\nexport default function WmsOperationalDashboardPage() {\n const t = useT()\n const locale = useLocale()\n const access = useWmsInventoryMutationAccess()\n const [warehouseId, setWarehouseId] = React.useState<string>('all')\n const [adjustOpen, setAdjustOpen] = React.useState(false)\n const [cycleOpen, setCycleOpen] = React.useState(false)\n const [changeStatusOpen, setChangeStatusOpen] = React.useState(false)\n const [moveOpen, setMoveOpen] = React.useState(false)\n const [receiveOpen, setReceiveOpen] = React.useState(false)\n const [activeExpiryLot, setActiveExpiryLot] = React.useState<OperationalDashboardExpiryLotRow | null>(null)\n\n const openExpiryChangeStatus = React.useCallback((row: OperationalDashboardExpiryLotRow) => {\n setActiveExpiryLot(row)\n setChangeStatusOpen(true)\n }, [])\n\n const openExpiryMove = React.useCallback((row: OperationalDashboardExpiryLotRow) => {\n setActiveExpiryLot(row)\n setMoveOpen(true)\n }, [])\n\n const activityTimeFormatter = React.useMemo(\n () =>\n createDateTimeFormatter(locale, {\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n }),\n [locale],\n )\n\n const lastUpdatedFormatter = React.useMemo(\n () =>\n createDateTimeFormatter(locale, {\n hour: '2-digit',\n minute: '2-digit',\n }),\n [locale],\n )\n\n const expiryDateFormatter = React.useMemo(\n () =>\n createDateTimeFormatter(locale, {\n month: '2-digit',\n day: '2-digit',\n year: '2-digit',\n }),\n [locale],\n )\n\n const quantityFormatter = React.useMemo(\n () => new Intl.NumberFormat(locale, { maximumFractionDigits: 2 }),\n [locale],\n )\n\n const warehousesQuery = useQuery({\n queryKey: ['wms-dashboard', 'warehouses'],\n queryFn: async () => {\n const params = new URLSearchParams({ page: '1', pageSize: '100', sortField: 'name', sortDir: 'asc' })\n const call = await apiCall<PagedWarehouses>(`/api/wms/warehouses?${params.toString()}`)\n if (!call.ok) {\n await raiseCrudError(call.response, t('wms.backend.dashboard.errors.warehouses', 'Failed to load warehouses.'))\n }\n return call.result?.items ?? []\n },\n })\n\n const hasWarehouses = (warehousesQuery.data ?? []).length > 0\n\n const locationsCountQuery = useQuery({\n queryKey: ['wms-dashboard', 'locations-count'],\n queryFn: async () => {\n const params = new URLSearchParams({ page: '1', pageSize: '1' })\n const call = await apiCall<{ total?: number }>(`/api/wms/locations?${params.toString()}`)\n if (!call.ok) {\n await raiseCrudError(call.response, t('wms.backend.dashboard.errors.locations', 'Failed to load locations.'))\n }\n return call.result?.total ?? 0\n },\n enabled: hasWarehouses,\n })\n\n const dashboardQuery = useQuery({\n queryKey: ['wms-dashboard', 'operational', warehouseId],\n queryFn: async () => {\n const params = new URLSearchParams()\n if (warehouseId !== 'all') params.set('warehouseId', warehouseId)\n const call = await apiCall<OperationalDashboardPayload>(\n `/api/wms/dashboard/operational?${params.toString()}`,\n )\n if (!call.ok) {\n await raiseCrudError(call.response, t('wms.backend.dashboard.errors.load', 'Failed to load dashboard.'))\n }\n return call.result as OperationalDashboardPayload\n },\n refetchInterval: AUTO_REFRESH_MS,\n })\n\n const selectedWarehouse = warehousesQuery.data?.find((warehouse) => warehouse.id === warehouseId)\n const warehouseLabel =\n warehouseId === 'all'\n ? t('wms.backend.dashboard.filters.allWarehouses', 'All warehouses')\n : selectedWarehouse?.name || selectedWarehouse?.code || warehouseId\n\n const firstRunMode = React.useMemo<'no-warehouses' | 'no-locations' | null>(\n () =>\n resolveDashboardFirstRunMode({\n warehousesLoading: warehousesQuery.isLoading,\n warehousesError: warehousesQuery.isError,\n hasWarehouses,\n locationsLoading: locationsCountQuery.isLoading,\n locationsError: locationsCountQuery.isError,\n locationsCount: locationsCountQuery.data ?? 0,\n }),\n [\n warehousesQuery.isLoading,\n warehousesQuery.isError,\n hasWarehouses,\n locationsCountQuery.isLoading,\n locationsCountQuery.isError,\n locationsCountQuery.data,\n ],\n )\n\n const kpiConfig = React.useMemo(() => {\n const buildLotsHref = (expiryWindow: 'expiringSoon' | 'pastDue') => {\n const params = new URLSearchParams({ expiryWindow })\n if (warehouseId !== 'all') params.set('warehouseId', warehouseId)\n return `/backend/wms/lots?${params.toString()}`\n }\n const buildInventoryHref = (lowStock?: 'belowReorder' | 'belowSafety') => {\n const params = new URLSearchParams()\n if (warehouseId !== 'all') params.set('warehouseId', warehouseId)\n if (lowStock) params.set('lowStock', lowStock)\n const query = params.toString()\n return query ? `/backend/wms/inventory?${query}` : '/backend/wms/inventory'\n }\n const inventoryHref = buildInventoryHref()\n const reservationsHref = warehouseId === 'all'\n ? '/backend/wms/reservations'\n : `/backend/wms/reservations?warehouseId=${encodeURIComponent(warehouseId)}`\n const movementsHref = warehouseId === 'all'\n ? '/backend/wms/movements'\n : `/backend/wms/movements?warehouseId=${encodeURIComponent(warehouseId)}`\n\n return {\n lowStock: {\n title: t('wms.backend.dashboard.kpis.lowStock.title', 'Low stock'),\n caption: t('wms.backend.dashboard.kpis.lowStock.caption', 'Below reorder point'),\n ctaLabel: t('wms.backend.dashboard.kpis.lowStock.cta', 'View low stock'),\n href: buildInventoryHref('belowReorder'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'warning' as const,\n label: t('wms.backend.dashboard.kpis.lowStock.badgeActive', '{count} active', { count: kpi.count }),\n }),\n },\n reorderCritical: {\n title: t('wms.backend.dashboard.kpis.reorderCritical.title', 'Reorder critical'),\n caption: t('wms.backend.dashboard.kpis.reorderCritical.caption', 'Below safety stock'),\n ctaLabel: t('wms.backend.dashboard.kpis.reorderCritical.cta', 'View critical'),\n href: buildInventoryHref('belowSafety'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'error' as const,\n label: t('wms.backend.dashboard.kpis.reorderCritical.badge', '{count} critical', { count: kpi.count }),\n }),\n },\n expiringSoon: {\n title: t('wms.backend.dashboard.kpis.expiringSoon.title', 'Expiring soon'),\n caption: t('wms.backend.dashboard.kpis.expiringSoon.caption', 'Lots expiring in 30 days'),\n ctaLabel: t('wms.backend.dashboard.kpis.expiringSoon.cta', 'View expiry'),\n href: buildLotsHref('expiringSoon'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'warning' as const,\n label: t('wms.backend.dashboard.kpis.expiringSoon.badge', '{count} lots', { count: kpi.count }),\n }),\n },\n pastDue: {\n title: t('wms.backend.dashboard.kpis.pastDue.title', 'Past due'),\n caption: t('wms.backend.dashboard.kpis.pastDue.caption', 'Expired lots with on-hand stock'),\n ctaLabel: t('wms.backend.dashboard.kpis.pastDue.cta', 'View past due'),\n href: buildLotsHref('pastDue'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'error' as const,\n label: t('wms.backend.dashboard.kpis.pastDue.badge', '{count} lots', { count: kpi.count }),\n }),\n },\n agingReservations: {\n title: t('wms.backend.dashboard.kpis.agingReservations.title', 'Aging reservations'),\n caption: t('wms.backend.dashboard.kpis.agingReservations.caption', 'Active holds older than 7 days'),\n ctaLabel: t('wms.backend.dashboard.kpis.agingReservations.cta', 'View reservations'),\n href: reservationsHref,\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'warning' as const,\n label: t('wms.backend.dashboard.kpis.agingReservations.badge', '{count} aging', { count: kpi.count }),\n }),\n },\n todaysMoves: {\n title: t('wms.backend.dashboard.kpis.todaysMoves.title', \"Today's moves\"),\n caption: t('wms.backend.dashboard.kpis.todaysMoves.caption', 'Movements posted today'),\n ctaLabel: t('wms.backend.dashboard.kpis.todaysMoves.cta', 'View ledger'),\n href: movementsHref,\n resolveBadge: (kpi: OperationalDashboardKpi) => {\n if (kpi.deltaSinceYesterday === null) {\n return { variant: 'neutral' as const, label: null }\n }\n return {\n variant: kpi.deltaSinceYesterday >= 0 ? ('success' as const) : ('neutral' as const),\n label:\n kpi.deltaSinceYesterday >= 0\n ? t('wms.backend.dashboard.kpis.todaysMoves.badgeUp', '+{count} vs yesterday', {\n count: kpi.deltaSinceYesterday,\n })\n : t('wms.backend.dashboard.kpis.todaysMoves.badgeDown', '{count} vs yesterday', {\n count: kpi.deltaSinceYesterday,\n }),\n }\n },\n },\n }\n }, [t, warehouseId])\n\n const monthlyTrendData = React.useMemo(\n () =>\n (dashboardQuery.data?.monthlyTrends ?? []).map((point) => ({\n month: point.month,\n receive: point.receive,\n allocate: point.allocate,\n })),\n [dashboardQuery.data?.monthlyTrends],\n )\n\n const expiryLotsByCategory = React.useMemo(() => {\n const lots = dashboardQuery.data?.expiryLots ?? []\n return {\n expiringSoon: lots.filter((lot) => lot.category === 'expiringSoon'),\n pastDue: lots.filter((lot) => lot.category === 'pastDue'),\n }\n }, [dashboardQuery.data?.expiryLots])\n\n const movementsHref = kpiConfig.todaysMoves.href\n\n const activityColumns = React.useMemo<ColumnDef<OperationalDashboardActivityRow>[]>(\n () => [\n {\n id: 'event',\n header: t('wms.backend.dashboard.activity.columns.event', 'Event'),\n accessorKey: 'movementType',\n cell: ({ row }) => {\n const movementLabel = t(\n `wms.backend.dashboard.activity.types.${row.original.movementType}`,\n row.original.movementType,\n )\n const badgeVariant = movementStatusMap[row.original.movementType] ?? 'neutral'\n return (\n <StatusBadge variant={badgeVariant} dot>\n {movementLabel}\n </StatusBadge>\n )\n },\n meta: { maxWidth: '7rem' },\n },\n {\n id: 'details',\n header: t('wms.backend.dashboard.activity.columns.details', 'Details'),\n cell: ({ row }) => {\n const subtitle = formatActivitySubtitle(row.original, t)\n return (\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium\">{formatActivityTitle(row.original, t)}</p>\n {subtitle ? (\n <p className=\"truncate text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n </div>\n )\n },\n },\n {\n id: 'location',\n header: t('wms.backend.dashboard.activity.columns.location', 'Location'),\n accessorKey: 'locationLabel',\n cell: ({ row }) => (\n <p className=\"truncate text-sm text-muted-foreground\">{row.original.locationLabel}</p>\n ),\n meta: { maxWidth: '11rem', truncate: true },\n },\n {\n id: 'time',\n header: t('wms.backend.dashboard.activity.columns.time', 'Time'),\n accessorKey: 'performedAt',\n cell: ({ row }) => (\n <p className=\"text-xs leading-4 text-muted-foreground\">\n {activityTimeFormatter.format(new Date(row.original.performedAt))}\n </p>\n ),\n meta: { maxWidth: '5rem' },\n },\n {\n id: 'actions',\n header: t('wms.backend.dashboard.activity.columns.actions', 'Actions'),\n cell: ({ row }) => (\n <Button asChild type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\">\n <Link\n href={`${movementsHref}#${row.original.id}`}\n aria-label={t('wms.backend.dashboard.activity.open', 'Open movement')}\n >\n <ExternalLink className=\"size-3.5\" />\n </Link>\n </Button>\n ),\n meta: { maxWidth: '2.5rem' },\n },\n ],\n [activityTimeFormatter, movementsHref, t],\n )\n\n const subtitle = dashboardQuery.data?.lastUpdatedAt\n ? t('wms.backend.dashboard.subtitle', 'Live activity for today \u00B7 auto-refresh 60s \u00B7 last update {time}', {\n time: lastUpdatedFormatter.format(new Date(dashboardQuery.data.lastUpdatedAt)),\n })\n : t('wms.backend.dashboard.subtitleLoading', 'Live activity for today \u00B7 auto-refresh 60s')\n\n return (\n <Page>\n <PageBody className=\"space-y-6\">\n <PageHeader\n title={t('wms.backend.dashboard.title', 'Operational dashboard')}\n description={subtitle}\n actions={(\n <>\n <Select value={warehouseId} onValueChange={setWarehouseId}>\n <SelectTrigger className=\"w-full max-w-xs sm:w-56\">\n <SelectValue placeholder={warehouseLabel} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {t('wms.backend.dashboard.filters.allWarehouses', 'All warehouses')}\n </SelectItem>\n {(warehousesQuery.data ?? []).map((warehouse) => (\n <SelectItem key={warehouse.id} value={warehouse.id}>\n {warehouse.name || warehouse.code || warehouse.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => { void dashboardQuery.refetch() }}\n disabled={dashboardQuery.isFetching}\n >\n <RefreshCw className={`size-4 ${dashboardQuery.isFetching ? 'animate-spin' : ''}`} />\n {t('wms.backend.dashboard.actions.refresh', 'Refresh')}\n </Button>\n </>\n )}\n />\n\n {dashboardQuery.isLoading ? (\n <LoadingMessage label={t('wms.backend.dashboard.loading', 'Loading dashboard\u2026')} />\n ) : null}\n\n {dashboardQuery.isError ? (\n <ErrorMessage\n label={t('wms.backend.dashboard.errors.load', 'Failed to load dashboard.')}\n action={(\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => { void dashboardQuery.refetch() }}>\n {t('wms.backend.dashboard.actions.refresh', 'Refresh')}\n </Button>\n )}\n />\n ) : null}\n\n {firstRunMode === 'no-warehouses' ? (\n <section className=\"rounded-lg border-2 border-dashed border-border bg-card p-8 text-center shadow-sm\">\n <div className=\"mx-auto max-w-sm\">\n <div className=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-muted\">\n <WarehouseIcon2 className=\"size-7 text-muted-foreground\" />\n </div>\n <h2 className=\"text-lg font-semibold\">\n {t('wms.backend.dashboard.firstRun.title', 'Set up your warehouse')}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.firstRun.description',\n 'Create a warehouse, add storage locations, then receive your first stock to start tracking inventory.',\n )}\n </p>\n <div className=\"mt-6 flex flex-col items-center gap-3 sm:flex-row sm:justify-center\">\n <LinkButton asChild variant=\"primary\" size=\"sm\">\n <Link href=\"/backend/config/wms\">\n <WarehouseIcon2 className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.createWarehouse', 'Create warehouse')}\n </Link>\n </LinkButton>\n <LinkButton asChild variant=\"gray\" size=\"sm\">\n <Link href=\"/backend/config/wms\">\n <MapPin className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.addLocations', 'Add locations')}\n </Link>\n </LinkButton>\n {access.canReceive ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setReceiveOpen(true)}>\n <ArrowDown className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.receiveStock', 'Receive first stock')}\n </Button>\n ) : null}\n </div>\n </div>\n </section>\n ) : null}\n\n {firstRunMode === 'no-locations' ? (\n <section className=\"rounded-lg border-2 border-dashed border-border bg-card p-8 text-center shadow-sm\">\n <div className=\"mx-auto max-w-sm\">\n <div className=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-muted\">\n <MapPin className=\"size-7 text-muted-foreground\" />\n </div>\n <h2 className=\"text-lg font-semibold\">\n {t('wms.backend.dashboard.firstRun.noLocations.title', 'Add storage locations')}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.firstRun.noLocations.description',\n 'Your warehouse is set up \u2014 add at least one storage location before you can receive stock.',\n )}\n </p>\n <div className=\"mt-6 flex flex-col items-center gap-3 sm:flex-row sm:justify-center\">\n <LinkButton asChild variant=\"primary\" size=\"sm\">\n <Link href=\"/backend/config/wms\">\n <MapPin className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.addLocations', 'Add locations')}\n </Link>\n </LinkButton>\n </div>\n </div>\n </section>\n ) : null}\n\n {dashboardQuery.data ? (\n <>\n <section className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6\">\n {dashboardQuery.data.kpis.map((kpi) => {\n const config = kpiConfig[kpi.id]\n const badge = config.resolveBadge(kpi)\n return (\n <DashboardKpiCard\n key={kpi.id}\n kpi={kpi}\n title={config.title}\n caption={config.caption}\n badgeLabel={badge.label}\n badgeVariant={badge.variant}\n ctaLabel={config.ctaLabel}\n href={config.href}\n />\n )\n })}\n </section>\n\n <section className=\"rounded-lg border bg-card shadow-sm\">\n <div className=\"border-b px-5 py-4\">\n <h2 className=\"text-base font-semibold\">\n {t('wms.backend.dashboard.expiry.title', 'Expiry watch')}\n </h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.expiry.description',\n 'Upcoming and overdue lots with on-hand stock in the selected warehouse scope.',\n )}\n </p>\n </div>\n <div className=\"grid gap-6 p-5 md:grid-cols-2\">\n <ExpiryLotList\n title={t('wms.backend.dashboard.expiry.expiringSoon.title', 'Expiring soon')}\n emptyLabel={t(\n 'wms.backend.dashboard.expiry.expiringSoon.empty',\n 'No lots expiring within the next 30 days.',\n )}\n viewAllLabel={t(\n 'wms.backend.dashboard.expiry.expiringSoon.viewAll',\n 'View all expiring \u2192',\n )}\n viewAllHref={kpiConfig.expiringSoon.href}\n rows={expiryLotsByCategory.expiringSoon}\n expiryFormatter={expiryDateFormatter}\n quantityFormatter={quantityFormatter}\n canAdjust={access.canAdjust}\n onChangeStatus={openExpiryChangeStatus}\n onMove={openExpiryMove}\n t={t}\n />\n <ExpiryLotList\n title={t('wms.backend.dashboard.expiry.pastDue.title', 'Past due')}\n emptyLabel={t(\n 'wms.backend.dashboard.expiry.pastDue.empty',\n 'No expired lots with available stock.',\n )}\n viewAllLabel={t(\n 'wms.backend.dashboard.expiry.pastDue.viewAll',\n 'View all past due \u2192',\n )}\n viewAllHref={kpiConfig.pastDue.href}\n rows={expiryLotsByCategory.pastDue}\n expiryFormatter={expiryDateFormatter}\n quantityFormatter={quantityFormatter}\n canAdjust={access.canAdjust}\n onChangeStatus={openExpiryChangeStatus}\n onMove={openExpiryMove}\n t={t}\n />\n </div>\n </section>\n\n <section className=\"rounded-lg border bg-card shadow-sm\">\n <div className=\"flex items-center justify-between gap-3 border-b px-5 py-4\">\n <h2 className=\"text-base font-semibold\">\n {t('wms.backend.dashboard.trends.title', 'Monthly trends')}\n </h2>\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-2\">\n <span className=\"size-2.5 rounded-sm bg-chart-1\" aria-hidden=\"true\" />\n {t('wms.backend.dashboard.trends.receive', 'Receive')}\n </span>\n <span className=\"inline-flex items-center gap-2\">\n <span className=\"size-2.5 rounded-sm bg-chart-2\" aria-hidden=\"true\" />\n {t('wms.backend.dashboard.trends.allocate', 'Allocate')}\n </span>\n </div>\n </div>\n <div className=\"p-5\">\n <BarChart\n data={monthlyTrendData}\n index=\"month\"\n categories={['receive', 'allocate']}\n showLegend={false}\n categoryLabels={{\n receive: t('wms.backend.dashboard.trends.receive', 'Receive'),\n allocate: t('wms.backend.dashboard.trends.allocate', 'Allocate'),\n }}\n emptyMessage={t('wms.backend.dashboard.trends.empty', 'No movement trends yet.')}\n className=\"border-0 bg-transparent p-0 shadow-none\"\n />\n </div>\n </section>\n\n <DataTable<OperationalDashboardActivityRow>\n title={t('wms.backend.dashboard.activity.title', 'Recent activity')}\n columns={activityColumns}\n data={dashboardQuery.data.recentActivity}\n disableRowClick\n emptyState={t('wms.backend.dashboard.activity.empty', 'No recent movements yet.')}\n actions={(\n <Button asChild type=\"button\" variant=\"ghost\" size=\"sm\">\n <Link href={movementsHref}>\n {t('wms.backend.dashboard.activity.viewAll', 'View all movements \u2192')}\n </Link>\n </Button>\n )}\n />\n\n <section className=\"flex flex-col gap-4 rounded-lg border bg-card px-5 py-4 shadow-sm lg:flex-row lg:items-center lg:justify-between\">\n <div>\n <h2 className=\"text-base font-semibold\">\n {t('wms.backend.dashboard.quickActions.title', 'Quick actions')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.quickActions.description',\n 'Open a drawer without leaving the dashboard',\n )}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button asChild type=\"button\" variant=\"outline\">\n <Link href={kpiConfig.lowStock.href}>\n <Package className=\"size-4\" />\n {t('wms.backend.dashboard.quickActions.inventory', 'Open inventory console')}\n </Link>\n </Button>\n {access.canAdjust ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setAdjustOpen(true)}>\n <SlidersHorizontal className=\"size-4\" />\n {t('wms.backend.dashboard.quickActions.adjust', 'Adjust inventory')}\n </Button>\n ) : null}\n {access.canCycleCount ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setCycleOpen(true)}>\n <ClipboardList className=\"size-4\" />\n {t('wms.backend.dashboard.quickActions.cycleCount', 'Cycle count')}\n </Button>\n ) : null}\n <Button asChild type=\"button\" variant=\"outline\">\n <Link href={movementsHref}>\n {t('wms.backend.dashboard.quickActions.movements', 'View movements')}\n </Link>\n </Button>\n </div>\n </section>\n </>\n ) : null}\n </PageBody>\n\n {access.canReceive ? (\n <ReceiveInventoryDialog open={receiveOpen} onOpenChange={setReceiveOpen} access={access} />\n ) : null}\n {access.canAdjust ? (\n <AdjustInventoryDialog open={adjustOpen} onOpenChange={setAdjustOpen} access={access} />\n ) : null}\n {access.canCycleCount ? (\n <CycleCountWizardDialog open={cycleOpen} onOpenChange={setCycleOpen} access={access} />\n ) : null}\n {access.canAdjust && activeExpiryLot ? (\n <>\n <ChangeLotStatusDialog\n open={changeStatusOpen}\n onOpenChange={setChangeStatusOpen}\n access={access}\n lotId={activeExpiryLot.id}\n currentStatus={activeExpiryLot.status}\n lotUpdatedAt={activeExpiryLot.updatedAt}\n onSuccess={() => {\n void dashboardQuery.refetch()\n }}\n />\n <MoveInventoryDialog\n open={moveOpen}\n onOpenChange={setMoveOpen}\n access={access}\n initialCatalogVariantId={activeExpiryLot.catalogVariantId}\n initialWarehouseId={warehouseId === 'all' ? undefined : warehouseId}\n initialLotId={activeExpiryLot.id}\n initialAvailable={activeExpiryLot.availableQuantity}\n lockSourceContext\n />\n </>\n ) : null}\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useQuery } from '@tanstack/react-query'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport {\n ArrowDown,\n ClipboardList,\n ExternalLink,\n MapPin,\n Package,\n RefreshCw,\n SlidersHorizontal,\n Warehouse as WarehouseIcon2,\n} from 'lucide-react'\nimport { Page, PageBody, PageHeader } from '@open-mercato/ui/backend/Page'\nimport { BarChart } from '@open-mercato/ui/backend/charts'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { LinkButton } from '@open-mercato/ui/primitives/link-button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { StatusBadge, type StatusBadgeVariant } from '@open-mercato/ui/primitives/status-badge'\nimport type {\n OperationalDashboardActivityRow,\n OperationalDashboardExpiryLotRow,\n OperationalDashboardKpi,\n OperationalDashboardPayload,\n} from '../../lib/loadOperationalDashboard'\nimport {\n inventoryMovementReasonLabel,\n type InventoryDisplayTranslator,\n} from '../../lib/inventoryDisplayUi'\nimport { AdjustInventoryDialog } from './AdjustInventoryDialog'\nimport { ChangeLotStatusDialog } from './ChangeLotStatusDialog'\nimport { CycleCountWizardDialog } from './CycleCountWizardDialog'\nimport { MoveInventoryDialog } from './MoveInventoryDialog'\nimport { ReceiveInventoryDialog } from './ReceiveInventoryDialog'\nimport { useWmsInventoryMutationAccess } from './useWmsInventoryMutationAccess'\n\ntype WarehouseOption = {\n id: string\n name?: string | null\n code?: string | null\n}\n\ntype PagedWarehouses = {\n items: WarehouseOption[]\n}\n\nconst AUTO_REFRESH_MS = 60_000\n\nfunction Sparkline({ values, className }: { values: number[]; className?: string }) {\n const width = 160\n const height = 36\n const max = Math.max(...values, 1)\n const points = values.map((value, index) => {\n const x = values.length <= 1 ? width / 2 : (index / (values.length - 1)) * width\n const y = height - (value / max) * (height - 4) - 2\n return `${x},${y}`\n })\n\n return (\n <svg\n viewBox={`0 0 ${width} ${height}`}\n className={className}\n aria-hidden=\"true\"\n preserveAspectRatio=\"none\"\n >\n <polyline\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n points={points.join(' ')}\n className=\"text-status-info-icon\"\n />\n </svg>\n )\n}\n\nfunction formatActivityTitle(\n row: OperationalDashboardActivityRow,\n t: ReturnType<typeof useT>,\n): string {\n const sku = row.variantSku?.trim() || row.variantId\n const quantity = Math.abs(row.quantity)\n const signedQuantity = row.quantity\n switch (row.movementType) {\n case 'receipt':\n case 'return_receive':\n return t('wms.backend.dashboard.activity.titles.received', 'Received {quantity}\u00D7 {sku}', {\n quantity,\n sku,\n })\n case 'adjust':\n return t('wms.backend.dashboard.activity.titles.adjusted', 'Adjusted {quantity}\u00D7 {sku}', {\n quantity: `${signedQuantity >= 0 ? '+' : ''}${signedQuantity}`,\n sku,\n })\n case 'transfer':\n return t('wms.backend.dashboard.activity.titles.moved', 'Moved {quantity}\u00D7 {sku}', {\n quantity,\n sku,\n })\n case 'pick':\n case 'pack':\n return t('wms.backend.dashboard.activity.titles.allocated', 'Allocated {quantity}\u00D7 {sku}', {\n quantity,\n sku,\n })\n case 'cycle_count':\n return t('wms.backend.dashboard.activity.titles.reconciled', 'Inventory reconciled \u2014 {sku}', {\n sku,\n })\n default:\n return t('wms.backend.dashboard.activity.titles.generic', '{type} {quantity}\u00D7 {sku}', {\n type: row.movementType,\n quantity,\n sku,\n })\n }\n}\n\nfunction formatActivitySubtitle(\n row: OperationalDashboardActivityRow,\n t: InventoryDisplayTranslator,\n): string | null {\n const reasonLabel = inventoryMovementReasonLabel(\n {\n reasonCode: row.reasonCode,\n reason: row.reason,\n movementType: row.movementType,\n },\n t,\n )\n if (reasonLabel) return reasonLabel\n if (row.referenceType && row.referenceId) return `${row.referenceType} \u00B7 ${row.referenceId}`\n return null\n}\n\nfunction createDateTimeFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return new Intl.DateTimeFormat(locale, options)\n}\n\nexport function resolveDashboardFirstRunMode(input: {\n warehousesLoading: boolean\n warehousesError: boolean\n hasWarehouses: boolean\n locationsLoading: boolean\n locationsError: boolean\n locationsCount: number\n}): 'no-warehouses' | 'no-locations' | null {\n if (input.warehousesLoading || input.warehousesError) return null\n if (!input.hasWarehouses) return 'no-warehouses'\n if (input.locationsLoading || input.locationsError) return null\n if (input.locationsCount === 0) return 'no-locations'\n return null\n}\n\ntype DashboardKpiCardProps = {\n kpi: OperationalDashboardKpi\n title: string\n caption: string\n badgeLabel: string | null\n badgeVariant: StatusBadgeVariant\n ctaLabel: string\n href: string\n}\n\nfunction DashboardKpiCard({\n kpi,\n title,\n caption,\n badgeLabel,\n badgeVariant,\n ctaLabel,\n href,\n}: DashboardKpiCardProps) {\n return (\n <section className=\"flex min-h-52 flex-col rounded-lg border bg-card p-5 text-card-foreground shadow-sm\">\n <div>\n <p className=\"text-sm font-medium\">{title}</p>\n <p className=\"mt-3 text-xs text-muted-foreground\">{caption}</p>\n </div>\n <div className=\"mt-auto pt-2\">\n <div className=\"flex items-end gap-3\">\n <p className=\"text-3xl font-semibold tracking-tight\">{kpi.count}</p>\n {badgeLabel ? (\n <StatusBadge variant={badgeVariant} dot>\n {badgeLabel}\n </StatusBadge>\n ) : null}\n </div>\n <Sparkline values={kpi.sparkline} className=\"mt-3 h-9 w-full max-w-40\" />\n <LinkButton asChild variant=\"primary\" size=\"sm\" className=\"mt-4 w-fit\">\n <Link href={href}>{ctaLabel}</Link>\n </LinkButton>\n </div>\n </section>\n )\n}\n\ntype ExpiryLotListProps = {\n title: string\n emptyLabel: string\n viewAllLabel: string\n viewAllHref: string\n rows: OperationalDashboardExpiryLotRow[]\n expiryFormatter: Intl.DateTimeFormat\n quantityFormatter: Intl.NumberFormat\n canAdjust: boolean\n onChangeStatus: (row: OperationalDashboardExpiryLotRow) => void\n onMove: (row: OperationalDashboardExpiryLotRow) => void\n t: ReturnType<typeof useT>\n}\n\nfunction ExpiryLotList({\n title,\n emptyLabel,\n viewAllLabel,\n viewAllHref,\n rows,\n expiryFormatter,\n quantityFormatter,\n canAdjust,\n onChangeStatus,\n onMove,\n t,\n}: ExpiryLotListProps) {\n return (\n <div className=\"min-w-0\">\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"text-sm font-semibold\">{title}</h3>\n <LinkButton asChild variant=\"gray\" size=\"sm\" className=\"h-8 px-2\">\n <Link href={viewAllHref}>{viewAllLabel}</Link>\n </LinkButton>\n </div>\n {rows.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">{emptyLabel}</p>\n ) : (\n <ul className=\"divide-y divide-border\">\n {rows.map((row) => {\n const badgeVariant: StatusBadgeVariant = row.category === 'pastDue' ? 'error' : 'warning'\n return (\n <li key={row.id} className=\"flex items-start justify-between gap-3 py-3 first:pt-0 last:pb-0\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium\">{row.lotNumber}</p>\n <p className=\"truncate text-xs text-muted-foreground\">{row.sku}</p>\n <div className=\"mt-1 flex flex-wrap items-center gap-2\">\n <StatusBadge variant={badgeVariant} dot>\n {expiryFormatter.format(new Date(row.expiresAt))}\n </StatusBadge>\n <span className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.expiry.available',\n '{quantity} available',\n { quantity: quantityFormatter.format(row.availableQuantity) },\n )}\n </span>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {canAdjust ? (\n <RowActions\n items={[\n {\n id: 'change-status',\n label: t('wms.backend.lots.actions.changeStatus', 'Change status'),\n onSelect: () => onChangeStatus(row),\n },\n {\n id: 'move',\n label: t('wms.backend.lots.actions.move', 'Move'),\n onSelect: () => onMove(row),\n },\n ]}\n />\n ) : null}\n <Button asChild type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7 shrink-0\">\n <Link\n href={`/backend/wms/lot/${row.id}`}\n aria-label={t('wms.backend.dashboard.expiry.openLot', 'Open lot')}\n >\n <ExternalLink className=\"size-3.5\" />\n </Link>\n </Button>\n </div>\n </li>\n )\n })}\n </ul>\n )}\n </div>\n )\n}\n\nconst movementStatusMap: Record<string, StatusBadgeVariant> = {\n receipt: 'success',\n return_receive: 'success',\n adjust: 'warning',\n transfer: 'info',\n pick: 'info',\n pack: 'info',\n cycle_count: 'neutral',\n putaway: 'info',\n ship: 'success',\n}\n\nexport default function WmsOperationalDashboardPage() {\n const t = useT()\n const locale = useLocale()\n const access = useWmsInventoryMutationAccess()\n const [warehouseId, setWarehouseId] = React.useState<string>('all')\n const [adjustOpen, setAdjustOpen] = React.useState(false)\n const [cycleOpen, setCycleOpen] = React.useState(false)\n const [changeStatusOpen, setChangeStatusOpen] = React.useState(false)\n const [moveOpen, setMoveOpen] = React.useState(false)\n const [receiveOpen, setReceiveOpen] = React.useState(false)\n const [activeExpiryLot, setActiveExpiryLot] = React.useState<OperationalDashboardExpiryLotRow | null>(null)\n\n const openExpiryChangeStatus = React.useCallback((row: OperationalDashboardExpiryLotRow) => {\n setActiveExpiryLot(row)\n setChangeStatusOpen(true)\n }, [])\n\n const openExpiryMove = React.useCallback((row: OperationalDashboardExpiryLotRow) => {\n setActiveExpiryLot(row)\n setMoveOpen(true)\n }, [])\n\n const activityTimeFormatter = React.useMemo(\n () =>\n createDateTimeFormatter(locale, {\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n }),\n [locale],\n )\n\n const lastUpdatedFormatter = React.useMemo(\n () =>\n createDateTimeFormatter(locale, {\n hour: '2-digit',\n minute: '2-digit',\n }),\n [locale],\n )\n\n const expiryDateFormatter = React.useMemo(\n () =>\n createDateTimeFormatter(locale, {\n month: '2-digit',\n day: '2-digit',\n year: '2-digit',\n }),\n [locale],\n )\n\n const quantityFormatter = React.useMemo(\n () => new Intl.NumberFormat(locale, { maximumFractionDigits: 2 }),\n [locale],\n )\n\n const warehousesQuery = useQuery({\n queryKey: ['wms-dashboard', 'warehouses'],\n queryFn: async () => {\n const params = new URLSearchParams({ page: '1', pageSize: '100', sortField: 'name', sortDir: 'asc' })\n const call = await apiCall<PagedWarehouses>(`/api/wms/warehouses?${params.toString()}`)\n if (!call.ok) {\n await raiseCrudError(call.response, t('wms.backend.dashboard.errors.warehouses', 'Failed to load warehouses.'))\n }\n return call.result?.items ?? []\n },\n })\n\n const hasWarehouses = (warehousesQuery.data ?? []).length > 0\n\n const locationsCountQuery = useQuery({\n queryKey: ['wms-dashboard', 'locations-count'],\n queryFn: async () => {\n const params = new URLSearchParams({ page: '1', pageSize: '1' })\n const call = await apiCall<{ total?: number }>(`/api/wms/locations?${params.toString()}`)\n if (!call.ok) {\n await raiseCrudError(call.response, t('wms.backend.dashboard.errors.locations', 'Failed to load locations.'))\n }\n return call.result?.total ?? 0\n },\n enabled: hasWarehouses,\n })\n\n const dashboardQuery = useQuery({\n queryKey: ['wms-dashboard', 'operational', warehouseId],\n queryFn: async () => {\n const params = new URLSearchParams()\n if (warehouseId !== 'all') params.set('warehouseId', warehouseId)\n const call = await apiCall<OperationalDashboardPayload>(\n `/api/wms/dashboard/operational?${params.toString()}`,\n )\n if (!call.ok) {\n await raiseCrudError(call.response, t('wms.backend.dashboard.errors.load', 'Failed to load dashboard.'))\n }\n return call.result as OperationalDashboardPayload\n },\n refetchInterval: AUTO_REFRESH_MS,\n })\n\n const selectedWarehouse = warehousesQuery.data?.find((warehouse) => warehouse.id === warehouseId)\n const warehouseLabel =\n warehouseId === 'all'\n ? t('wms.backend.dashboard.filters.allWarehouses', 'All warehouses')\n : selectedWarehouse?.name || selectedWarehouse?.code || warehouseId\n\n const firstRunMode = React.useMemo<'no-warehouses' | 'no-locations' | null>(\n () =>\n resolveDashboardFirstRunMode({\n warehousesLoading: warehousesQuery.isLoading,\n warehousesError: warehousesQuery.isError,\n hasWarehouses,\n locationsLoading: locationsCountQuery.isLoading,\n locationsError: locationsCountQuery.isError,\n locationsCount: locationsCountQuery.data ?? 0,\n }),\n [\n warehousesQuery.isLoading,\n warehousesQuery.isError,\n hasWarehouses,\n locationsCountQuery.isLoading,\n locationsCountQuery.isError,\n locationsCountQuery.data,\n ],\n )\n\n const kpiConfig = React.useMemo(() => {\n const buildLotsHref = (expiryWindow: 'expiringSoon' | 'pastDue') => {\n const params = new URLSearchParams({ expiryWindow })\n if (warehouseId !== 'all') params.set('warehouseId', warehouseId)\n return `/backend/wms/lots?${params.toString()}`\n }\n const buildInventoryHref = (lowStock?: 'belowReorder' | 'belowSafety') => {\n const params = new URLSearchParams()\n if (warehouseId !== 'all') params.set('warehouseId', warehouseId)\n if (lowStock) params.set('lowStock', lowStock)\n const query = params.toString()\n return query ? `/backend/wms/inventory?${query}` : '/backend/wms/inventory'\n }\n const inventoryHref = buildInventoryHref()\n const reservationsHref = warehouseId === 'all'\n ? '/backend/wms/reservations'\n : `/backend/wms/reservations?warehouseId=${encodeURIComponent(warehouseId)}`\n const movementsHref = warehouseId === 'all'\n ? '/backend/wms/movements'\n : `/backend/wms/movements?warehouseId=${encodeURIComponent(warehouseId)}`\n\n return {\n lowStock: {\n title: t('wms.backend.dashboard.kpis.lowStock.title', 'Low stock'),\n caption: t('wms.backend.dashboard.kpis.lowStock.caption', 'Below reorder point'),\n ctaLabel: t('wms.backend.dashboard.kpis.lowStock.cta', 'View low stock'),\n href: buildInventoryHref('belowReorder'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'warning' as const,\n label: t('wms.backend.dashboard.kpis.lowStock.badgeActive', '{count} active', { count: kpi.count }),\n }),\n },\n reorderCritical: {\n title: t('wms.backend.dashboard.kpis.reorderCritical.title', 'Reorder critical'),\n caption: t('wms.backend.dashboard.kpis.reorderCritical.caption', 'Below safety stock'),\n ctaLabel: t('wms.backend.dashboard.kpis.reorderCritical.cta', 'View critical'),\n href: buildInventoryHref('belowSafety'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'error' as const,\n label: t('wms.backend.dashboard.kpis.reorderCritical.badge', '{count} critical', { count: kpi.count }),\n }),\n },\n expiringSoon: {\n title: t('wms.backend.dashboard.kpis.expiringSoon.title', 'Expiring soon'),\n caption: t('wms.backend.dashboard.kpis.expiringSoon.caption', 'Lots expiring in 30 days'),\n ctaLabel: t('wms.backend.dashboard.kpis.expiringSoon.cta', 'View expiry'),\n href: buildLotsHref('expiringSoon'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'warning' as const,\n label: t('wms.backend.dashboard.kpis.expiringSoon.badge', '{count} lots', { count: kpi.count }),\n }),\n },\n pastDue: {\n title: t('wms.backend.dashboard.kpis.pastDue.title', 'Past due'),\n caption: t('wms.backend.dashboard.kpis.pastDue.caption', 'Expired lots with on-hand stock'),\n ctaLabel: t('wms.backend.dashboard.kpis.pastDue.cta', 'View past due'),\n href: buildLotsHref('pastDue'),\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'error' as const,\n label: t('wms.backend.dashboard.kpis.pastDue.badge', '{count} lots', { count: kpi.count }),\n }),\n },\n agingReservations: {\n title: t('wms.backend.dashboard.kpis.agingReservations.title', 'Aging reservations'),\n caption: t('wms.backend.dashboard.kpis.agingReservations.caption', 'Active holds older than 7 days'),\n ctaLabel: t('wms.backend.dashboard.kpis.agingReservations.cta', 'View reservations'),\n href: reservationsHref,\n resolveBadge: (kpi: OperationalDashboardKpi) => ({\n variant: 'warning' as const,\n label: t('wms.backend.dashboard.kpis.agingReservations.badge', '{count} aging', { count: kpi.count }),\n }),\n },\n todaysMoves: {\n title: t('wms.backend.dashboard.kpis.todaysMoves.title', \"Today's moves\"),\n caption: t('wms.backend.dashboard.kpis.todaysMoves.caption', 'Movements posted today'),\n ctaLabel: t('wms.backend.dashboard.kpis.todaysMoves.cta', 'View ledger'),\n href: movementsHref,\n resolveBadge: (kpi: OperationalDashboardKpi) => {\n if (kpi.deltaSinceYesterday === null) {\n return { variant: 'neutral' as const, label: null }\n }\n return {\n variant: kpi.deltaSinceYesterday >= 0 ? ('success' as const) : ('neutral' as const),\n label:\n kpi.deltaSinceYesterday >= 0\n ? t('wms.backend.dashboard.kpis.todaysMoves.badgeUp', '+{count} vs yesterday', {\n count: kpi.deltaSinceYesterday,\n })\n : t('wms.backend.dashboard.kpis.todaysMoves.badgeDown', '{count} vs yesterday', {\n count: kpi.deltaSinceYesterday,\n }),\n }\n },\n },\n }\n }, [t, warehouseId])\n\n const monthlyTrendData = React.useMemo(\n () =>\n (dashboardQuery.data?.monthlyTrends ?? []).map((point) => ({\n month: point.month,\n receive: point.receive,\n allocate: point.allocate,\n })),\n [dashboardQuery.data?.monthlyTrends],\n )\n\n const expiryLotsByCategory = React.useMemo(() => {\n const lots = dashboardQuery.data?.expiryLots ?? []\n return {\n expiringSoon: lots.filter((lot) => lot.category === 'expiringSoon'),\n pastDue: lots.filter((lot) => lot.category === 'pastDue'),\n }\n }, [dashboardQuery.data?.expiryLots])\n\n const movementsHref = kpiConfig.todaysMoves.href\n\n const activityColumns = React.useMemo<ColumnDef<OperationalDashboardActivityRow>[]>(\n () => [\n {\n id: 'event',\n header: t('wms.backend.dashboard.activity.columns.event', 'Event'),\n accessorKey: 'movementType',\n cell: ({ row }) => {\n const movementLabel = t(\n `wms.backend.dashboard.activity.types.${row.original.movementType}`,\n row.original.movementType,\n )\n const badgeVariant = movementStatusMap[row.original.movementType] ?? 'neutral'\n return (\n <StatusBadge variant={badgeVariant} dot>\n {movementLabel}\n </StatusBadge>\n )\n },\n meta: { maxWidth: '7rem' },\n },\n {\n id: 'details',\n header: t('wms.backend.dashboard.activity.columns.details', 'Details'),\n cell: ({ row }) => {\n const subtitle = formatActivitySubtitle(row.original, t)\n return (\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium\">{formatActivityTitle(row.original, t)}</p>\n {subtitle ? (\n <p className=\"truncate text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n </div>\n )\n },\n },\n {\n id: 'location',\n header: t('wms.backend.dashboard.activity.columns.location', 'Location'),\n accessorKey: 'locationLabel',\n cell: ({ row }) => (\n <p className=\"truncate text-sm text-muted-foreground\">{row.original.locationLabel}</p>\n ),\n meta: { maxWidth: '11rem', truncate: true },\n },\n {\n id: 'time',\n header: t('wms.backend.dashboard.activity.columns.time', 'Time'),\n accessorKey: 'performedAt',\n cell: ({ row }) => (\n <p className=\"text-xs leading-4 text-muted-foreground\">\n {activityTimeFormatter.format(new Date(row.original.performedAt))}\n </p>\n ),\n meta: { maxWidth: '5rem' },\n },\n {\n id: 'actions',\n header: t('wms.backend.dashboard.activity.columns.actions', 'Actions'),\n cell: ({ row }) => (\n <Button asChild type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\">\n <Link\n href={`${movementsHref}#${row.original.id}`}\n aria-label={t('wms.backend.dashboard.activity.open', 'Open movement')}\n >\n <ExternalLink className=\"size-3.5\" />\n </Link>\n </Button>\n ),\n meta: { maxWidth: '2.5rem' },\n },\n ],\n [activityTimeFormatter, movementsHref, t],\n )\n\n const subtitle = dashboardQuery.data?.lastUpdatedAt\n ? t('wms.backend.dashboard.subtitle', 'Live activity for today \u00B7 auto-refresh 60s \u00B7 last update {time}', {\n time: lastUpdatedFormatter.format(new Date(dashboardQuery.data.lastUpdatedAt)),\n })\n : t('wms.backend.dashboard.subtitleLoading', 'Live activity for today \u00B7 auto-refresh 60s')\n\n return (\n <Page>\n <PageBody className=\"space-y-6\">\n <PageHeader\n title={t('wms.backend.dashboard.title', 'Operational dashboard')}\n description={subtitle}\n actions={(\n <>\n <Select value={warehouseId} onValueChange={setWarehouseId}>\n <SelectTrigger className=\"w-full max-w-xs sm:w-56\">\n <SelectValue placeholder={warehouseLabel} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {t('wms.backend.dashboard.filters.allWarehouses', 'All warehouses')}\n </SelectItem>\n {(warehousesQuery.data ?? []).map((warehouse) => (\n <SelectItem key={warehouse.id} value={warehouse.id}>\n {warehouse.name || warehouse.code || warehouse.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => { void dashboardQuery.refetch() }}\n disabled={dashboardQuery.isFetching}\n >\n <RefreshCw className={`size-4 ${dashboardQuery.isFetching ? 'animate-spin' : ''}`} />\n {t('wms.backend.dashboard.actions.refresh', 'Refresh')}\n </Button>\n </>\n )}\n />\n\n {dashboardQuery.isLoading ? (\n <LoadingMessage label={t('wms.backend.dashboard.loading', 'Loading dashboard\u2026')} />\n ) : null}\n\n {dashboardQuery.isError ? (\n <ErrorMessage\n label={t('wms.backend.dashboard.errors.load', 'Failed to load dashboard.')}\n action={(\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => { void dashboardQuery.refetch() }}>\n {t('wms.backend.dashboard.actions.refresh', 'Refresh')}\n </Button>\n )}\n />\n ) : null}\n\n {firstRunMode === 'no-warehouses' ? (\n <section className=\"rounded-lg border-2 border-dashed border-border bg-card p-8 text-center shadow-sm\">\n <div className=\"mx-auto max-w-sm\">\n <div className=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-muted\">\n <WarehouseIcon2 className=\"size-7 text-muted-foreground\" />\n </div>\n <h2 className=\"text-lg font-semibold\">\n {t('wms.backend.dashboard.firstRun.title', 'Set up your warehouse')}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.firstRun.description',\n 'Create a warehouse, add storage locations, then receive your first stock to start tracking inventory.',\n )}\n </p>\n <div className=\"mt-6 flex flex-col items-center gap-3 sm:flex-row sm:justify-center\">\n <LinkButton asChild variant=\"primary\" size=\"sm\">\n <Link href=\"/backend/config/wms\">\n <WarehouseIcon2 className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.createWarehouse', 'Create warehouse')}\n </Link>\n </LinkButton>\n <LinkButton asChild variant=\"gray\" size=\"sm\">\n <Link href=\"/backend/config/wms\">\n <MapPin className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.addLocations', 'Add locations')}\n </Link>\n </LinkButton>\n {access.canReceive ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setReceiveOpen(true)}>\n <ArrowDown className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.receiveStock', 'Receive first stock')}\n </Button>\n ) : null}\n </div>\n </div>\n </section>\n ) : null}\n\n {firstRunMode === 'no-locations' ? (\n <section className=\"rounded-lg border-2 border-dashed border-border bg-card p-8 text-center shadow-sm\">\n <div className=\"mx-auto max-w-sm\">\n <div className=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-muted\">\n <MapPin className=\"size-7 text-muted-foreground\" />\n </div>\n <h2 className=\"text-lg font-semibold\">\n {t('wms.backend.dashboard.firstRun.noLocations.title', 'Add storage locations')}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.firstRun.noLocations.description',\n 'Your warehouse is set up \u2014 add at least one storage location before you can receive stock.',\n )}\n </p>\n <div className=\"mt-6 flex flex-col items-center gap-3 sm:flex-row sm:justify-center\">\n <LinkButton asChild variant=\"primary\" size=\"sm\">\n <Link href=\"/backend/config/wms\">\n <MapPin className=\"size-4\" />\n {t('wms.backend.dashboard.firstRun.actions.addLocations', 'Add locations')}\n </Link>\n </LinkButton>\n </div>\n </div>\n </section>\n ) : null}\n\n {dashboardQuery.data ? (\n <>\n <section className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6\">\n {dashboardQuery.data.kpis.map((kpi) => {\n const config = kpiConfig[kpi.id]\n const badge = config.resolveBadge(kpi)\n return (\n <DashboardKpiCard\n key={kpi.id}\n kpi={kpi}\n title={config.title}\n caption={config.caption}\n badgeLabel={badge.label}\n badgeVariant={badge.variant}\n ctaLabel={config.ctaLabel}\n href={config.href}\n />\n )\n })}\n </section>\n\n <section className=\"rounded-lg border bg-card shadow-sm\">\n <div className=\"border-b px-5 py-4\">\n <h2 className=\"text-base font-semibold\">\n {t('wms.backend.dashboard.expiry.title', 'Expiry watch')}\n </h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.expiry.description',\n 'Upcoming and overdue lots with on-hand stock in the selected warehouse scope.',\n )}\n </p>\n </div>\n <div className=\"grid gap-6 p-5 md:grid-cols-2\">\n <ExpiryLotList\n title={t('wms.backend.dashboard.expiry.expiringSoon.title', 'Expiring soon')}\n emptyLabel={t(\n 'wms.backend.dashboard.expiry.expiringSoon.empty',\n 'No lots expiring within the next 30 days.',\n )}\n viewAllLabel={t(\n 'wms.backend.dashboard.expiry.expiringSoon.viewAll',\n 'View all expiring \u2192',\n )}\n viewAllHref={kpiConfig.expiringSoon.href}\n rows={expiryLotsByCategory.expiringSoon}\n expiryFormatter={expiryDateFormatter}\n quantityFormatter={quantityFormatter}\n canAdjust={access.canAdjust}\n onChangeStatus={openExpiryChangeStatus}\n onMove={openExpiryMove}\n t={t}\n />\n <ExpiryLotList\n title={t('wms.backend.dashboard.expiry.pastDue.title', 'Past due')}\n emptyLabel={t(\n 'wms.backend.dashboard.expiry.pastDue.empty',\n 'No expired lots with available stock.',\n )}\n viewAllLabel={t(\n 'wms.backend.dashboard.expiry.pastDue.viewAll',\n 'View all past due \u2192',\n )}\n viewAllHref={kpiConfig.pastDue.href}\n rows={expiryLotsByCategory.pastDue}\n expiryFormatter={expiryDateFormatter}\n quantityFormatter={quantityFormatter}\n canAdjust={access.canAdjust}\n onChangeStatus={openExpiryChangeStatus}\n onMove={openExpiryMove}\n t={t}\n />\n </div>\n </section>\n\n <section className=\"rounded-lg border bg-card shadow-sm\">\n <div className=\"flex items-center justify-between gap-3 border-b px-5 py-4\">\n <h2 className=\"text-base font-semibold\">\n {t('wms.backend.dashboard.trends.title', 'Monthly trends')}\n </h2>\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-2\">\n <span className=\"size-2.5 rounded-sm bg-chart-1\" aria-hidden=\"true\" />\n {t('wms.backend.dashboard.trends.receive', 'Receive')}\n </span>\n <span className=\"inline-flex items-center gap-2\">\n <span className=\"size-2.5 rounded-sm bg-chart-2\" aria-hidden=\"true\" />\n {t('wms.backend.dashboard.trends.allocate', 'Allocate')}\n </span>\n </div>\n </div>\n <div className=\"p-5\">\n <BarChart\n data={monthlyTrendData}\n index=\"month\"\n categories={['receive', 'allocate']}\n showLegend={false}\n categoryLabels={{\n receive: t('wms.backend.dashboard.trends.receive', 'Receive'),\n allocate: t('wms.backend.dashboard.trends.allocate', 'Allocate'),\n }}\n emptyMessage={t('wms.backend.dashboard.trends.empty', 'No movement trends yet.')}\n className=\"border-0 bg-transparent p-0 shadow-none\"\n />\n </div>\n </section>\n\n <DataTable<OperationalDashboardActivityRow>\n title={t('wms.backend.dashboard.activity.title', 'Recent activity')}\n columns={activityColumns}\n data={dashboardQuery.data.recentActivity}\n disableRowClick\n emptyState={t('wms.backend.dashboard.activity.empty', 'No recent movements yet.')}\n actions={(\n <Button asChild type=\"button\" variant=\"ghost\" size=\"sm\">\n <Link href={movementsHref}>\n {t('wms.backend.dashboard.activity.viewAll', 'View all movements \u2192')}\n </Link>\n </Button>\n )}\n />\n\n <section className=\"flex flex-col gap-4 rounded-lg border bg-card px-5 py-4 shadow-sm lg:flex-row lg:items-center lg:justify-between\">\n <div>\n <h2 className=\"text-base font-semibold\">\n {t('wms.backend.dashboard.quickActions.title', 'Quick actions')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'wms.backend.dashboard.quickActions.description',\n 'Open a drawer without leaving the dashboard',\n )}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button asChild type=\"button\" variant=\"outline\">\n <Link href={kpiConfig.lowStock.href}>\n <Package className=\"size-4\" />\n {t('wms.backend.dashboard.quickActions.inventory', 'Open inventory console')}\n </Link>\n </Button>\n {access.canAdjust ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setAdjustOpen(true)}>\n <SlidersHorizontal className=\"size-4\" />\n {t('wms.backend.dashboard.quickActions.adjust', 'Adjust inventory')}\n </Button>\n ) : null}\n {access.canCycleCount ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setCycleOpen(true)}>\n <ClipboardList className=\"size-4\" />\n {t('wms.backend.dashboard.quickActions.cycleCount', 'Cycle count')}\n </Button>\n ) : null}\n <Button asChild type=\"button\" variant=\"outline\">\n <Link href={movementsHref}>\n {t('wms.backend.dashboard.quickActions.movements', 'View movements')}\n </Link>\n </Button>\n </div>\n </section>\n </>\n ) : null}\n </PageBody>\n\n {access.canReceive ? (\n <ReceiveInventoryDialog open={receiveOpen} onOpenChange={setReceiveOpen} access={access} />\n ) : null}\n {access.canAdjust ? (\n <AdjustInventoryDialog open={adjustOpen} onOpenChange={setAdjustOpen} access={access} />\n ) : null}\n {access.canCycleCount ? (\n <CycleCountWizardDialog open={cycleOpen} onOpenChange={setCycleOpen} access={access} />\n ) : null}\n {access.canAdjust && activeExpiryLot ? (\n <>\n <ChangeLotStatusDialog\n open={changeStatusOpen}\n onOpenChange={setChangeStatusOpen}\n access={access}\n lotId={activeExpiryLot.id}\n currentStatus={activeExpiryLot.status}\n lotUpdatedAt={activeExpiryLot.updatedAt}\n onSuccess={() => {\n void dashboardQuery.refetch()\n }}\n />\n <MoveInventoryDialog\n open={moveOpen}\n onOpenChange={setMoveOpen}\n access={access}\n initialCatalogVariantId={activeExpiryLot.catalogVariantId}\n initialWarehouseId={warehouseId === 'all' ? undefined : warehouseId}\n initialLotId={activeExpiryLot.id}\n initialAvailable={activeExpiryLot.availableQuantity}\n lockSourceContext\n />\n </>\n ) : null}\n </Page>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["movementsHref", "subtitle"]
7
7
  }
@@ -248,13 +248,17 @@ function SkuKpiCard({
248
248
  ctaHref
249
249
  }) {
250
250
  return /* @__PURE__ */ jsxs("section", { className: "flex min-h-52 flex-col rounded-lg border bg-card p-5 text-card-foreground shadow-sm", children: [
251
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: title }),
252
- /* @__PURE__ */ jsx("p", { className: "mt-3 text-xs text-muted-foreground", children: caption }),
253
- /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-end gap-3", children: [
254
- /* @__PURE__ */ jsx("p", { className: "text-3xl font-semibold tracking-tight", children: value }),
255
- badgeLabel ? /* @__PURE__ */ jsx(StatusBadge, { variant: badgeVariant, dot: true, children: badgeLabel }) : null
251
+ /* @__PURE__ */ jsxs("div", { children: [
252
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: title }),
253
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-xs text-muted-foreground", children: caption })
256
254
  ] }),
257
- /* @__PURE__ */ jsx(LinkButton, { asChild: true, variant: "primary", size: "sm", className: "mt-auto pt-4 w-fit", children: /* @__PURE__ */ jsx(Link, { href: ctaHref, children: ctaLabel }) })
255
+ /* @__PURE__ */ jsxs("div", { className: "mt-auto pt-2", children: [
256
+ /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-3", children: [
257
+ /* @__PURE__ */ jsx("p", { className: "text-3xl font-semibold tracking-tight", children: value }),
258
+ badgeLabel ? /* @__PURE__ */ jsx(StatusBadge, { variant: badgeVariant, dot: true, children: badgeLabel }) : null
259
+ ] }),
260
+ /* @__PURE__ */ jsx(LinkButton, { asChild: true, variant: "primary", size: "sm", className: "mt-4 w-fit", children: /* @__PURE__ */ jsx(Link, { href: ctaHref, children: ctaLabel }) })
261
+ ] })
258
262
  ] });
259
263
  }
260
264
  function WmsSkuDetailPage({ variantId }) {