@burdenoff/microfe-assethandler 2026.625.2 → 2026.703.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/assethandler/AssetHandlerRoot.js +0 -24
  2. package/dist/assethandler/AssetHandlerRoot.js.map +1 -1
  3. package/dist/assethandler/AssetHandlerRoutes.js +92 -160
  4. package/dist/assethandler/AssetHandlerRoutes.js.map +1 -1
  5. package/dist/assethandler/pages/AnalyticsPage.js +367 -402
  6. package/dist/assethandler/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js +29 -26
  8. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js.map +1 -1
  9. package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js +278 -164
  10. package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
  11. package/dist/assethandler/pages/AssetsAssetCreatePage.js +200 -242
  12. package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
  13. package/dist/assethandler/pages/AssetsAssetDetailPage.js +192 -286
  14. package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
  15. package/dist/assethandler/pages/AssetsAssetListPage.js +204 -296
  16. package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
  17. package/dist/assethandler/pages/AssetsAssetTrackingPage.js +38 -42
  18. package/dist/assethandler/pages/AssetsAssetTrackingPage.js.map +1 -1
  19. package/dist/assethandler/pages/DashboardPage.js +212 -236
  20. package/dist/assethandler/pages/DashboardPage.js.map +1 -1
  21. package/dist/assethandler/pages/ItilIncidentDetailPage.js +41 -85
  22. package/dist/assethandler/pages/ItilIncidentDetailPage.js.map +1 -1
  23. package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js +1 -1
  24. package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js.map +1 -1
  25. package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js +37 -86
  26. package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js.map +1 -1
  27. package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js +82 -98
  28. package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js.map +1 -1
  29. package/dist/assethandler/pages/OperationsOperationsHubPage.js +6 -22
  30. package/dist/assethandler/pages/OperationsOperationsHubPage.js.map +1 -1
  31. package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js +4 -34
  32. package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
  33. package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js +105 -150
  34. package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js.map +1 -1
  35. package/dist/assethandler/pages/TransactionsTransactionDetailPage.js +116 -152
  36. package/dist/assethandler/pages/TransactionsTransactionDetailPage.js.map +1 -1
  37. package/dist/assethandler/providers/AssetHandlerProvider.js.map +1 -1
  38. package/dist/assethandler/store/assethandlerStore.js +68 -2206
  39. package/dist/assethandler/store/assethandlerStore.js.map +1 -1
  40. package/dist/assethandler/utils/toast.js +33 -0
  41. package/dist/assethandler/utils/toast.js.map +1 -0
  42. package/package.json +5 -4
  43. package/dist/assethandler/pages/AssetsAssetEditPage.js +0 -353
  44. package/dist/assethandler/pages/AssetsAssetEditPage.js.map +0 -1
  45. package/dist/assethandler/pages/AuditTrailPage.js +0 -215
  46. package/dist/assethandler/pages/AuditTrailPage.js.map +0 -1
  47. package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js +0 -177
  48. package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js.map +0 -1
  49. package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js +0 -162
  50. package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js.map +0 -1
  51. package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js +0 -143
  52. package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js.map +0 -1
  53. package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js +0 -163
  54. package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js.map +0 -1
  55. package/dist/assethandler/pages/ReportsReportBuilderPage.js +0 -208
  56. package/dist/assethandler/pages/ReportsReportBuilderPage.js.map +0 -1
  57. package/dist/assethandler/pages/ReportsReportsDashboardPage.js +0 -236
  58. package/dist/assethandler/pages/ReportsReportsDashboardPage.js.map +0 -1
  59. package/dist/assethandler/pages/ReportsReportsListPage.js +0 -144
  60. package/dist/assethandler/pages/ReportsReportsListPage.js.map +0 -1
  61. package/dist/assethandler/pages/SecurityScheduleBackupPage.js +0 -149
  62. package/dist/assethandler/pages/SecurityScheduleBackupPage.js.map +0 -1
  63. package/dist/assethandler/pages/UsersPage.js +0 -208
  64. package/dist/assethandler/pages/UsersPage.js.map +0 -1
  65. package/dist/assethandler/pages/UsersUserCreatePage.js +0 -220
  66. package/dist/assethandler/pages/UsersUserCreatePage.js.map +0 -1
  67. package/dist/assethandler/pages/UsersUserManagementHubPage.js +0 -373
  68. package/dist/assethandler/pages/UsersUserManagementHubPage.js.map +0 -1
  69. package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js +0 -264
  70. package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js.map +0 -1
  71. package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js +0 -206
  72. package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js.map +0 -1
  73. package/dist/assethandler/pages/WorkflowsWorkflowListPage.js +0 -171
  74. package/dist/assethandler/pages/WorkflowsWorkflowListPage.js.map +0 -1
  75. package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js +0 -173
  76. package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsAssetListPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetListPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Checkbox,\n Separator,\n GradientText,\n CTAOverflowMenu,\n IllustratedEmptyState,\n EmphasisPanel,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Filter,\n Plus,\n Download,\n Grid3x3,\n List,\n Table as TableIcon,\n Trash2,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n under_maintenance: 'secondary',\n disposed: 'destructive',\n reserved: 'secondary',\n in_transit: 'outline',\n};\n\nconst conditionColors: Record<string, string> = {\n excellent: 'text-status-success-text bg-status-success-bg-subtle',\n good: 'text-status-info-text bg-status-info-bg-subtle',\n fair: 'text-status-warning-text bg-status-warning-bg-subtle',\n poor: 'text-status-warning-text bg-status-warning-bg-subtle',\n non_functional: 'text-status-error-text bg-status-error-bg-subtle',\n};\n\nexport function AssetsAssetListPage() {\n const { t } = useI18n();\n const { assets } = useAssetHandlerStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState('all');\n const [statusFilter, setStatusFilter] = useState('all');\n const [viewMode, setViewMode] = useState<'table' | 'grid' | 'list'>('table');\n const [selectedAssets, setSelectedAssets] = useState<string[]>([]);\n\n const filteredAssets = useMemo(() => {\n return assets.filter((a) => {\n const matchesSearch =\n searchQuery === '' ||\n a.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.assetTag.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.serialNumber.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesCategory = categoryFilter === 'all' || a.category === categoryFilter;\n const matchesStatus = statusFilter === 'all' || a.status === statusFilter;\n return matchesSearch && matchesCategory && matchesStatus;\n });\n }, [assets, searchQuery, categoryFilter, statusFilter]);\n\n const toggleSelect = (id: string) => {\n setSelectedAssets((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const toggleAll = () => {\n if (selectedAssets.length === filteredAssets.length) {\n setSelectedAssets([]);\n } else {\n setSelectedAssets(filteredAssets.map((a) => a.id));\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tWithFallback(t, 'assethandler.assets.list.title', 'Asset Inventory')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {assets.length} total assets &middot; $\n {assets.reduce((s, a) => s + a.currentValue, 0).toLocaleString()} portfolio value\n </p>\n </div>\n <CTAOverflowMenu\n primary={{\n label: tWithFallback(t, 'assethandler.assets.list.actions.addAsset', 'Add Asset'),\n onSelect: () => {},\n icon: <Plus className=\"h-4 w-4\" />,\n }}\n actions={[\n {\n label: tWithFallback(t, 'assethandler.assets.list.actions.export', 'Export'),\n onSelect: () => {},\n icon: <Download className=\"h-4 w-4\" />,\n },\n ]}\n />\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'assethandler.assets.list.purpose',\n 'The single source of truth for every asset you own or manage. Search, filter and group by category, status or condition to find any item fast, review its value and assignment, then drill in to update, check it in/out or schedule maintenance.'\n )}\n </PagePurpose>\n\n {/* Portfolio summary emphasis */}\n <EmphasisPanel className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.label', 'Total portfolio value')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">\n ${assets.reduce((s, a) => s + a.currentValue, 0).toLocaleString()}\n </p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.tracked', 'Assets tracked')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">{assets.length}</p>\n </div>\n </EmphasisPanel>\n\n {/* Filters Bar */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex flex-col md:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.search.placeholder',\n 'Search by name, asset tag, serial number...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Select value={categoryFilter} onValueChange={setCategoryFilter}>\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.placeholder',\n 'Category'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.all',\n 'All Categories'\n )}\n </SelectItem>\n <SelectItem value=\"electronics\">Electronics</SelectItem>\n <SelectItem value=\"it_hardware\">IT Hardware</SelectItem>\n <SelectItem value=\"furniture\">Furniture</SelectItem>\n <SelectItem value=\"vehicles\">Vehicles</SelectItem>\n <SelectItem value=\"equipment\">Equipment</SelectItem>\n <SelectItem value=\"software\">Software</SelectItem>\n <SelectItem value=\"networking\">Networking</SelectItem>\n <SelectItem value=\"servers\">Servers</SelectItem>\n </SelectContent>\n </Select>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-[160px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.placeholder',\n 'Status'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.all', 'All Statuses')}\n </SelectItem>\n <SelectItem value=\"active\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.active', 'Active')}\n </SelectItem>\n <SelectItem value=\"inactive\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.inactive', 'Inactive')}\n </SelectItem>\n <SelectItem value=\"under_maintenance\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.underMaintenance',\n 'Under Maintenance'\n )}\n </SelectItem>\n <SelectItem value=\"disposed\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.disposed', 'Disposed')}\n </SelectItem>\n <SelectItem value=\"reserved\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.reserved', 'Reserved')}\n </SelectItem>\n <SelectItem value=\"in_transit\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.inTransit',\n 'In Transit'\n )}\n </SelectItem>\n </SelectContent>\n </Select>\n <div className=\"flex gap-1 border rounded-md p-0.5\">\n <Button\n variant={viewMode === 'table' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('table')}\n >\n <TableIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'grid' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('grid')}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('list')}\n >\n <List className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {selectedAssets.length > 0 && (\n <div className=\"flex items-center gap-3 mt-3 pt-3 border-t\">\n <span className=\"text-sm text-text-secondary\">\n {selectedAssets.length}{' '}\n {tWithFallback(t, 'assethandler.assets.list.bulk.selected', 'selected')}\n </span>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setSelectedAssets([])}>\n {tWithFallback(t, 'assethandler.assets.list.bulk.clear', 'Clear')}\n </Button>\n <Button variant=\"destructive\" size=\"sm\">\n <Trash2 className=\"mr-2 h-3 w-3\" />\n {tWithFallback(\n t,\n 'assethandler.assets.list.bulk.deleteSelected',\n 'Delete Selected'\n )}\n </Button>\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Results */}\n <div className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.results.showing', 'Showing')}{' '}\n {filteredAssets.length} {tWithFallback(t, 'assethandler.assets.list.results.of', 'of')}{' '}\n {assets.length} {tWithFallback(t, 'assethandler.assets.list.results.assets', 'assets')}\n </div>\n\n {viewMode === 'table' && (\n <Card>\n <CardContent className=\"p-0\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-bg-sunken/50\">\n <th className=\"p-3 w-10\">\n <Checkbox\n checked={\n selectedAssets.length === filteredAssets.length &&\n filteredAssets.length > 0\n }\n onCheckedChange={toggleAll}\n />\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assetTag', 'Asset Tag')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.name', 'Name')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.category', 'Category')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.status', 'Status')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.condition', 'Condition')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.location', 'Location')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assignedTo', 'Assigned To')}\n </th>\n <th className=\"text-right p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.value', 'Value')}\n </th>\n </tr>\n </thead>\n <tbody>\n {filteredAssets.map((asset) => (\n <tr key={asset.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3\">\n <Checkbox\n checked={selectedAssets.includes(asset.id)}\n onCheckedChange={() => toggleSelect(asset.id)}\n />\n </td>\n <td className=\"p-3 font-mono text-xs\">{asset.assetTag}</td>\n <td className=\"p-3\">\n <div>\n <p className=\"font-medium\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{asset.serialNumber}</p>\n </div>\n </td>\n <td className=\"p-3 capitalize\">{asset.category.replace('_', ' ')}</td>\n <td className=\"p-3\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace('_', ' ')}\n </Badge>\n </td>\n <td className=\"p-3\">\n <span\n className={`inline-flex rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </td>\n <td className=\"p-3 text-xs max-w-[200px] truncate\">{asset.location}</td>\n <td className=\"p-3 text-xs\">{asset.assignedTo}</td>\n <td className=\"p-3 text-right font-medium\">\n ${asset.currentValue.toLocaleString()}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n\n {viewMode === 'grid' && (\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {filteredAssets.map((asset) => (\n <Card key={asset.id} className=\"cursor-pointer hover:shadow-md transition-shadow\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace('_', ' ')}\n </Badge>\n <span className=\"text-xs font-mono text-text-secondary\">{asset.assetTag}</span>\n </div>\n <CardTitle className=\"text-base mt-2\">{asset.name}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.category', 'Category')}\n </span>\n <span className=\"capitalize\">{asset.category.replace('_', ' ')}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.condition', 'Condition')}\n </span>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.department', 'Department')}\n </span>\n <span className=\"text-xs\">{asset.department}</span>\n </div>\n <Separator />\n <div className=\"flex justify-between items-center\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.value', 'Value')}\n </span>\n <span className=\"font-bold text-lg\">\n ${asset.currentValue.toLocaleString()}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {viewMode === 'list' && (\n <div className=\"space-y-2\">\n {filteredAssets.map((asset) => (\n <Card key={asset.id} className=\"cursor-pointer hover:shadow-sm transition-shadow\">\n <CardContent className=\"py-3 px-4\">\n <div className=\"flex items-center gap-4\">\n <Checkbox\n checked={selectedAssets.includes(asset.id)}\n onCheckedChange={() => toggleSelect(asset.id)}\n />\n <div className=\"flex-1 min-w-0 grid grid-cols-6 gap-4 items-center\">\n <div className=\"col-span-2\">\n <p className=\"font-medium text-sm truncate\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">\n {asset.assetTag} &middot; {asset.serialNumber}\n </p>\n </div>\n <div className=\"capitalize text-sm\">{asset.category.replace('_', ' ')}</div>\n <div>\n <Badge variant={statusColors[asset.status] || 'outline'} className=\"text-xs\">\n {asset.status.replace('_', ' ')}\n </Badge>\n </div>\n <div className=\"text-sm text-text-secondary truncate\">{asset.location}</div>\n <div className=\"text-right font-medium\">\n ${asset.currentValue.toLocaleString()}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {filteredAssets.length === 0 && (\n <IllustratedEmptyState\n illustration={\n searchQuery || categoryFilter !== 'all' || statusFilter !== 'all'\n ? 'empty-search'\n : 'empty-data'\n }\n title={tWithFallback(t, 'assethandler.assets.list.empty.title', 'No assets found')}\n description={tWithFallback(\n t,\n 'assethandler.assets.list.empty.description',\n 'Try adjusting your filters or add a new asset to get started.'\n )}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsAssetListPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetListPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n GradientText,\n IllustratedEmptyState,\n EmphasisPanel,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Search, Plus, Grid3x3, List, Table as TableIcon } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n maintenance: 'secondary',\n retired: 'outline',\n disposed: 'destructive',\n};\n\nconst conditionColors: Record<string, string> = {\n excellent: 'text-status-success-text bg-status-success-bg-subtle',\n good: 'text-status-info-text bg-status-info-bg-subtle',\n fair: 'text-status-warning-text bg-status-warning-bg-subtle',\n poor: 'text-status-warning-text bg-status-warning-bg-subtle',\n damaged: 'text-status-error-text bg-status-error-bg-subtle',\n};\n\nexport function AssetsAssetListPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { assets, hydrated } = useAssetHandlerStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState('all');\n const [statusFilter, setStatusFilter] = useState('all');\n const [viewMode, setViewMode] = useState<'table' | 'grid' | 'list'>('table');\n\n const categories = useMemo(\n () => [...new Set(assets.map((a) => a.category).filter(Boolean))].sort(),\n [assets]\n );\n\n const filteredAssets = useMemo(() => {\n return assets.filter((a) => {\n const matchesSearch =\n searchQuery === '' ||\n a.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.assetTag.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.serialNumber.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesCategory = categoryFilter === 'all' || a.category === categoryFilter;\n const matchesStatus = statusFilter === 'all' || a.status === statusFilter;\n return matchesSearch && matchesCategory && matchesStatus;\n });\n }, [assets, searchQuery, categoryFilter, statusFilter]);\n\n const activeCount = assets.filter((a) => a.status === 'active').length;\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tWithFallback(t, 'assethandler.assets.list.title', 'Asset Inventory')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {assets.length}{' '}\n {tWithFallback(t, 'assethandler.assets.list.subtitle.totalAssets', 'total assets')}{' '}\n &middot; {activeCount}{' '}\n {tWithFallback(t, 'assethandler.assets.list.subtitle.active', 'active')}\n </p>\n </div>\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.list.actions.addAsset', 'Add Asset')}\n </Button>\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'assethandler.assets.list.purpose',\n 'The single source of truth for every asset you own or manage. Search, filter and group by category, status or condition to find any item fast, review its assignment, then drill in to update, check it in/out or schedule maintenance.'\n )}\n </PagePurpose>\n\n {/* Inventory summary emphasis */}\n <EmphasisPanel className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.tracked', 'Assets tracked')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">{assets.length}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.categories', 'Categories')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">{categories.length}</p>\n </div>\n </EmphasisPanel>\n\n {/* Filters Bar */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex flex-col md:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.search.placeholder',\n 'Search by name, asset tag, serial number...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Select value={categoryFilter} onValueChange={setCategoryFilter}>\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.placeholder',\n 'Category'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.all',\n 'All Categories'\n )}\n </SelectItem>\n {categories.map((category) => (\n <SelectItem key={category} value={category} className=\"capitalize\">\n {category.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-[160px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.placeholder',\n 'Status'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.all', 'All Statuses')}\n </SelectItem>\n <SelectItem value=\"active\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.active', 'Active')}\n </SelectItem>\n <SelectItem value=\"inactive\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.inactive', 'Inactive')}\n </SelectItem>\n <SelectItem value=\"maintenance\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.maintenance',\n 'Maintenance'\n )}\n </SelectItem>\n <SelectItem value=\"retired\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.retired', 'Retired')}\n </SelectItem>\n <SelectItem value=\"disposed\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.disposed', 'Disposed')}\n </SelectItem>\n </SelectContent>\n </Select>\n <div className=\"flex gap-1 border rounded-md p-0.5\">\n <Button\n variant={viewMode === 'table' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('table')}\n >\n <TableIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'grid' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('grid')}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('list')}\n >\n <List className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Results */}\n <div className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.results.showing', 'Showing')}{' '}\n {filteredAssets.length} {tWithFallback(t, 'assethandler.assets.list.results.of', 'of')}{' '}\n {assets.length} {tWithFallback(t, 'assethandler.assets.list.results.assets', 'assets')}\n </div>\n\n {!hydrated && assets.length === 0 ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ))}\n </div>\n ) : null}\n\n {viewMode === 'table' && filteredAssets.length > 0 && (\n <Card>\n <CardContent className=\"p-0\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-bg-sunken/50\">\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assetTag', 'Asset Tag')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.name', 'Name')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.category', 'Category')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.status', 'Status')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.condition', 'Condition')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.location', 'Location')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assignedTo', 'Assigned To')}\n </th>\n </tr>\n </thead>\n <tbody>\n {filteredAssets.map((asset) => (\n <tr\n key={asset.id}\n className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <td className=\"p-3 font-mono text-xs\">{asset.assetTag}</td>\n <td className=\"p-3\">\n <div>\n <p className=\"font-medium\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{asset.serialNumber}</p>\n </div>\n </td>\n <td className=\"p-3 capitalize\">{asset.category.replace(/_/g, ' ')}</td>\n <td className=\"p-3\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n </td>\n <td className=\"p-3\">\n <span\n className={`inline-flex rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </td>\n <td className=\"p-3 text-xs max-w-[200px] truncate\">\n {asset.location || '—'}\n </td>\n <td className=\"p-3 text-xs\">{asset.assignedTo || '—'}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n\n {viewMode === 'grid' && filteredAssets.length > 0 && (\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {filteredAssets.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n <span className=\"text-xs font-mono text-text-secondary\">{asset.assetTag}</span>\n </div>\n <CardTitle className=\"text-base mt-2\">{asset.name}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.category', 'Category')}\n </span>\n <span className=\"capitalize\">{asset.category.replace(/_/g, ' ')}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.condition', 'Condition')}\n </span>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.assignedTo', 'Assigned To')}\n </span>\n <span className=\"text-xs\">{asset.assignedTo || '—'}</span>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {viewMode === 'list' && filteredAssets.length > 0 && (\n <div className=\"space-y-2\">\n {filteredAssets.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardContent className=\"py-3 px-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"flex-1 min-w-0 grid grid-cols-5 gap-4 items-center\">\n <div className=\"col-span-2\">\n <p className=\"font-medium text-sm truncate\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">\n {asset.assetTag} &middot; {asset.serialNumber}\n </p>\n </div>\n <div className=\"capitalize text-sm\">{asset.category.replace(/_/g, ' ')}</div>\n <div>\n <Badge variant={statusColors[asset.status] || 'outline'} className=\"text-xs\">\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n </div>\n <div className=\"text-sm text-text-secondary truncate\">\n {asset.location || '—'}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {hydrated && filteredAssets.length === 0 && (\n <IllustratedEmptyState\n illustration={\n searchQuery || categoryFilter !== 'all' || statusFilter !== 'all'\n ? 'empty-search'\n : 'empty-data'\n }\n title={tWithFallback(t, 'assethandler.assets.list.empty.title', 'No assets found')}\n description={tWithFallback(\n t,\n 'assethandler.assets.list.empty.description',\n 'Try adjusting your filters or add a new asset to get started.'\n )}\n action={\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.list.actions.addAsset', 'Add Asset')}\n </Button>\n }\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,15 +1,21 @@
1
1
  import { useAssetHandlerStore as e } from "../store/assethandlerStore.js";
2
- import { Building as t, Clock as n, MapPin as r, Navigation as i, Radio as a, RefreshCw as o, Search as s } from "lucide-react";
2
+ import { useMemo as t } from "react";
3
+ import { Building as n, HelpCircle as r, MapPin as i, Radio as a, RefreshCw as o, Search as s } from "lucide-react";
3
4
  import { Badge as c, Button as l, Card as u, CardContent as d, CardDescription as f, CardHeader as p, CardTitle as m, EmphasisPanel as h, GradientText as g, IllustratedEmptyState as _, Input as v, PagePurpose as y } from "@burdenoff/fe-libs/ui";
4
5
  import { jsx as b, jsxs as x } from "react/jsx-runtime";
5
6
  //#region src/assethandler/pages/AssetsAssetTrackingPage.tsx
6
7
  var S = {
7
8
  active: "default",
8
9
  inactive: "outline",
9
- under_maintenance: "secondary"
10
- };
11
- function C() {
12
- let { assetLocations: C } = e(), w = C.reduce((e, t) => (e[t.building] || (e[t.building] = []), e[t.building].push(t), e), {});
10
+ maintenance: "secondary",
11
+ retired: "outline",
12
+ disposed: "destructive"
13
+ }, C = "Unlocated";
14
+ function w() {
15
+ let { assets: w } = e(), T = t(() => w.reduce((e, t) => {
16
+ let n = t.location.trim() || C;
17
+ return e[n] || (e[n] = []), e[n].push(t), e;
18
+ }, {}), [w]), E = w.filter((e) => e.location.trim()).length, D = w.length - E, O = Object.keys(T).filter((e) => e !== C).length;
13
19
  return /* @__PURE__ */ x("div", {
14
20
  className: "space-y-6 p-6",
15
21
  children: [
@@ -21,8 +27,8 @@ function C() {
21
27
  }), /* @__PURE__ */ x("p", {
22
28
  className: "text-sm text-text-secondary",
23
29
  children: [
24
- "Real-time location tracking for ",
25
- C.length,
30
+ "Location overview for ",
31
+ w.length,
26
32
  " assets"
27
33
  ]
28
34
  })] }), /* @__PURE__ */ x("div", {
@@ -38,51 +44,41 @@ function C() {
38
44
  })]
39
45
  }),
40
46
  /* @__PURE__ */ x("div", {
41
- className: "grid gap-4 md:grid-cols-4",
47
+ className: "grid gap-4 md:grid-cols-3",
42
48
  children: [
43
49
  /* @__PURE__ */ b(u, { children: /* @__PURE__ */ x(d, {
44
50
  className: "pt-4",
45
51
  children: [/* @__PURE__ */ x("div", {
46
52
  className: "flex items-center gap-2 text-sm text-text-secondary",
47
- children: [/* @__PURE__ */ b(a, { className: "h-4 w-4" }), "Tracked Assets"]
53
+ children: [/* @__PURE__ */ b(a, { className: "h-4 w-4" }), "Located Assets"]
48
54
  }), /* @__PURE__ */ b("p", {
49
55
  className: "text-2xl font-bold mt-1",
50
- children: C.length
56
+ children: E
51
57
  })]
52
58
  }) }),
53
59
  /* @__PURE__ */ b(u, { children: /* @__PURE__ */ x(d, {
54
60
  className: "pt-4",
55
61
  children: [/* @__PURE__ */ x("div", {
56
62
  className: "flex items-center gap-2 text-sm text-text-secondary",
57
- children: [/* @__PURE__ */ b(t, { className: "h-4 w-4" }), "Buildings"]
63
+ children: [/* @__PURE__ */ b(n, { className: "h-4 w-4" }), "Locations"]
58
64
  }), /* @__PURE__ */ b("p", {
59
65
  className: "text-2xl font-bold mt-1",
60
- children: Object.keys(w).length
66
+ children: O
61
67
  })]
62
68
  }) }),
63
69
  /* @__PURE__ */ b(u, { children: /* @__PURE__ */ x(d, {
64
70
  className: "pt-4",
65
71
  children: [/* @__PURE__ */ x("div", {
66
72
  className: "flex items-center gap-2 text-sm text-text-secondary",
67
- children: [/* @__PURE__ */ b(i, { className: "h-4 w-4" }), "In Field"]
73
+ children: [/* @__PURE__ */ b(r, { className: "h-4 w-4" }), "Unlocated"]
68
74
  }), /* @__PURE__ */ b("p", {
69
75
  className: "text-2xl font-bold mt-1",
70
- children: C.filter((e) => e.building === "Field").length
71
- })]
72
- }) }),
73
- /* @__PURE__ */ b(u, { children: /* @__PURE__ */ x(d, {
74
- className: "pt-4",
75
- children: [/* @__PURE__ */ x("div", {
76
- className: "flex items-center gap-2 text-sm text-text-secondary",
77
- children: [/* @__PURE__ */ b(n, { className: "h-4 w-4" }), "Last Update"]
78
- }), /* @__PURE__ */ b("p", {
79
- className: "text-lg font-bold mt-1",
80
- children: "Just now"
76
+ children: D
81
77
  })]
82
78
  }) })
83
79
  ]
84
80
  }),
85
- /* @__PURE__ */ b(y, { children: "Know where your assets physically are at any moment. See them grouped by building, floor and room (and out in the field), so you can locate equipment fast, spot anything that has moved unexpectedly, and confirm assets are where they should be." }),
81
+ /* @__PURE__ */ b(y, { children: "Know where your assets physically are. See them grouped by location, so you can locate equipment fast, spot assets that still have no recorded location, and confirm items are where they should be." }),
86
82
  /* @__PURE__ */ x("div", {
87
83
  className: "grid gap-6 lg:grid-cols-5",
88
84
  children: [/* @__PURE__ */ x(h, {
@@ -97,7 +93,7 @@ function C() {
97
93
  children: /* @__PURE__ */ x("div", {
98
94
  className: "text-center",
99
95
  children: [
100
- /* @__PURE__ */ b(r, { className: "h-12 w-12 text-text-secondary mx-auto mb-2" }),
96
+ /* @__PURE__ */ b(i, { className: "h-12 w-12 text-text-secondary mx-auto mb-2" }),
101
97
  /* @__PURE__ */ b("p", {
102
98
  className: "text-text-secondary",
103
99
  children: "Interactive map view"
@@ -118,37 +114,37 @@ function C() {
118
114
  placeholder: "Search assets...",
119
115
  className: "pl-9"
120
116
  })]
121
- })] }), /* @__PURE__ */ b(d, { children: C.length === 0 ? /* @__PURE__ */ b(_, {
117
+ })] }), /* @__PURE__ */ b(d, { children: w.length === 0 ? /* @__PURE__ */ b(_, {
122
118
  illustration: "empty-generic",
123
- title: "No tracked assets",
124
- description: "Start tracking an asset's location and it will appear here grouped by building."
119
+ title: "No assets to track",
120
+ description: "Add an asset and give it a location to see it grouped here."
125
121
  }) : /* @__PURE__ */ b("div", {
126
122
  className: "space-y-4",
127
- children: Object.entries(w).map(([e, n]) => /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ x("h4", {
123
+ children: Object.entries(T).map(([e, t]) => /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ x("h4", {
128
124
  className: "text-sm font-medium flex items-center gap-2 mb-2",
129
125
  children: [
130
- /* @__PURE__ */ b(t, { className: "h-3.5 w-3.5" }),
126
+ /* @__PURE__ */ b(n, { className: "h-3.5 w-3.5" }),
131
127
  e,
132
128
  /* @__PURE__ */ b(c, {
133
129
  variant: "secondary",
134
130
  className: "text-[10px]",
135
- children: n.length
131
+ children: t.length
136
132
  })
137
133
  ]
138
134
  }), /* @__PURE__ */ b("div", {
139
135
  className: "space-y-2 ml-5",
140
- children: n.map((e) => /* @__PURE__ */ x("div", {
136
+ children: t.map((e) => /* @__PURE__ */ x("div", {
141
137
  className: "flex items-start gap-3 rounded border p-2.5",
142
- children: [/* @__PURE__ */ b(r, { className: "h-3.5 w-3.5 mt-0.5 text-text-secondary shrink-0" }), /* @__PURE__ */ x("div", {
138
+ children: [/* @__PURE__ */ b(i, { className: "h-3.5 w-3.5 mt-0.5 text-text-secondary shrink-0" }), /* @__PURE__ */ x("div", {
143
139
  className: "flex-1 min-w-0",
144
140
  children: [
145
141
  /* @__PURE__ */ b("p", {
146
142
  className: "text-sm font-medium truncate",
147
- children: e.assetName
143
+ children: e.name
148
144
  }),
149
- /* @__PURE__ */ x("p", {
145
+ /* @__PURE__ */ b("p", {
150
146
  className: "text-xs text-text-secondary",
151
- children: [e.floor === "-" ? "" : `Floor ${e.floor}, `, e.room]
147
+ children: e.assetTag
152
148
  }),
153
149
  /* @__PURE__ */ x("div", {
154
150
  className: "flex items-center gap-2 mt-1",
@@ -156,14 +152,14 @@ function C() {
156
152
  variant: S[e.status] || "outline",
157
153
  className: "text-[10px]",
158
154
  children: e.status.replace("_", " ")
159
- }), /* @__PURE__ */ x("span", {
155
+ }), e.updatedAt ? /* @__PURE__ */ x("span", {
160
156
  className: "text-[10px] text-text-secondary",
161
- children: ["Updated: ", new Date(e.lastUpdated).toLocaleTimeString()]
162
- })]
157
+ children: ["Updated: ", new Date(e.updatedAt).toLocaleDateString()]
158
+ }) : null]
163
159
  })
164
160
  ]
165
161
  })]
166
- }, e.assetId))
162
+ }, e.id))
167
163
  })] }, e))
168
164
  }) })]
169
165
  })]
@@ -172,6 +168,6 @@ function C() {
172
168
  });
173
169
  }
174
170
  //#endregion
175
- export { C as AssetsAssetTrackingPage };
171
+ export { w as AssetsAssetTrackingPage };
176
172
 
177
173
  //# sourceMappingURL=AssetsAssetTrackingPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsAssetTrackingPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetTrackingPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Input,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { MapPin, Search, RefreshCw, Radio, Navigation, Building, Clock } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n under_maintenance: 'secondary',\n};\n\nexport function AssetsAssetTrackingPage() {\n const { assetLocations } = useAssetHandlerStore();\n\n const buildingGroups = assetLocations.reduce<Record<string, typeof assetLocations>>(\n (acc, loc) => {\n if (!acc[loc.building]) acc[loc.building] = [];\n acc[loc.building].push(loc);\n return acc;\n },\n {}\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Asset Tracking</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Real-time location tracking for {assetLocations.length} assets\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <RefreshCw className=\"mr-2 h-4 w-4\" />\n Refresh\n </Button>\n <Button size=\"sm\">\n <Radio className=\"mr-2 h-4 w-4\" />\n Track New Asset\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Radio className=\"h-4 w-4\" />\n Tracked Assets\n </div>\n <p className=\"text-2xl font-bold mt-1\">{assetLocations.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Building className=\"h-4 w-4\" />\n Buildings\n </div>\n <p className=\"text-2xl font-bold mt-1\">{Object.keys(buildingGroups).length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Navigation className=\"h-4 w-4\" />\n In Field\n </div>\n <p className=\"text-2xl font-bold mt-1\">\n {assetLocations.filter((l) => l.building === 'Field').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Clock className=\"h-4 w-4\" />\n Last Update\n </div>\n <p className=\"text-lg font-bold mt-1\">Just now</p>\n </CardContent>\n </Card>\n </div>\n\n <PagePurpose>\n Know where your assets physically are at any moment. See them grouped by building, floor and\n room (and out in the field), so you can locate equipment fast, spot anything that has moved\n unexpectedly, and confirm assets are where they should be.\n </PagePurpose>\n\n <div className=\"grid gap-6 lg:grid-cols-5\">\n <EmphasisPanel className=\"lg:col-span-3\">\n <CardHeader className=\"px-0 pt-0\">\n <CardTitle>Location Map</CardTitle>\n <CardDescription>Geographic distribution of tracked assets</CardDescription>\n </CardHeader>\n <CardContent className=\"px-0 pb-0\">\n <div className=\"bg-bg-sunken rounded-lg h-80 flex items-center justify-center border-2 border-dashed\">\n <div className=\"text-center\">\n <MapPin className=\"h-12 w-12 text-text-secondary mx-auto mb-2\" />\n <p className=\"text-text-secondary\">Interactive map view</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n Map integration would render here\n </p>\n </div>\n </div>\n </CardContent>\n </EmphasisPanel>\n\n <Card className=\"lg:col-span-2\">\n <CardHeader>\n <CardTitle>Asset Locations</CardTitle>\n <div className=\"relative mt-2\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input placeholder=\"Search assets...\" className=\"pl-9\" />\n </div>\n </CardHeader>\n <CardContent>\n {assetLocations.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No tracked assets\"\n description=\"Start tracking an asset's location and it will appear here grouped by building.\"\n />\n ) : (\n <div className=\"space-y-4\">\n {Object.entries(buildingGroups).map(([building, locations]) => (\n <div key={building}>\n <h4 className=\"text-sm font-medium flex items-center gap-2 mb-2\">\n <Building className=\"h-3.5 w-3.5\" />\n {building}\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {locations.length}\n </Badge>\n </h4>\n <div className=\"space-y-2 ml-5\">\n {locations.map((loc) => (\n <div\n key={loc.assetId}\n className=\"flex items-start gap-3 rounded border p-2.5\"\n >\n <MapPin className=\"h-3.5 w-3.5 mt-0.5 text-text-secondary shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{loc.assetName}</p>\n <p className=\"text-xs text-text-secondary\">\n {loc.floor !== '-' ? `Floor ${loc.floor}, ` : ''}\n {loc.room}\n </p>\n <div className=\"flex items-center gap-2 mt-1\">\n <Badge\n variant={statusColors[loc.status] || 'outline'}\n className=\"text-[10px]\"\n >\n {loc.status.replace('_', ' ')}\n </Badge>\n <span className=\"text-[10px] text-text-secondary\">\n Updated: {new Date(loc.lastUpdated).toLocaleTimeString()}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsAssetTrackingPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetTrackingPage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Input,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { MapPin, Search, RefreshCw, Radio, Building, HelpCircle } from 'lucide-react';\nimport { useAssetHandlerStore, type Asset } from '../store/assethandlerStore';\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n maintenance: 'secondary',\n retired: 'outline',\n disposed: 'destructive',\n};\n\nconst UNLOCATED = 'Unlocated';\n\nexport function AssetsAssetTrackingPage() {\n const { assets } = useAssetHandlerStore();\n\n const locationGroups = useMemo(\n () =>\n assets.reduce<Record<string, Asset[]>>((acc, asset) => {\n const key = asset.location.trim() || UNLOCATED;\n if (!acc[key]) acc[key] = [];\n acc[key].push(asset);\n return acc;\n }, {}),\n [assets]\n );\n\n const locatedCount = assets.filter((a) => a.location.trim()).length;\n const unlocatedCount = assets.length - locatedCount;\n const locationCount = Object.keys(locationGroups).filter((k) => k !== UNLOCATED).length;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Asset Tracking</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Location overview for {assets.length} assets\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <RefreshCw className=\"mr-2 h-4 w-4\" />\n Refresh\n </Button>\n <Button size=\"sm\">\n <Radio className=\"mr-2 h-4 w-4\" />\n Track New Asset\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Radio className=\"h-4 w-4\" />\n Located Assets\n </div>\n <p className=\"text-2xl font-bold mt-1\">{locatedCount}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Building className=\"h-4 w-4\" />\n Locations\n </div>\n <p className=\"text-2xl font-bold mt-1\">{locationCount}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <HelpCircle className=\"h-4 w-4\" />\n Unlocated\n </div>\n <p className=\"text-2xl font-bold mt-1\">{unlocatedCount}</p>\n </CardContent>\n </Card>\n </div>\n\n <PagePurpose>\n Know where your assets physically are. See them grouped by location, so you can locate\n equipment fast, spot assets that still have no recorded location, and confirm items are\n where they should be.\n </PagePurpose>\n\n <div className=\"grid gap-6 lg:grid-cols-5\">\n <EmphasisPanel className=\"lg:col-span-3\">\n <CardHeader className=\"px-0 pt-0\">\n <CardTitle>Location Map</CardTitle>\n <CardDescription>Geographic distribution of tracked assets</CardDescription>\n </CardHeader>\n <CardContent className=\"px-0 pb-0\">\n <div className=\"bg-bg-sunken rounded-lg h-80 flex items-center justify-center border-2 border-dashed\">\n <div className=\"text-center\">\n <MapPin className=\"h-12 w-12 text-text-secondary mx-auto mb-2\" />\n <p className=\"text-text-secondary\">Interactive map view</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n Map integration would render here\n </p>\n </div>\n </div>\n </CardContent>\n </EmphasisPanel>\n\n <Card className=\"lg:col-span-2\">\n <CardHeader>\n <CardTitle>Asset Locations</CardTitle>\n <div className=\"relative mt-2\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input placeholder=\"Search assets...\" className=\"pl-9\" />\n </div>\n </CardHeader>\n <CardContent>\n {assets.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No assets to track\"\n description=\"Add an asset and give it a location to see it grouped here.\"\n />\n ) : (\n <div className=\"space-y-4\">\n {Object.entries(locationGroups).map(([location, groupAssets]) => (\n <div key={location}>\n <h4 className=\"text-sm font-medium flex items-center gap-2 mb-2\">\n <Building className=\"h-3.5 w-3.5\" />\n {location}\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {groupAssets.length}\n </Badge>\n </h4>\n <div className=\"space-y-2 ml-5\">\n {groupAssets.map((asset) => (\n <div\n key={asset.id}\n className=\"flex items-start gap-3 rounded border p-2.5\"\n >\n <MapPin className=\"h-3.5 w-3.5 mt-0.5 text-text-secondary shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{asset.assetTag}</p>\n <div className=\"flex items-center gap-2 mt-1\">\n <Badge\n variant={statusColors[asset.status] || 'outline'}\n className=\"text-[10px]\"\n >\n {asset.status.replace('_', ' ')}\n </Badge>\n {asset.updatedAt ? (\n <span className=\"text-[10px] text-text-secondary\">\n Updated: {new Date(asset.updatedAt).toLocaleDateString()}\n </span>\n ) : null}\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}