@burdenoff/microfe-theglobalfuel 2026.704.1 → 2026.705.2

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 (133) hide show
  1. package/dist/node_modules/{.bun/clsx@2.1.1/node_modules/clsx → clsx}/dist/clsx.js +1 -1
  2. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  3. package/dist/node_modules/{.bun/tailwind-merge@3.5.0/node_modules/tailwind-merge → tailwind-merge}/dist/bundle-mjs.js +212 -170
  4. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  5. package/dist/theglobalfuel/components/DataTable.js +37 -27
  6. package/dist/theglobalfuel/components/DataTable.js.map +1 -1
  7. package/dist/theglobalfuel/hooks/index.js +1 -0
  8. package/dist/theglobalfuel/hooks/useNotify.js +19 -0
  9. package/dist/theglobalfuel/hooks/useNotify.js.map +1 -0
  10. package/dist/theglobalfuel/hooks/useTheFiles.js +4 -1
  11. package/dist/theglobalfuel/hooks/useTheFiles.js.map +1 -1
  12. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js +59 -31
  13. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js.map +1 -1
  14. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js +367 -321
  15. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js.map +1 -1
  16. package/dist/theglobalfuel/pages/assets/AssetsPage.js +66 -54
  17. package/dist/theglobalfuel/pages/assets/AssetsPage.js.map +1 -1
  18. package/dist/theglobalfuel/pages/compliance/CompliancePage.js +346 -182
  19. package/dist/theglobalfuel/pages/compliance/CompliancePage.js.map +1 -1
  20. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.js +418 -390
  21. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.js.map +1 -1
  22. package/dist/theglobalfuel/pages/contracts/ContractsPage.js +238 -230
  23. package/dist/theglobalfuel/pages/contracts/ContractsPage.js.map +1 -1
  24. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js +5 -3
  25. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js.map +1 -1
  26. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js +201 -177
  27. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js.map +1 -1
  28. package/dist/theglobalfuel/pages/inventory/InventoryPage.js +271 -238
  29. package/dist/theglobalfuel/pages/inventory/InventoryPage.js.map +1 -1
  30. package/dist/theglobalfuel/pages/production/ProductionPage.js +185 -177
  31. package/dist/theglobalfuel/pages/production/ProductionPage.js.map +1 -1
  32. package/dist/theglobalfuel/pages/reserves/ReservesPage.js +160 -138
  33. package/dist/theglobalfuel/pages/reserves/ReservesPage.js.map +1 -1
  34. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js +250 -198
  35. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js.map +1 -1
  36. package/dist/theglobalfuel/utils/cn.js +2 -2
  37. package/dist/theglobalfuel/utils/formatters.js +6 -1
  38. package/dist/theglobalfuel/utils/formatters.js.map +1 -1
  39. package/dist/theglobalfuel/utils/transitions.js +70 -0
  40. package/dist/theglobalfuel/utils/transitions.js.map +1 -0
  41. package/package.json +1 -1
  42. package/dist/dev/main.d.ts +0 -2
  43. package/dist/dev/main.d.ts.map +0 -1
  44. package/dist/index.d.ts +0 -2
  45. package/dist/index.d.ts.map +0 -1
  46. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js.map +0 -1
  47. package/dist/node_modules/.bun/tailwind-merge@3.5.0/node_modules/tailwind-merge/dist/bundle-mjs.js.map +0 -1
  48. package/dist/theglobalfuel/TheGlobalFuelRoot.d.ts +0 -5
  49. package/dist/theglobalfuel/TheGlobalFuelRoot.d.ts.map +0 -1
  50. package/dist/theglobalfuel/TheGlobalFuelRoutes.d.ts +0 -4
  51. package/dist/theglobalfuel/TheGlobalFuelRoutes.d.ts.map +0 -1
  52. package/dist/theglobalfuel/components/DataTable.d.ts +0 -28
  53. package/dist/theglobalfuel/components/DataTable.d.ts.map +0 -1
  54. package/dist/theglobalfuel/components/EmptyState.d.ts +0 -18
  55. package/dist/theglobalfuel/components/EmptyState.d.ts.map +0 -1
  56. package/dist/theglobalfuel/components/EvidenceUpload.d.ts +0 -14
  57. package/dist/theglobalfuel/components/EvidenceUpload.d.ts.map +0 -1
  58. package/dist/theglobalfuel/components/FileLink.d.ts +0 -15
  59. package/dist/theglobalfuel/components/FileLink.d.ts.map +0 -1
  60. package/dist/theglobalfuel/components/FilterTabs.d.ts +0 -18
  61. package/dist/theglobalfuel/components/FilterTabs.d.ts.map +0 -1
  62. package/dist/theglobalfuel/components/MetricsCard.d.ts +0 -23
  63. package/dist/theglobalfuel/components/MetricsCard.d.ts.map +0 -1
  64. package/dist/theglobalfuel/components/MiniBar.d.ts +0 -16
  65. package/dist/theglobalfuel/components/MiniBar.d.ts.map +0 -1
  66. package/dist/theglobalfuel/components/PageLayout.d.ts +0 -16
  67. package/dist/theglobalfuel/components/PageLayout.d.ts.map +0 -1
  68. package/dist/theglobalfuel/components/Pagination.d.ts +0 -22
  69. package/dist/theglobalfuel/components/Pagination.d.ts.map +0 -1
  70. package/dist/theglobalfuel/components/StateViews.d.ts +0 -24
  71. package/dist/theglobalfuel/components/StateViews.d.ts.map +0 -1
  72. package/dist/theglobalfuel/components/StatusBadge.d.ts +0 -9
  73. package/dist/theglobalfuel/components/StatusBadge.d.ts.map +0 -1
  74. package/dist/theglobalfuel/components/Tabs.d.ts +0 -17
  75. package/dist/theglobalfuel/components/Tabs.d.ts.map +0 -1
  76. package/dist/theglobalfuel/components/TheDiscussion.d.ts +0 -18
  77. package/dist/theglobalfuel/components/TheDiscussion.d.ts.map +0 -1
  78. package/dist/theglobalfuel/components/TheTags.d.ts +0 -17
  79. package/dist/theglobalfuel/components/TheTags.d.ts.map +0 -1
  80. package/dist/theglobalfuel/components/index.d.ts +0 -19
  81. package/dist/theglobalfuel/components/index.d.ts.map +0 -1
  82. package/dist/theglobalfuel/context/TheGlobalFuelContext.d.ts +0 -16
  83. package/dist/theglobalfuel/context/TheGlobalFuelContext.d.ts.map +0 -1
  84. package/dist/theglobalfuel/context/index.d.ts +0 -6
  85. package/dist/theglobalfuel/context/index.d.ts.map +0 -1
  86. package/dist/theglobalfuel/hooks/index.d.ts +0 -10
  87. package/dist/theglobalfuel/hooks/index.d.ts.map +0 -1
  88. package/dist/theglobalfuel/hooks/useCursorPager.d.ts +0 -33
  89. package/dist/theglobalfuel/hooks/useCursorPager.d.ts.map +0 -1
  90. package/dist/theglobalfuel/hooks/useTheComments.d.ts +0 -36
  91. package/dist/theglobalfuel/hooks/useTheComments.d.ts.map +0 -1
  92. package/dist/theglobalfuel/hooks/useTheFiles.d.ts +0 -47
  93. package/dist/theglobalfuel/hooks/useTheFiles.d.ts.map +0 -1
  94. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts +0 -75
  95. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts.map +0 -1
  96. package/dist/theglobalfuel/hooks/useTheTags.d.ts +0 -44
  97. package/dist/theglobalfuel/hooks/useTheTags.d.ts.map +0 -1
  98. package/dist/theglobalfuel/index.d.ts +0 -9
  99. package/dist/theglobalfuel/index.d.ts.map +0 -1
  100. package/dist/theglobalfuel/pages/assets/AssetDetailPage.d.ts +0 -13
  101. package/dist/theglobalfuel/pages/assets/AssetDetailPage.d.ts.map +0 -1
  102. package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts +0 -10
  103. package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts.map +0 -1
  104. package/dist/theglobalfuel/pages/compliance/CompliancePage.d.ts +0 -11
  105. package/dist/theglobalfuel/pages/compliance/CompliancePage.d.ts.map +0 -1
  106. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.d.ts +0 -9
  107. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.d.ts.map +0 -1
  108. package/dist/theglobalfuel/pages/contracts/ContractsPage.d.ts +0 -8
  109. package/dist/theglobalfuel/pages/contracts/ContractsPage.d.ts.map +0 -1
  110. package/dist/theglobalfuel/pages/dashboard/DashboardPage.d.ts +0 -13
  111. package/dist/theglobalfuel/pages/dashboard/DashboardPage.d.ts.map +0 -1
  112. package/dist/theglobalfuel/pages/emissions/EmissionsPage.d.ts +0 -12
  113. package/dist/theglobalfuel/pages/emissions/EmissionsPage.d.ts.map +0 -1
  114. package/dist/theglobalfuel/pages/inventory/InventoryPage.d.ts +0 -11
  115. package/dist/theglobalfuel/pages/inventory/InventoryPage.d.ts.map +0 -1
  116. package/dist/theglobalfuel/pages/production/ProductionPage.d.ts +0 -11
  117. package/dist/theglobalfuel/pages/production/ProductionPage.d.ts.map +0 -1
  118. package/dist/theglobalfuel/pages/reserves/ReservesPage.d.ts +0 -10
  119. package/dist/theglobalfuel/pages/reserves/ReservesPage.d.ts.map +0 -1
  120. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.d.ts +0 -10
  121. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.d.ts.map +0 -1
  122. package/dist/theglobalfuel/types/index.d.ts +0 -376
  123. package/dist/theglobalfuel/types/index.d.ts.map +0 -1
  124. package/dist/theglobalfuel/utils/cn.d.ts +0 -4
  125. package/dist/theglobalfuel/utils/cn.d.ts.map +0 -1
  126. package/dist/theglobalfuel/utils/formatters.d.ts +0 -36
  127. package/dist/theglobalfuel/utils/formatters.d.ts.map +0 -1
  128. package/dist/theglobalfuel/utils/i18n.d.ts +0 -6
  129. package/dist/theglobalfuel/utils/i18n.d.ts.map +0 -1
  130. package/dist/theglobalfuel/utils/index.d.ts +0 -9
  131. package/dist/theglobalfuel/utils/index.d.ts.map +0 -1
  132. package/dist/theglobalfuel/utils/navigation.d.ts +0 -14
  133. package/dist/theglobalfuel/utils/navigation.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CompliancePage.js","names":[],"sources":["../../../../src/theglobalfuel/pages/compliance/CompliancePage.tsx"],"sourcesContent":["/**\n * Compliance — certifications, licenses & permits register.\n * @module theglobalfuel/pages/compliance\n *\n * Reads `theListComplianceCerts` (a plain array — no pagination); writes\n * `theCreateComplianceCert` and lifecycle transitions via\n * `theTransitionComplianceCert`. Every figure comes from the real\n * `wspace-theglobalfuel-svc` contract — no mock data.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, ScrollText, BadgeCheck, Clock, AlertTriangle } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n MetricsCard,\n StatusBadge,\n DataTable,\n type Column,\n FilterTabs,\n type FilterOption,\n LoadingView,\n ErrorView,\n EmptyState,\n EvidenceUpload,\n FileLink,\n} from '../../components';\nimport {\n useTheComplianceCerts,\n useTheCreateComplianceCert,\n useTheTransitionComplianceCert,\n useTheAssets,\n type UploadedTheFile,\n} from '../../hooks';\nimport { useTheGlobalFuel } from '../../context';\nimport { formatDate, formatEnumLabel, isExpired } from '../../utils';\nimport type {\n TheComplianceCert,\n TheComplianceCategory,\n TheComplianceStatus,\n} from '../../types';\n\n// ── Enum option sets (mirror svc) ────────────────────────────────────────────\nconst STATUS_FILTERS: FilterOption<TheComplianceStatus | 'ALL'>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'PENDING', label: 'Pending' },\n { value: 'SUBMITTED', label: 'Submitted' },\n { value: 'APPROVED', label: 'Approved' },\n { value: 'REJECTED', label: 'Rejected' },\n { value: 'EXPIRED', label: 'Expired' },\n { value: 'REVOKED', label: 'Revoked' },\n];\n\nconst STATUSES: TheComplianceStatus[] = [\n 'PENDING',\n 'SUBMITTED',\n 'APPROVED',\n 'REJECTED',\n 'EXPIRED',\n 'REVOKED',\n];\n\nconst CATEGORIES: TheComplianceCategory[] = [\n 'EXTRACTION_LICENSE',\n 'ENVIRONMENTAL_PERMIT',\n 'EXPORT_LICENSE',\n 'SAFETY_AUDIT',\n 'EMISSIONS_REPORT',\n 'CARBON_CREDIT',\n 'CHAIN_OF_CUSTODY',\n];\n\nconst THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;\n\n/** True when a cert is still valid but expires within the next 30 days. */\nfunction isExpiringSoon(date: string | null | undefined): boolean {\n if (!date) return false;\n const d = new Date(date);\n if (Number.isNaN(d.getTime())) return false;\n const diff = d.getTime() - Date.now();\n return diff >= 0 && diff <= THIRTY_DAYS_MS;\n}\n\ninterface CreateFormState {\n title: string;\n category: TheComplianceCategory;\n assetId: string;\n authority: string;\n certNumber: string;\n issuedAt: string;\n expiresAt: string;\n notes: string;\n}\n\nconst EMPTY_FORM: CreateFormState = {\n title: '',\n category: 'EXTRACTION_LICENSE',\n assetId: '',\n authority: '',\n certNumber: '',\n issuedAt: '',\n expiresAt: '',\n notes: '',\n};\n\nexport function CompliancePage() {\n const { currentUser } = useTheGlobalFuel();\n\n const [status, setStatus] = useState<TheComplianceStatus | 'ALL'>('ALL');\n const [category, setCategory] = useState<TheComplianceCategory | 'ALL'>('ALL');\n const [assetFilter, setAssetFilter] = useState<string>('ALL');\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<CreateFormState>(EMPTY_FORM);\n const [evidence, setEvidence] = useState<UploadedTheFile | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n\n // Assets feed both the filter Select and the create dialog's asset picker.\n const assets = useTheAssets({ pagination: { limit: 100 } });\n const assetItems = assets.data?.items ?? [];\n\n // Unfiltered register drives the header KPIs (portfolio-wide, filter-agnostic).\n const allCerts = useTheComplianceCerts();\n // Filtered register drives the table.\n const { data, isLoading, isError, refetch } = useTheComplianceCerts(\n assetFilter === 'ALL' ? undefined : assetFilter,\n category === 'ALL' ? undefined : category,\n status === 'ALL' ? undefined : status\n );\n\n const createCert = useTheCreateComplianceCert();\n const transitionCert = useTheTransitionComplianceCert();\n\n const rows = useMemo(() => data ?? [], [data]);\n const filtersActive = status !== 'ALL' || category !== 'ALL' || assetFilter !== 'ALL';\n\n // ── Header metrics (portfolio-wide) ────────────────────────────────────────\n const portfolio = useMemo(() => allCerts.data ?? [], [allCerts.data]);\n const total = portfolio.length;\n const approvedCount = portfolio.filter((c) => c.status === 'APPROVED').length;\n const pendingCount = portfolio.filter((c) => c.status === 'PENDING').length;\n const atRiskCount = portfolio.filter(\n (c) => c.status === 'EXPIRED' || isExpired(c.expiresAt) || isExpiringSoon(c.expiresAt)\n ).length;\n\n // Per-status counts for the filter tabs.\n const statusCounts = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const c of portfolio) counts[c.status] = (counts[c.status] ?? 0) + 1;\n return counts;\n }, [portfolio]);\n const statusFilterOptions = STATUS_FILTERS.map((opt) => ({\n ...opt,\n count: opt.value === 'ALL' ? total : (statusCounts[opt.value] ?? 0),\n }));\n\n const resetForm = () => {\n setForm(EMPTY_FORM);\n setEvidence(null);\n setFormError(null);\n };\n\n const handleCreate = async () => {\n if (!form.title.trim()) {\n setFormError('A certification title is required.');\n return;\n }\n setFormError(null);\n try {\n await createCert.mutateAsync({\n title: form.title.trim(),\n category: form.category,\n assetId: form.assetId || null,\n authority: form.authority.trim() || null,\n certNumber: form.certNumber.trim() || null,\n ownerId: currentUser?.id || null,\n issuedAt: form.issuedAt ? new Date(form.issuedAt).toISOString() : null,\n expiresAt: form.expiresAt ? new Date(form.expiresAt).toISOString() : null,\n evidenceFileId: evidence?.fileId ?? null,\n notes: form.notes.trim() || null,\n });\n setDialogOpen(false);\n resetForm();\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to create certification.');\n }\n };\n\n // ── Columns ────────────────────────────────────────────────────────────────\n const columns: Column<TheComplianceCert>[] = [\n {\n key: 'title',\n header: 'Certification',\n render: (c) => (\n <div className=\"min-w-0\">\n <p className=\"truncate font-semibold text-text-primary\">{c.title}</p>\n <p className=\"truncate text-xs text-text-tertiary\">{formatEnumLabel(c.category)}</p>\n </div>\n ),\n },\n {\n key: 'category',\n header: 'Category',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-secondary\">{formatEnumLabel(c.category)}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n render: (c) => <StatusBadge status={c.status} />,\n },\n {\n key: 'authority',\n header: 'Authority',\n hideOnMobile: true,\n render: (c) =>\n c.authority ? (\n <span className=\"text-text-secondary\">{c.authority}</span>\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'certNumber',\n header: 'Cert. no.',\n hideOnMobile: true,\n render: (c) =>\n c.certNumber ? (\n <span className=\"tabular-nums text-text-secondary\">{c.certNumber}</span>\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'issued',\n header: 'Issued',\n align: 'right',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-tertiary\">{formatDate(c.issuedAt)}</span>,\n },\n {\n key: 'expires',\n header: 'Expires',\n align: 'right',\n render: (c) => {\n if (!c.expiresAt) return <span className=\"text-text-tertiary\">—</span>;\n const expired = isExpired(c.expiresAt);\n const soon = !expired && isExpiringSoon(c.expiresAt);\n return (\n <div className=\"flex items-center justify-end gap-2\">\n <span className=\"tabular-nums text-text-secondary\">{formatDate(c.expiresAt)}</span>\n {expired ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-error-bg-subtle px-2 py-0.5 text-xs font-medium text-status-error-text\">\n <AlertTriangle className=\"h-3 w-3\" aria-hidden=\"true\" /> Expired\n </span>\n ) : soon ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n <Clock className=\"h-3 w-3\" aria-hidden=\"true\" /> Expiring soon\n </span>\n ) : null}\n </div>\n );\n },\n },\n {\n key: 'evidence',\n header: 'Evidence',\n hideOnMobile: true,\n render: (c) =>\n c.evidence?.id ? (\n <FileLink fileId={c.evidence.id} />\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'action',\n header: '',\n align: 'right',\n render: (c) => (\n <Select\n value={c.status}\n onValueChange={(v) => transitionCert.mutate({ id: c.id, status: v as TheComplianceStatus })}\n >\n <SelectTrigger className=\"h-8 w-36\" aria-label={`Change status for ${c.title}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUSES.map((s) => (\n <SelectItem key={s} value={s}>\n {formatEnumLabel(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n },\n ];\n\n return (\n <PageLayout\n title=\"Compliance\"\n description=\"Licenses, permits & certifications — issuance, expiry & audit evidence across the resource portfolio.\"\n actions={\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New certification\n </Button>\n }\n >\n {/* KPI strip */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<ScrollText className=\"h-5 w-5\" />}\n value={total}\n label=\"Total certifications\"\n featured\n />\n <MetricsCard\n icon={<BadgeCheck className=\"h-5 w-5\" />}\n value={approvedCount}\n label=\"Approved\"\n accent=\"success\"\n />\n <MetricsCard\n icon={<Clock className=\"h-5 w-5\" />}\n value={pendingCount}\n label=\"Pending\"\n />\n <MetricsCard\n icon={<AlertTriangle className=\"h-5 w-5\" />}\n value={atRiskCount}\n label=\"Expired / expiring\"\n accent=\"warning\"\n pill={\n atRiskCount > 0 ? (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n Action needed\n </span>\n ) : undefined\n }\n />\n </div>\n\n {/* Filters */}\n <div className=\"mb-5 mt-6 flex flex-wrap items-center gap-3\">\n <FilterTabs\n options={statusFilterOptions}\n value={status}\n onChange={(v) => setStatus(v)}\n />\n <Select\n value={category}\n onValueChange={(v) => setCategory(v as TheComplianceCategory | 'ALL')}\n >\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All categories\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All categories</SelectItem>\n {CATEGORIES.map((cat) => (\n <SelectItem key={cat} value={cat}>\n {formatEnumLabel(cat)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={assetFilter} onValueChange={(v) => setAssetFilter(v)}>\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All assets\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All assets</SelectItem>\n {assetItems.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {isLoading ? (\n <LoadingView label=\"Loading certifications…\" />\n ) : isError ? (\n <ErrorView message=\"Couldn't load certifications.\" onRetry={() => refetch()} />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ScrollText className=\"h-10 w-10\" />}\n title=\"No certifications yet\"\n description={\n filtersActive\n ? 'No certifications match these filters.'\n : 'Register your first license, permit or certification to track issuance, expiry and audit evidence.'\n }\n action={\n !filtersActive ? (\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New certification\n </Button>\n ) : undefined\n }\n />\n ) : (\n <DataTable columns={columns} rows={rows} rowKey={(c) => c.id} />\n )}\n\n {/* New certification dialog */}\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n if (!open) resetForm();\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>New certification</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Register a license, permit or certification and attach its supporting evidence.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccTitle\">Title *</Label>\n <Input\n id=\"ccTitle\"\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n placeholder=\"Block 7 extraction license\"\n />\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccCategory\">Category</Label>\n <Select\n value={form.category}\n onValueChange={(v) =>\n setForm({ ...form, category: v as TheComplianceCategory })\n }\n >\n <SelectTrigger id=\"ccCategory\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CATEGORIES.map((cat) => (\n <SelectItem key={cat} value={cat}>\n {formatEnumLabel(cat)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccAsset\">Asset</Label>\n <Select\n value={form.assetId}\n onValueChange={(v) => setForm({ ...form, assetId: v })}\n >\n <SelectTrigger id=\"ccAsset\">\n <SelectValue placeholder=\"Optional\" />\n </SelectTrigger>\n <SelectContent>\n {assetItems.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccAuthority\">Issuing authority</Label>\n <Input\n id=\"ccAuthority\"\n value={form.authority}\n onChange={(e) => setForm({ ...form, authority: e.target.value })}\n placeholder=\"Ministry of Petroleum & Natural Gas\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccNumber\">Certificate number</Label>\n <Input\n id=\"ccNumber\"\n value={form.certNumber}\n onChange={(e) => setForm({ ...form, certNumber: e.target.value })}\n placeholder=\"EXT-2026-00471\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccIssued\">Issued</Label>\n <Input\n id=\"ccIssued\"\n type=\"date\"\n value={form.issuedAt}\n onChange={(e) => setForm({ ...form, issuedAt: e.target.value })}\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccExpires\">Expires</Label>\n <Input\n id=\"ccExpires\"\n type=\"date\"\n value={form.expiresAt}\n onChange={(e) => setForm({ ...form, expiresAt: e.target.value })}\n />\n </div>\n </div>\n\n <EvidenceUpload\n id=\"evidence\"\n label=\"Evidence document\"\n value={evidence}\n onChange={setEvidence}\n hint=\"Attach the signed certificate, permit or audit report (PDF or image).\"\n />\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccNotes\">Notes</Label>\n <Textarea\n id=\"ccNotes\"\n rows={2}\n value={form.notes}\n onChange={(e) => setForm({ ...form, notes: e.target.value })}\n placeholder=\"Optional context about scope, conditions or renewal.\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleCreate} disabled={createCert.isPending}>\n {createCert.isPending ? 'Creating…' : 'Create certification'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CompliancePage.js","names":[],"sources":["../../../../src/theglobalfuel/pages/compliance/CompliancePage.tsx"],"sourcesContent":["/**\n * Compliance — certifications, licenses & permits register.\n * @module theglobalfuel/pages/compliance\n *\n * Reads `theListComplianceCerts` (a cursor connection — `{ items, pageInfo }`);\n * writes `theCreateComplianceCert` and lifecycle transitions via\n * `theTransitionComplianceCert`. Every figure comes from the real\n * `wspace-theglobalfuel-svc` contract — no mock data.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, ScrollText, BadgeCheck, Clock, AlertTriangle, Info } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n MetricsCard,\n StatusBadge,\n DataTable,\n type Column,\n FilterTabs,\n type FilterOption,\n LoadingView,\n ErrorView,\n EmptyState,\n EvidenceUpload,\n FileLink,\n TheTags,\n TheDiscussion,\n Pagination,\n} from '../../components';\nimport {\n useTheComplianceCerts,\n useTheCreateComplianceCert,\n useTheTransitionComplianceCert,\n useTheAssets,\n useCursorPager,\n useNotify,\n type UploadedTheFile,\n} from '../../hooks';\nimport { useTheGlobalFuel } from '../../context';\nimport {\n formatDate,\n formatEnumLabel,\n isExpired,\n toBackendDate,\n COMPLIANCE_TRANSITIONS,\n nextStatuses,\n} from '../../utils';\nimport type {\n TheComplianceCert,\n TheComplianceCategory,\n TheComplianceStatus,\n} from '../../types';\n\n// ── Enum option sets (mirror svc) ────────────────────────────────────────────\nconst STATUS_FILTERS: FilterOption<TheComplianceStatus | 'ALL'>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'PENDING', label: 'Pending' },\n { value: 'SUBMITTED', label: 'Submitted' },\n { value: 'APPROVED', label: 'Approved' },\n { value: 'REJECTED', label: 'Rejected' },\n { value: 'EXPIRED', label: 'Expired' },\n { value: 'REVOKED', label: 'Revoked' },\n];\n\nconst CATEGORIES: TheComplianceCategory[] = [\n 'EXTRACTION_LICENSE',\n 'ENVIRONMENTAL_PERMIT',\n 'EXPORT_LICENSE',\n 'SAFETY_AUDIT',\n 'EMISSIONS_REPORT',\n 'CARBON_CREDIT',\n 'CHAIN_OF_CUSTODY',\n];\n\nconst THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;\n\nconst PAGE_SIZE = 25;\n\n/** True when a cert is still valid but expires within the next 30 days. */\nfunction isExpiringSoon(date: string | null | undefined): boolean {\n if (!date) return false;\n const d = new Date(date);\n if (Number.isNaN(d.getTime())) return false;\n const diff = d.getTime() - Date.now();\n return diff >= 0 && diff <= THIRTY_DAYS_MS;\n}\n\ninterface CreateFormState {\n title: string;\n category: TheComplianceCategory;\n assetId: string;\n authority: string;\n certNumber: string;\n issuedAt: string;\n expiresAt: string;\n notes: string;\n}\n\nconst EMPTY_FORM: CreateFormState = {\n title: '',\n category: 'EXTRACTION_LICENSE',\n assetId: '',\n authority: '',\n certNumber: '',\n issuedAt: '',\n expiresAt: '',\n notes: '',\n};\n\nexport function CompliancePage() {\n const { currentUser } = useTheGlobalFuel();\n const notify = useNotify();\n\n const [status, setStatus] = useState<TheComplianceStatus | 'ALL'>('ALL');\n const [category, setCategory] = useState<TheComplianceCategory | 'ALL'>('ALL');\n const [assetFilter, setAssetFilter] = useState<string>('ALL');\n const pager = useCursorPager();\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<CreateFormState>(EMPTY_FORM);\n const [evidence, setEvidence] = useState<UploadedTheFile | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n\n // Track the cert whose transition is in flight, so only that row's Select\n // disables (transitionCert.isPending is shared across all rows).\n const [transitioningId, setTransitioningId] = useState<string | null>(null);\n // Details drawer — surfaces Tags + Discussion (reuses tags/conversations svc).\n const [detailsCert, setDetailsCert] = useState<TheComplianceCert | null>(null);\n const [detailsOpen, setDetailsOpen] = useState(false);\n\n // Assets feed both the filter Select and the create dialog's asset picker.\n const assets = useTheAssets({ pagination: { limit: 100 } });\n const assetItems = assets.data?.items ?? [];\n\n // Unfiltered register drives the header KPIs (portfolio-wide, filter-agnostic).\n // Broad limit so the KPIs stay representative and don't reflect a single page.\n const allCerts = useTheComplianceCerts(undefined, undefined, undefined, { limit: 200 });\n // Filtered register drives the (cursor-paginated) table.\n const { data, isLoading, isError, refetch } = useTheComplianceCerts(\n assetFilter === 'ALL' ? undefined : assetFilter,\n category === 'ALL' ? undefined : category,\n status === 'ALL' ? undefined : status,\n { limit: PAGE_SIZE, cursor: pager.cursor }\n );\n\n const createCert = useTheCreateComplianceCert();\n const transitionCert = useTheTransitionComplianceCert();\n\n const rows = useMemo(() => data?.items ?? [], [data]);\n const filtersActive = status !== 'ALL' || category !== 'ALL' || assetFilter !== 'ALL';\n\n // ── Header metrics (portfolio-wide) ────────────────────────────────────────\n const portfolio = useMemo(() => allCerts.data?.items ?? [], [allCerts.data]);\n const total = portfolio.length;\n const approvedCount = portfolio.filter((c) => c.status === 'APPROVED').length;\n const pendingCount = portfolio.filter((c) => c.status === 'PENDING').length;\n const atRiskCount = portfolio.filter(\n (c) => c.status === 'EXPIRED' || isExpired(c.expiresAt) || isExpiringSoon(c.expiresAt)\n ).length;\n\n // Per-status counts for the filter tabs.\n const statusCounts = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const c of portfolio) counts[c.status] = (counts[c.status] ?? 0) + 1;\n return counts;\n }, [portfolio]);\n const statusFilterOptions = STATUS_FILTERS.map((opt) => ({\n ...opt,\n count: opt.value === 'ALL' ? total : (statusCounts[opt.value] ?? 0),\n }));\n\n const resetForm = () => {\n setForm(EMPTY_FORM);\n setEvidence(null);\n setFormError(null);\n };\n\n const handleCreate = async () => {\n if (!form.title.trim()) {\n setFormError('A certification title is required.');\n return;\n }\n setFormError(null);\n try {\n await createCert.mutateAsync({\n title: form.title.trim(),\n category: form.category,\n assetId: form.assetId || null,\n authority: form.authority.trim() || null,\n certNumber: form.certNumber.trim() || null,\n ownerId: currentUser?.id || null,\n issuedAt: toBackendDate(form.issuedAt) ?? null,\n expiresAt: toBackendDate(form.expiresAt) ?? null,\n evidenceFileId: evidence?.fileId ?? null,\n notes: form.notes.trim() || null,\n });\n notify.success('Certification created');\n setDialogOpen(false);\n resetForm();\n } catch (err) {\n notify.fromError(err);\n setFormError(err instanceof Error ? err.message : 'Failed to create certification.');\n }\n };\n\n // ── Columns ────────────────────────────────────────────────────────────────\n const columns: Column<TheComplianceCert>[] = [\n {\n key: 'title',\n header: 'Certification',\n render: (c) => (\n <div className=\"min-w-0\">\n <p className=\"truncate font-semibold text-text-primary\">{c.title}</p>\n <p className=\"truncate text-xs text-text-tertiary\">{formatEnumLabel(c.category)}</p>\n </div>\n ),\n },\n {\n key: 'category',\n header: 'Category',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-secondary\">{formatEnumLabel(c.category)}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n render: (c) => <StatusBadge status={c.status} />,\n },\n {\n key: 'authority',\n header: 'Authority',\n hideOnMobile: true,\n render: (c) =>\n c.authority ? (\n <span className=\"text-text-secondary\">{c.authority}</span>\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'certNumber',\n header: 'Cert. no.',\n hideOnMobile: true,\n render: (c) =>\n c.certNumber ? (\n <span className=\"tabular-nums text-text-secondary\">{c.certNumber}</span>\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'issued',\n header: 'Issued',\n align: 'right',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-tertiary\">{formatDate(c.issuedAt)}</span>,\n },\n {\n key: 'expires',\n header: 'Expires',\n align: 'right',\n render: (c) => {\n if (!c.expiresAt) return <span className=\"text-text-tertiary\">—</span>;\n const expired = isExpired(c.expiresAt);\n const soon = !expired && isExpiringSoon(c.expiresAt);\n return (\n <div className=\"flex items-center justify-end gap-2\">\n <span className=\"tabular-nums text-text-secondary\">{formatDate(c.expiresAt)}</span>\n {expired ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-error-bg-subtle px-2 py-0.5 text-xs font-medium text-status-error-text\">\n <AlertTriangle className=\"h-3 w-3\" aria-hidden=\"true\" /> Expired\n </span>\n ) : soon ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n <Clock className=\"h-3 w-3\" aria-hidden=\"true\" /> Expiring soon\n </span>\n ) : null}\n </div>\n );\n },\n },\n {\n key: 'evidence',\n header: 'Evidence',\n hideOnMobile: true,\n render: (c) =>\n c.evidence?.id ? (\n <FileLink fileId={c.evidence.id} />\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'details',\n header: '',\n align: 'right',\n render: (c) => (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setDetailsCert(c);\n setDetailsOpen(true);\n }}\n aria-label={`View details for ${c.title}`}\n >\n <Info className=\"h-4 w-4\" />\n <span className=\"ml-1.5 hidden sm:inline\">Details</span>\n </Button>\n ),\n },\n {\n key: 'action',\n header: '',\n align: 'right',\n render: (c) => {\n // Offer ONLY the legal next states; a terminal status (e.g. REVOKED)\n // has none, so the control is disabled. The current status shows on the\n // trigger via the placeholder (it is not itself a selectable option).\n const nexts = nextStatuses(COMPLIANCE_TRANSITIONS, c.status);\n const terminal = nexts.length === 0;\n return (\n <Select\n value={c.status}\n disabled={terminal || transitioningId === c.id}\n onValueChange={(v) => {\n if (v === c.status) return;\n setTransitioningId(c.id);\n transitionCert.mutate(\n { id: c.id, status: v as TheComplianceStatus },\n {\n onSuccess: () => notify.success(`Status updated to ${formatEnumLabel(v)}`),\n onError: (e) => notify.fromError(e),\n onSettled: () => setTransitioningId(null),\n }\n );\n }}\n >\n <SelectTrigger\n className=\"h-8 w-36\"\n aria-label={terminal ? `Status for ${c.title}` : `Change status for ${c.title}`}\n >\n <SelectValue placeholder={formatEnumLabel(c.status)} />\n </SelectTrigger>\n <SelectContent>\n {nexts.map((s) => (\n <SelectItem key={s} value={s}>\n {formatEnumLabel(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n },\n },\n ];\n\n return (\n <PageLayout\n title=\"Compliance\"\n description=\"Licenses, permits & certifications — issuance, expiry & audit evidence across the resource portfolio.\"\n actions={\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New certification\n </Button>\n }\n >\n {/* KPI strip */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<ScrollText className=\"h-5 w-5\" />}\n value={total}\n label=\"Total certifications\"\n featured\n />\n <MetricsCard\n icon={<BadgeCheck className=\"h-5 w-5\" />}\n value={approvedCount}\n label=\"Approved\"\n accent=\"success\"\n />\n <MetricsCard\n icon={<Clock className=\"h-5 w-5\" />}\n value={pendingCount}\n label=\"Pending\"\n />\n <MetricsCard\n icon={<AlertTriangle className=\"h-5 w-5\" />}\n value={atRiskCount}\n label=\"Expired / expiring\"\n accent=\"warning\"\n pill={\n atRiskCount > 0 ? (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n Action needed\n </span>\n ) : undefined\n }\n />\n </div>\n\n {/* Filters */}\n <div className=\"mb-5 mt-6 flex flex-wrap items-center gap-3\">\n <FilterTabs\n options={statusFilterOptions}\n value={status}\n onChange={(v) => {\n setStatus(v);\n pager.reset();\n }}\n />\n <Select\n value={category}\n onValueChange={(v) => {\n setCategory(v as TheComplianceCategory | 'ALL');\n pager.reset();\n }}\n >\n <SelectTrigger className=\"w-52\" aria-label=\"Filter by category\">\n <SelectValue placeholder=\"All categories\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All categories</SelectItem>\n {CATEGORIES.map((cat) => (\n <SelectItem key={cat} value={cat}>\n {formatEnumLabel(cat)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select\n value={assetFilter}\n onValueChange={(v) => {\n setAssetFilter(v);\n pager.reset();\n }}\n >\n <SelectTrigger className=\"w-52\" aria-label=\"Filter by asset\">\n <SelectValue placeholder=\"All assets\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All assets</SelectItem>\n {assetItems.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {isLoading ? (\n <LoadingView label=\"Loading certifications…\" />\n ) : isError ? (\n <ErrorView message=\"Couldn't load certifications.\" onRetry={() => refetch()} />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ScrollText className=\"h-10 w-10\" />}\n title=\"No certifications yet\"\n description={\n filtersActive\n ? 'No certifications match these filters.'\n : 'Register your first license, permit or certification to track issuance, expiry and audit evidence.'\n }\n action={\n !filtersActive ? (\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New certification\n </Button>\n ) : undefined\n }\n />\n ) : (\n <>\n <DataTable columns={columns} rows={rows} rowKey={(c) => c.id} />\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={data?.pageInfo?.hasMore ?? false}\n onPageChange={(p) => pager.onPageChange(p, data?.pageInfo?.cursor)}\n />\n </>\n )}\n\n {/* New certification dialog */}\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n if (!open) resetForm();\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>New certification</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Register a license, permit or certification and attach its supporting evidence.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n void handleCreate();\n }}\n >\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccTitle\">Title *</Label>\n <Input\n id=\"ccTitle\"\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n placeholder=\"Block 7 extraction license\"\n />\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccCategory\">Category</Label>\n <Select\n value={form.category}\n onValueChange={(v) =>\n setForm({ ...form, category: v as TheComplianceCategory })\n }\n >\n <SelectTrigger id=\"ccCategory\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CATEGORIES.map((cat) => (\n <SelectItem key={cat} value={cat}>\n {formatEnumLabel(cat)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccAsset\">Asset</Label>\n <Select\n value={form.assetId}\n onValueChange={(v) => setForm({ ...form, assetId: v })}\n >\n <SelectTrigger id=\"ccAsset\">\n <SelectValue placeholder=\"Optional\" />\n </SelectTrigger>\n <SelectContent>\n {assetItems.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccAuthority\">Issuing authority</Label>\n <Input\n id=\"ccAuthority\"\n value={form.authority}\n onChange={(e) => setForm({ ...form, authority: e.target.value })}\n placeholder=\"Ministry of Petroleum & Natural Gas\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccNumber\">Certificate number</Label>\n <Input\n id=\"ccNumber\"\n value={form.certNumber}\n onChange={(e) => setForm({ ...form, certNumber: e.target.value })}\n placeholder=\"EXT-2026-00471\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccIssued\">Issued</Label>\n <Input\n id=\"ccIssued\"\n type=\"date\"\n value={form.issuedAt}\n onChange={(e) => setForm({ ...form, issuedAt: e.target.value })}\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccExpires\">Expires</Label>\n <Input\n id=\"ccExpires\"\n type=\"date\"\n value={form.expiresAt}\n onChange={(e) => setForm({ ...form, expiresAt: e.target.value })}\n />\n </div>\n </div>\n\n <EvidenceUpload\n id=\"evidence\"\n label=\"Evidence document\"\n accept=\"image/*,application/pdf\"\n value={evidence}\n onChange={setEvidence}\n hint=\"Attach the signed certificate, permit or audit report (PDF or image).\"\n />\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"ccNotes\">Notes</Label>\n <Textarea\n id=\"ccNotes\"\n rows={2}\n value={form.notes}\n onChange={(e) => setForm({ ...form, notes: e.target.value })}\n placeholder=\"Optional context about scope, conditions or renewal.\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={createCert.isPending}>\n {createCert.isPending ? 'Creating…' : 'Create certification'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Certification details — summary + Tags + Discussion (reuse) */}\n <ResponsiveDialog\n open={detailsOpen}\n onOpenChange={(open) => {\n setDetailsOpen(open);\n if (!open) setDetailsCert(null);\n }}\n >\n <ResponsiveDialogContent className=\"sm:max-w-xl\">\n {detailsCert && (\n <>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>{detailsCert.title}</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {formatEnumLabel(detailsCert.category)}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"max-h-[70vh] space-y-6 overflow-y-auto py-2\">\n {/* Summary */}\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-3 text-sm\">\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Status</dt>\n <dd>\n <StatusBadge status={detailsCert.status} />\n </dd>\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Asset</dt>\n <dd className=\"text-text-secondary\">\n {detailsCert.assetId\n ? (assetItems.find((a) => a.id === detailsCert.assetId)?.name ?? '—')\n : '—'}\n </dd>\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Authority</dt>\n <dd className=\"text-text-secondary\">{detailsCert.authority || '—'}</dd>\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Certificate no.</dt>\n <dd className=\"tabular-nums text-text-secondary\">\n {detailsCert.certNumber || '—'}\n </dd>\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Issued</dt>\n <dd className=\"text-text-secondary\">{formatDate(detailsCert.issuedAt)}</dd>\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Expires</dt>\n <dd className=\"text-text-secondary\">{formatDate(detailsCert.expiresAt)}</dd>\n </div>\n {detailsCert.evidence?.id && (\n <div className=\"col-span-2 space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Evidence</dt>\n <dd>\n <FileLink fileId={detailsCert.evidence.id} />\n </dd>\n </div>\n )}\n {detailsCert.notes && (\n <div className=\"col-span-2 space-y-1\">\n <dt className=\"text-xs text-text-tertiary\">Notes</dt>\n <dd className=\"whitespace-pre-wrap text-text-secondary\">\n {detailsCert.notes}\n </dd>\n </div>\n )}\n </dl>\n\n {/* Tags — reuses wspace-tags-svc, keyed by the cert id */}\n <div className=\"border-t border-border-seam pt-4\">\n <TheTags entityType=\"theglobalfuel-compliance\" entityId={detailsCert.id} />\n </div>\n\n {/* Discussion — reuses wspace-conversations-svc, keyed by the cert id */}\n <div className=\"border-t border-border-seam pt-4\">\n <TheDiscussion\n entityType=\"theglobalfuel-compliance\"\n entityId={detailsCert.id}\n title=\"Discussion\"\n description=\"Coordinate review, renewal & audit evidence for this certification.\"\n />\n </div>\n </div>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDetailsOpen(false)}>\n Close\n </Button>\n </ResponsiveDialogFooter>\n </>\n )}\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}