@burdenoff/microfe-assethandler 2026.608.1 → 2026.624.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assethandler/pages/AiPredictionsPage.js +8 -8
- package/dist/assethandler/pages/AiPredictionsPage.js.map +1 -1
- package/dist/assethandler/pages/AnalyticsPage.js +32 -32
- package/dist/assethandler/pages/AnalyticsPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCategoriesPage.js +8 -8
- package/dist/assethandler/pages/AssetsAssetCategoriesPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js +12 -12
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.js +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.js +15 -15
- package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetEditPage.js +2 -2
- package/dist/assethandler/pages/AssetsAssetEditPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetListPage.js +14 -14
- package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetTrackingPage.js +13 -13
- package/dist/assethandler/pages/AssetsAssetTrackingPage.js.map +1 -1
- package/dist/assethandler/pages/AuditTrailPage.js +14 -14
- package/dist/assethandler/pages/AuditTrailPage.js.map +1 -1
- package/dist/assethandler/pages/CmdbBrowserPage.js +4 -4
- package/dist/assethandler/pages/CmdbBrowserPage.js.map +1 -1
- package/dist/assethandler/pages/DashboardPage.js +21 -21
- package/dist/assethandler/pages/DashboardPage.js.map +1 -1
- package/dist/assethandler/pages/DigitalTwinPage.js +6 -6
- package/dist/assethandler/pages/DigitalTwinPage.js.map +1 -1
- package/dist/assethandler/pages/DiscoveryJobsPage.js +6 -6
- package/dist/assethandler/pages/DiscoveryJobsPage.js.map +1 -1
- package/dist/assethandler/pages/EsgDashboardPage.js +8 -8
- package/dist/assethandler/pages/EsgDashboardPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceBudgetDetailPage.js +12 -12
- package/dist/assethandler/pages/FinanceBudgetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceFinanceHubPage.js +15 -15
- package/dist/assethandler/pages/FinanceFinanceHubPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceInvoiceDetailPage.js +10 -10
- package/dist/assethandler/pages/FinanceInvoiceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/IotDevicesPage.js +5 -5
- package/dist/assethandler/pages/IotDevicesPage.js.map +1 -1
- package/dist/assethandler/pages/ItilChangeDetailPage.js +15 -15
- package/dist/assethandler/pages/ItilChangeDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilChangeManagementPage.js +8 -8
- package/dist/assethandler/pages/ItilChangeManagementPage.js.map +1 -1
- package/dist/assethandler/pages/ItilIncidentDetailPage.js +15 -15
- package/dist/assethandler/pages/ItilIncidentDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilIncidentManagementPage.js +9 -9
- package/dist/assethandler/pages/ItilIncidentManagementPage.js.map +1 -1
- package/dist/assethandler/pages/ItilItilhubPage.js +15 -15
- package/dist/assethandler/pages/ItilItilhubPage.js.map +1 -1
- package/dist/assethandler/pages/ItilProblemDetailPage.js +12 -12
- package/dist/assethandler/pages/ItilProblemDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilProblemManagementPage.js +8 -8
- package/dist/assethandler/pages/ItilProblemManagementPage.js.map +1 -1
- package/dist/assethandler/pages/KnowledgeBasePage.js +7 -7
- package/dist/assethandler/pages/KnowledgeBasePage.js.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js +8 -8
- package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js +9 -9
- package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js +10 -10
- package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js +5 -5
- package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js +4 -4
- package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js +4 -4
- package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js +17 -17
- package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsOperationsHubPage.js +10 -10
- package/dist/assethandler/pages/OperationsOperationsHubPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js +12 -12
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
- package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js +14 -14
- package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js.map +1 -1
- package/dist/assethandler/pages/ProvenancePage.js +7 -7
- package/dist/assethandler/pages/ProvenancePage.js.map +1 -1
- package/dist/assethandler/pages/ReportsReportBuilderPage.js +3 -3
- package/dist/assethandler/pages/ReportsReportBuilderPage.js.map +1 -1
- package/dist/assethandler/pages/ReportsReportsDashboardPage.js +9 -9
- package/dist/assethandler/pages/ReportsReportsDashboardPage.js.map +1 -1
- package/dist/assethandler/pages/ReportsReportsListPage.js +5 -5
- package/dist/assethandler/pages/ReportsReportsListPage.js.map +1 -1
- package/dist/assethandler/pages/SamLicensesPage.js +4 -4
- package/dist/assethandler/pages/SamLicensesPage.js.map +1 -1
- package/dist/assethandler/pages/SecurityComplianceDetailPage.js +8 -8
- package/dist/assethandler/pages/SecurityComplianceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecurityPolicyDetailPage.js +9 -9
- package/dist/assethandler/pages/SecurityPolicyDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecurityScheduleBackupPage.js +11 -11
- package/dist/assethandler/pages/SecurityScheduleBackupPage.js.map +1 -1
- package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js +8 -8
- package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecuritySecurityHubPage.js +17 -17
- package/dist/assethandler/pages/SecuritySecurityHubPage.js.map +1 -1
- package/dist/assethandler/pages/TransactionsTransactionDetailPage.js +22 -22
- package/dist/assethandler/pages/TransactionsTransactionDetailPage.js.map +1 -1
- package/dist/assethandler/pages/TransactionsTransactionListPage.js +5 -5
- package/dist/assethandler/pages/TransactionsTransactionListPage.js.map +1 -1
- package/dist/assethandler/pages/UsersPage.js +5 -5
- package/dist/assethandler/pages/UsersPage.js.map +1 -1
- package/dist/assethandler/pages/UsersUserCreatePage.js +1 -1
- package/dist/assethandler/pages/UsersUserCreatePage.js.map +1 -1
- package/dist/assethandler/pages/UsersUserManagementHubPage.js +8 -8
- package/dist/assethandler/pages/UsersUserManagementHubPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js +8 -8
- package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js +9 -9
- package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowListPage.js +7 -7
- package/dist/assethandler/pages/WorkflowsWorkflowListPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js +10 -10
- package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -36,7 +36,7 @@ function l() {
|
|
|
36
36
|
children: [/* @__PURE__ */ n(t, { className: "h-6 w-6" }), " AI Predictions"]
|
|
37
37
|
}),
|
|
38
38
|
/* @__PURE__ */ n("p", {
|
|
39
|
-
className: "text-
|
|
39
|
+
className: "text-text-secondary",
|
|
40
40
|
children: "Predictive maintenance and asset risk scoring are enabled through real backend APIs."
|
|
41
41
|
}),
|
|
42
42
|
/* @__PURE__ */ r("form", {
|
|
@@ -59,11 +59,11 @@ function l() {
|
|
|
59
59
|
onChange: (e) => l(e.target.value)
|
|
60
60
|
}),
|
|
61
61
|
/* @__PURE__ */ n("div", {
|
|
62
|
-
className: "text-sm text-
|
|
62
|
+
className: "text-sm text-text-secondary",
|
|
63
63
|
children: "Prediction Type: maintenance-risk"
|
|
64
64
|
}),
|
|
65
65
|
/* @__PURE__ */ n("button", {
|
|
66
|
-
className: "rounded-md bg-primary px-3 py-2 text-primary-
|
|
66
|
+
className: "rounded-md bg-action-primary-bg px-3 py-2 text-action-primary-text",
|
|
67
67
|
disabled: m,
|
|
68
68
|
type: "submit",
|
|
69
69
|
children: m ? "Running..." : "Run Prediction"
|
|
@@ -74,18 +74,18 @@ function l() {
|
|
|
74
74
|
className: "grid gap-3 md:grid-cols-2",
|
|
75
75
|
children: [
|
|
76
76
|
d && h.length === 0 ? /* @__PURE__ */ n("p", {
|
|
77
|
-
className: "text-sm text-
|
|
77
|
+
className: "text-sm text-text-secondary",
|
|
78
78
|
children: "Loading predictions..."
|
|
79
79
|
}) : null,
|
|
80
80
|
!d && h.length === 0 ? /* @__PURE__ */ n("p", {
|
|
81
|
-
className: "text-sm text-
|
|
81
|
+
className: "text-sm text-text-secondary",
|
|
82
82
|
children: "No AI predictions available yet."
|
|
83
83
|
}) : null,
|
|
84
84
|
h.map((e) => /* @__PURE__ */ r("article", {
|
|
85
85
|
className: "rounded-lg border p-4",
|
|
86
86
|
children: [
|
|
87
87
|
/* @__PURE__ */ r("p", {
|
|
88
|
-
className: "text-xs uppercase tracking-wide text-
|
|
88
|
+
className: "text-xs uppercase tracking-wide text-text-secondary",
|
|
89
89
|
children: [
|
|
90
90
|
e.predictionType,
|
|
91
91
|
" • ",
|
|
@@ -101,7 +101,7 @@ function l() {
|
|
|
101
101
|
]
|
|
102
102
|
}),
|
|
103
103
|
/* @__PURE__ */ r("p", {
|
|
104
|
-
className: "mt-1 text-sm text-
|
|
104
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
105
105
|
children: [
|
|
106
106
|
"Confidence ",
|
|
107
107
|
(e.confidence * 100).toFixed(1),
|
|
@@ -113,7 +113,7 @@ function l() {
|
|
|
113
113
|
children: e.recommendation
|
|
114
114
|
}),
|
|
115
115
|
/* @__PURE__ */ r("p", {
|
|
116
|
-
className: "mt-2 text-xs text-
|
|
116
|
+
className: "mt-2 text-xs text-text-secondary",
|
|
117
117
|
children: [
|
|
118
118
|
e.modelVersion,
|
|
119
119
|
" • ",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiPredictionsPage.js","names":[],"sources":["../../../src/assethandler/pages/AiPredictionsPage.tsx"],"sourcesContent":["import { BrainCircuit } from 'lucide-react';\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\n\nconst AI_PREDICTIONS_QUERY = gql`\n query AssetHandlerAiPredictions {\n aiPredictions {\n id\n assetId\n predictionType\n score\n confidence\n recommendation\n generatedAt\n modelVersion\n }\n }\n`;\n\nconst REQUEST_AI_PREDICTION_MUTATION = gql`\n mutation AssetHandlerRequestAiPrediction($input: RequestAIPredictionInput!) {\n requestAIPrediction(input: $input) {\n id\n }\n }\n`;\n\nexport function AiPredictionsPage() {\n const [assetId, setAssetId] = useState('AST-001');\n\n const { data, loading, refetch } = useQuery<{\n aiPredictions: Array<{\n id: string;\n assetId: string;\n predictionType: string;\n score: number;\n confidence: number;\n recommendation: string;\n generatedAt: string;\n modelVersion: string;\n }>;\n }>(AI_PREDICTIONS_QUERY, { fetchPolicy: 'cache-and-network' });\n\n const [requestPrediction, { loading: requesting }] = useMutation(REQUEST_AI_PREDICTION_MUTATION, {\n onCompleted: () => {\n void refetch();\n },\n });\n\n const predictions = data?.aiPredictions ?? [];\n\n return (\n <div className=\"space-y-4 p-4\">\n <h1 className=\"flex items-center gap-2 text-2xl font-semibold\">\n <BrainCircuit className=\"h-6 w-6\" /> AI Predictions\n </h1>\n <p className=\"text-
|
|
1
|
+
{"version":3,"file":"AiPredictionsPage.js","names":[],"sources":["../../../src/assethandler/pages/AiPredictionsPage.tsx"],"sourcesContent":["import { BrainCircuit } from 'lucide-react';\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\n\nconst AI_PREDICTIONS_QUERY = gql`\n query AssetHandlerAiPredictions {\n aiPredictions {\n id\n assetId\n predictionType\n score\n confidence\n recommendation\n generatedAt\n modelVersion\n }\n }\n`;\n\nconst REQUEST_AI_PREDICTION_MUTATION = gql`\n mutation AssetHandlerRequestAiPrediction($input: RequestAIPredictionInput!) {\n requestAIPrediction(input: $input) {\n id\n }\n }\n`;\n\nexport function AiPredictionsPage() {\n const [assetId, setAssetId] = useState('AST-001');\n\n const { data, loading, refetch } = useQuery<{\n aiPredictions: Array<{\n id: string;\n assetId: string;\n predictionType: string;\n score: number;\n confidence: number;\n recommendation: string;\n generatedAt: string;\n modelVersion: string;\n }>;\n }>(AI_PREDICTIONS_QUERY, { fetchPolicy: 'cache-and-network' });\n\n const [requestPrediction, { loading: requesting }] = useMutation(REQUEST_AI_PREDICTION_MUTATION, {\n onCompleted: () => {\n void refetch();\n },\n });\n\n const predictions = data?.aiPredictions ?? [];\n\n return (\n <div className=\"space-y-4 p-4\">\n <h1 className=\"flex items-center gap-2 text-2xl font-semibold\">\n <BrainCircuit className=\"h-6 w-6\" /> AI Predictions\n </h1>\n <p className=\"text-text-secondary\">\n Predictive maintenance and asset risk scoring are enabled through real backend APIs.\n </p>\n <form\n className=\"grid gap-3 rounded-lg border p-4 md:grid-cols-3\"\n onSubmit={(event) => {\n event.preventDefault();\n void requestPrediction({\n variables: {\n input: {\n assetId,\n predictionType: 'maintenance-risk',\n featureVector: {\n runtimeHours: 10240,\n lastIncidentDaysAgo: 9,\n temperatureVariance: 0.23,\n },\n },\n },\n });\n }}\n >\n <input\n className=\"rounded-md border px-3 py-2\"\n value={assetId}\n onChange={(event) => setAssetId(event.target.value)}\n />\n <div className=\"text-sm text-text-secondary\">Prediction Type: maintenance-risk</div>\n <button\n className=\"rounded-md bg-action-primary-bg px-3 py-2 text-action-primary-text\"\n disabled={requesting}\n type=\"submit\"\n >\n {requesting ? 'Running...' : 'Run Prediction'}\n </button>\n </form>\n <div className=\"grid gap-3 md:grid-cols-2\">\n {loading && predictions.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">Loading predictions...</p>\n ) : null}\n {!loading && predictions.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">No AI predictions available yet.</p>\n ) : null}\n {predictions.map((prediction) => (\n <article key={prediction.id} className=\"rounded-lg border p-4\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {prediction.predictionType} • {prediction.assetId}\n </p>\n <h2 className=\"mt-1 text-base font-semibold\">\n Risk score {(prediction.score * 100).toFixed(1)}%\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Confidence {(prediction.confidence * 100).toFixed(1)}%\n </p>\n <p className=\"mt-2 text-sm\">{prediction.recommendation}</p>\n <p className=\"mt-2 text-xs text-text-secondary\">\n {prediction.modelVersion} • {new Date(prediction.generatedAt).toLocaleString()}\n </p>\n </article>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;AAKA,IAAM,IAAuB,CAAG;;;;;;;;;;;;;GAe1B,IAAiC,CAAG;;;;;;;AAQ1C,SAAgB,IAAoB;CAClC,IAAM,CAAC,GAAS,KAAc,EAAS,UAAU,EAE3C,EAAE,SAAM,YAAS,eAAY,EAWhC,GAAsB,EAAE,aAAa,qBAAqB,CAAC,EAExD,CAAC,GAAmB,EAAE,SAAS,OAAgB,EAAY,GAAgC,EAC/F,mBAAmB;AACZ,KAAS;IAEjB,CAAC,EAEI,IAAc,GAAM,iBAAiB,EAAE;AAE7C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,MAAD;IAAI,WAAU;cAAd,CACE,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,EAAA,kBACjC;;GACL,kBAAC,KAAD;IAAG,WAAU;cAAsB;IAE/B,CAAA;GACJ,kBAAC,QAAD;IACE,WAAU;IACV,WAAW,MAAU;AAEd,KADL,EAAM,gBAAgB,EACjB,EAAkB,EACrB,WAAW,EACT,OAAO;MACL;MACA,gBAAgB;MAChB,eAAe;OACb,cAAc;OACd,qBAAqB;OACrB,qBAAqB;OACtB;MACF,EACF,EACF,CAAC;;cAhBN;KAmBE,kBAAC,SAAD;MACE,WAAU;MACV,OAAO;MACP,WAAW,MAAU,EAAW,EAAM,OAAO,MAAM;MACnD,CAAA;KACF,kBAAC,OAAD;MAAK,WAAU;gBAA8B;MAAuC,CAAA;KACpF,kBAAC,UAAD;MACE,WAAU;MACV,UAAU;MACV,MAAK;gBAEJ,IAAa,eAAe;MACtB,CAAA;KACJ;;GACP,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,KAAW,EAAY,WAAW,IACjC,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAA0B,CAAA,GACnE;KACH,CAAC,KAAW,EAAY,WAAW,IAClC,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAAoC,CAAA,GAC7E;KACH,EAAY,KAAK,MAChB,kBAAC,WAAD;MAA6B,WAAU;gBAAvC;OACE,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAW;SAAe;SAAI,EAAW;SACxC;;OACJ,kBAAC,MAAD;QAAI,WAAU;kBAAd;SAA6C;UAC9B,EAAW,QAAQ,KAAK,QAAQ,EAAE;SAAC;SAC7C;;OACL,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAAgD;UACjC,EAAW,aAAa,KAAK,QAAQ,EAAE;SAAC;SACnD;;OACJ,kBAAC,KAAD;QAAG,WAAU;kBAAgB,EAAW;QAAmB,CAAA;OAC3D,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAW;SAAa;SAAI,IAAI,KAAK,EAAW,YAAY,CAAC,gBAAgB;SAC5E;;OACI;QAdI,EAAW,GAcf,CACV;KACE;;GACF"}
|
|
@@ -23,7 +23,7 @@ function w() {
|
|
|
23
23
|
className: "text-3xl font-bold",
|
|
24
24
|
children: "Analytics & Business Intelligence"
|
|
25
25
|
}), /* @__PURE__ */ S("p", {
|
|
26
|
-
className: "text-sm text-
|
|
26
|
+
className: "text-sm text-text-secondary mt-1",
|
|
27
27
|
children: "Comprehensive asset management analytics and insights"
|
|
28
28
|
})] }), /* @__PURE__ */ C("div", {
|
|
29
29
|
className: "flex gap-2",
|
|
@@ -31,7 +31,7 @@ function w() {
|
|
|
31
31
|
/* @__PURE__ */ C("select", {
|
|
32
32
|
value: A,
|
|
33
33
|
onChange: (e) => j(e.target.value),
|
|
34
|
-
className: "rounded-md border border-
|
|
34
|
+
className: "rounded-md border border-border-default bg-bg-surface px-3 py-1.5 text-sm",
|
|
35
35
|
children: [
|
|
36
36
|
/* @__PURE__ */ S("option", {
|
|
37
37
|
value: "7d",
|
|
@@ -95,12 +95,12 @@ function w() {
|
|
|
95
95
|
children: [/* @__PURE__ */ S(g, {
|
|
96
96
|
className: "text-sm font-medium",
|
|
97
97
|
children: "Total Portfolio Value"
|
|
98
|
-
}), /* @__PURE__ */ S(o, { className: "h-4 w-4 text-
|
|
98
|
+
}), /* @__PURE__ */ S(o, { className: "h-4 w-4 text-text-secondary" })]
|
|
99
99
|
}), /* @__PURE__ */ C(p, { children: [/* @__PURE__ */ C("div", {
|
|
100
100
|
className: "text-2xl font-bold",
|
|
101
101
|
children: ["$", T.totalValue.toLocaleString()]
|
|
102
102
|
}), /* @__PURE__ */ C("p", {
|
|
103
|
-
className: "text-xs text-
|
|
103
|
+
className: "text-xs text-text-secondary flex items-center mt-1",
|
|
104
104
|
children: [
|
|
105
105
|
/* @__PURE__ */ S(r, { className: "mr-1 h-3 w-3 text-green-600" }),
|
|
106
106
|
/* @__PURE__ */ S("span", {
|
|
@@ -115,12 +115,12 @@ function w() {
|
|
|
115
115
|
children: [/* @__PURE__ */ S(g, {
|
|
116
116
|
className: "text-sm font-medium",
|
|
117
117
|
children: "Total Depreciation"
|
|
118
|
-
}), /* @__PURE__ */ S(l, { className: "h-4 w-4 text-
|
|
118
|
+
}), /* @__PURE__ */ S(l, { className: "h-4 w-4 text-text-secondary" })]
|
|
119
119
|
}), /* @__PURE__ */ C(p, { children: [/* @__PURE__ */ C("div", {
|
|
120
120
|
className: "text-2xl font-bold text-red-600",
|
|
121
121
|
children: ["-$", P.toLocaleString()]
|
|
122
122
|
}), /* @__PURE__ */ C("p", {
|
|
123
|
-
className: "text-xs text-
|
|
123
|
+
className: "text-xs text-text-secondary",
|
|
124
124
|
children: [F, "% of original value"]
|
|
125
125
|
})] })] }),
|
|
126
126
|
/* @__PURE__ */ C(f, { children: [/* @__PURE__ */ C(h, {
|
|
@@ -128,12 +128,12 @@ function w() {
|
|
|
128
128
|
children: [/* @__PURE__ */ S(g, {
|
|
129
129
|
className: "text-sm font-medium",
|
|
130
130
|
children: "Total Assets"
|
|
131
|
-
}), /* @__PURE__ */ S(a, { className: "h-4 w-4 text-
|
|
131
|
+
}), /* @__PURE__ */ S(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
132
132
|
}), /* @__PURE__ */ C(p, { children: [/* @__PURE__ */ S("div", {
|
|
133
133
|
className: "text-2xl font-bold",
|
|
134
134
|
children: T.totalAssets
|
|
135
135
|
}), /* @__PURE__ */ C("p", {
|
|
136
|
-
className: "text-xs text-
|
|
136
|
+
className: "text-xs text-text-secondary",
|
|
137
137
|
children: [w.filter((e) => e.status === "active").length, " currently active"]
|
|
138
138
|
})] })] }),
|
|
139
139
|
/* @__PURE__ */ C(f, { children: [/* @__PURE__ */ C(h, {
|
|
@@ -141,12 +141,12 @@ function w() {
|
|
|
141
141
|
children: [/* @__PURE__ */ S(g, {
|
|
142
142
|
className: "text-sm font-medium",
|
|
143
143
|
children: "Avg. Asset Value"
|
|
144
|
-
}), /* @__PURE__ */ S(i, { className: "h-4 w-4 text-
|
|
144
|
+
}), /* @__PURE__ */ S(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
145
145
|
}), /* @__PURE__ */ C(p, { children: [/* @__PURE__ */ C("div", {
|
|
146
146
|
className: "text-2xl font-bold",
|
|
147
147
|
children: ["$", I.toLocaleString()]
|
|
148
148
|
}), /* @__PURE__ */ S("p", {
|
|
149
|
-
className: "text-xs text-
|
|
149
|
+
className: "text-xs text-text-secondary",
|
|
150
150
|
children: "Across all categories"
|
|
151
151
|
})] })] })
|
|
152
152
|
]
|
|
@@ -168,7 +168,7 @@ function w() {
|
|
|
168
168
|
className: "font-medium capitalize",
|
|
169
169
|
children: e
|
|
170
170
|
}), /* @__PURE__ */ C("span", {
|
|
171
|
-
className: "text-
|
|
171
|
+
className: "text-text-secondary",
|
|
172
172
|
children: [
|
|
173
173
|
t.count,
|
|
174
174
|
" · $",
|
|
@@ -177,9 +177,9 @@ function w() {
|
|
|
177
177
|
]
|
|
178
178
|
})]
|
|
179
179
|
}), /* @__PURE__ */ S("div", {
|
|
180
|
-
className: "h-2 rounded-full bg-
|
|
180
|
+
className: "h-2 rounded-full bg-bg-sunken overflow-hidden",
|
|
181
181
|
children: /* @__PURE__ */ S("div", {
|
|
182
|
-
className: "h-full rounded-full bg-primary",
|
|
182
|
+
className: "h-full rounded-full bg-action-primary-bg",
|
|
183
183
|
style: { width: `${n}%` }
|
|
184
184
|
})
|
|
185
185
|
})]
|
|
@@ -204,9 +204,9 @@ function w() {
|
|
|
204
204
|
}), /* @__PURE__ */ C("div", {
|
|
205
205
|
className: "flex items-center gap-3",
|
|
206
206
|
children: [/* @__PURE__ */ S("div", {
|
|
207
|
-
className: "h-2 w-24 rounded-full bg-
|
|
207
|
+
className: "h-2 w-24 rounded-full bg-bg-sunken overflow-hidden",
|
|
208
208
|
children: /* @__PURE__ */ S("div", {
|
|
209
|
-
className: "h-full rounded-full bg-primary",
|
|
209
|
+
className: "h-full rounded-full bg-action-primary-bg",
|
|
210
210
|
style: { width: `${n}%` }
|
|
211
211
|
})
|
|
212
212
|
}), /* @__PURE__ */ S("span", {
|
|
@@ -226,7 +226,7 @@ function w() {
|
|
|
226
226
|
children: Object.entries(z).sort((e, t) => t[1].count - e[1].count).slice(0, 5).map(([e, t]) => /* @__PURE__ */ C("div", {
|
|
227
227
|
className: "flex items-center justify-between text-sm",
|
|
228
228
|
children: [/* @__PURE__ */ S("span", { children: e }), /* @__PURE__ */ C("span", {
|
|
229
|
-
className: "text-
|
|
229
|
+
className: "text-text-secondary",
|
|
230
230
|
children: [t.count, " assets"]
|
|
231
231
|
})]
|
|
232
232
|
}, e))
|
|
@@ -241,7 +241,7 @@ function w() {
|
|
|
241
241
|
className: "flex-1 flex flex-col items-center gap-1",
|
|
242
242
|
children: [
|
|
243
243
|
/* @__PURE__ */ C("span", {
|
|
244
|
-
className: "text-[10px] text-
|
|
244
|
+
className: "text-[10px] text-text-secondary",
|
|
245
245
|
children: [
|
|
246
246
|
"$",
|
|
247
247
|
(e.value / 1e6).toFixed(2),
|
|
@@ -249,11 +249,11 @@ function w() {
|
|
|
249
249
|
]
|
|
250
250
|
}),
|
|
251
251
|
/* @__PURE__ */ S("div", {
|
|
252
|
-
className: "w-full bg-primary/80 rounded-t",
|
|
252
|
+
className: "w-full bg-action-primary-bg/80 rounded-t",
|
|
253
253
|
style: { height: `${n}%` }
|
|
254
254
|
}),
|
|
255
255
|
/* @__PURE__ */ S("span", {
|
|
256
|
-
className: "text-[10px] text-
|
|
256
|
+
className: "text-[10px] text-text-secondary",
|
|
257
257
|
children: e.month.replace(" 20", "'")
|
|
258
258
|
})
|
|
259
259
|
]
|
|
@@ -279,7 +279,7 @@ function w() {
|
|
|
279
279
|
className: "text-2xl font-bold",
|
|
280
280
|
children: E.length
|
|
281
281
|
}), /* @__PURE__ */ C("p", {
|
|
282
|
-
className: "text-xs text-
|
|
282
|
+
className: "text-xs text-text-secondary",
|
|
283
283
|
children: [
|
|
284
284
|
"$",
|
|
285
285
|
E.reduce((e, t) => e + Math.abs(t.amount), 0).toLocaleString(),
|
|
@@ -296,7 +296,7 @@ function w() {
|
|
|
296
296
|
className: "text-2xl font-bold",
|
|
297
297
|
children: ["$", U.toLocaleString()]
|
|
298
298
|
}), /* @__PURE__ */ C("p", {
|
|
299
|
-
className: "text-xs text-
|
|
299
|
+
className: "text-xs text-text-secondary",
|
|
300
300
|
children: [O.length, " maintenance records"]
|
|
301
301
|
})] })] }),
|
|
302
302
|
/* @__PURE__ */ C(f, { children: [/* @__PURE__ */ S(h, {
|
|
@@ -309,7 +309,7 @@ function w() {
|
|
|
309
309
|
className: "text-2xl font-bold",
|
|
310
310
|
children: T.acquisitionTrend.reduce((e, t) => e + t.count, 0)
|
|
311
311
|
}), /* @__PURE__ */ C("p", {
|
|
312
|
-
className: "text-xs text-
|
|
312
|
+
className: "text-xs text-text-secondary",
|
|
313
313
|
children: [
|
|
314
314
|
"$",
|
|
315
315
|
(T.acquisitionTrend.reduce((e, t) => e + t.value, 0) / 1e3).toFixed(0),
|
|
@@ -326,7 +326,7 @@ function w() {
|
|
|
326
326
|
className: "flex-1 flex flex-col items-center gap-1",
|
|
327
327
|
children: [
|
|
328
328
|
/* @__PURE__ */ C("span", {
|
|
329
|
-
className: "text-[10px] text-
|
|
329
|
+
className: "text-[10px] text-text-secondary",
|
|
330
330
|
children: [e.count, " units"]
|
|
331
331
|
}),
|
|
332
332
|
/* @__PURE__ */ S("div", {
|
|
@@ -334,7 +334,7 @@ function w() {
|
|
|
334
334
|
style: { height: `${n}%` }
|
|
335
335
|
}),
|
|
336
336
|
/* @__PURE__ */ S("span", {
|
|
337
|
-
className: "text-[10px] text-
|
|
337
|
+
className: "text-[10px] text-text-secondary",
|
|
338
338
|
children: e.month.replace(" 20", "'")
|
|
339
339
|
})
|
|
340
340
|
]
|
|
@@ -370,7 +370,7 @@ function w() {
|
|
|
370
370
|
})
|
|
371
371
|
]
|
|
372
372
|
}) }), /* @__PURE__ */ S("tbody", { children: E.slice(0, 5).map((e) => /* @__PURE__ */ C("tr", {
|
|
373
|
-
className: "border-b hover:bg-
|
|
373
|
+
className: "border-b hover:bg-bg-sunken/50",
|
|
374
374
|
children: [
|
|
375
375
|
/* @__PURE__ */ S("td", {
|
|
376
376
|
className: "py-2 font-mono text-xs",
|
|
@@ -417,7 +417,7 @@ function w() {
|
|
|
417
417
|
className: "text-2xl font-bold",
|
|
418
418
|
children: D.length
|
|
419
419
|
}), /* @__PURE__ */ C("p", {
|
|
420
|
-
className: "text-xs text-
|
|
420
|
+
className: "text-xs text-text-secondary",
|
|
421
421
|
children: [B.length, " resolved"]
|
|
422
422
|
})] })] }),
|
|
423
423
|
/* @__PURE__ */ C(f, { children: [/* @__PURE__ */ S(h, {
|
|
@@ -430,7 +430,7 @@ function w() {
|
|
|
430
430
|
className: "text-2xl font-bold text-red-600",
|
|
431
431
|
children: V.length
|
|
432
432
|
}), /* @__PURE__ */ C("p", {
|
|
433
|
-
className: "text-xs text-
|
|
433
|
+
className: "text-xs text-text-secondary",
|
|
434
434
|
children: [((1 - V.length / Math.max(D.length, 1)) * 100).toFixed(1), "% compliance"]
|
|
435
435
|
})] })] }),
|
|
436
436
|
/* @__PURE__ */ C(f, { children: [/* @__PURE__ */ S(h, {
|
|
@@ -443,7 +443,7 @@ function w() {
|
|
|
443
443
|
className: "text-2xl font-bold",
|
|
444
444
|
children: H.length
|
|
445
445
|
}), /* @__PURE__ */ C("p", {
|
|
446
|
-
className: "text-xs text-
|
|
446
|
+
className: "text-xs text-text-secondary",
|
|
447
447
|
children: [
|
|
448
448
|
"of ",
|
|
449
449
|
O.length,
|
|
@@ -460,7 +460,7 @@ function w() {
|
|
|
460
460
|
className: "text-2xl font-bold",
|
|
461
461
|
children: [(k.reduce((e, t) => e + t.successRate, 0) / Math.max(k.length, 1)).toFixed(1), "%"]
|
|
462
462
|
}), /* @__PURE__ */ C("p", {
|
|
463
|
-
className: "text-xs text-
|
|
463
|
+
className: "text-xs text-text-secondary",
|
|
464
464
|
children: [k.length, " active workflows"]
|
|
465
465
|
})] })] })
|
|
466
466
|
]
|
|
@@ -530,13 +530,13 @@ function w() {
|
|
|
530
530
|
children: [/* @__PURE__ */ C("div", {
|
|
531
531
|
className: "flex items-center gap-3",
|
|
532
532
|
children: [/* @__PURE__ */ S("div", {
|
|
533
|
-
className: "w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-xs font-medium text-primary",
|
|
533
|
+
className: "w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-xs font-medium text-primary",
|
|
534
534
|
children: t + 1
|
|
535
535
|
}), /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("p", {
|
|
536
536
|
className: "text-sm font-medium",
|
|
537
537
|
children: e.name
|
|
538
538
|
}), /* @__PURE__ */ C("p", {
|
|
539
|
-
className: "text-xs text-
|
|
539
|
+
className: "text-xs text-text-secondary",
|
|
540
540
|
children: [
|
|
541
541
|
e.department,
|
|
542
542
|
" · ",
|
|
@@ -549,7 +549,7 @@ function w() {
|
|
|
549
549
|
className: "text-sm font-medium",
|
|
550
550
|
children: ["$", e.currentValue.toLocaleString()]
|
|
551
551
|
}), /* @__PURE__ */ S("p", {
|
|
552
|
-
className: "text-xs text-
|
|
552
|
+
className: "text-xs text-text-secondary",
|
|
553
553
|
children: e.currentValue < e.value ? /* @__PURE__ */ C("span", {
|
|
554
554
|
className: "text-red-600",
|
|
555
555
|
children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../src/assethandler/pages/AnalyticsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport {\n BarChart3,\n TrendingUp,\n TrendingDown,\n DollarSign,\n Box,\n PieChart,\n Activity,\n Download,\n ArrowUpRight,\n ArrowDownRight,\n} from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nexport function AnalyticsPage() {\n const { assets, portfolio, transactions, incidents, maintenanceRecords, workflows } =\n useAssetHandlerStore();\n const [timeRange, setTimeRange] = useState<'7d' | '30d' | '90d' | '1y'>('30d');\n\n const totalValue = assets.reduce((sum, a) => sum + a.currentValue, 0);\n const totalOriginal = assets.reduce((sum, a) => sum + a.value, 0);\n const depreciationTotal = totalOriginal - totalValue;\n const depreciationPct =\n totalOriginal > 0 ? ((depreciationTotal / totalOriginal) * 100).toFixed(1) : '0';\n const avgAssetValue = assets.length > 0 ? Math.round(totalValue / assets.length) : 0;\n\n const categoryBreakdown = assets.reduce<Record<string, { count: number; value: number }>>(\n (acc, a) => {\n const cat = a.category.replace('_', ' ');\n if (!acc[cat]) acc[cat] = { count: 0, value: 0 };\n acc[cat].count++;\n acc[cat].value += a.currentValue;\n return acc;\n },\n {}\n );\n\n const statusBreakdown = assets.reduce<Record<string, number>>((acc, a) => {\n acc[a.status] = (acc[a.status] || 0) + 1;\n return acc;\n }, {});\n\n const departmentBreakdown = assets.reduce<Record<string, { count: number; value: number }>>(\n (acc, a) => {\n if (!acc[a.department]) acc[a.department] = { count: 0, value: 0 };\n acc[a.department].count++;\n acc[a.department].value += a.currentValue;\n return acc;\n },\n {}\n );\n\n const resolvedIncidents = incidents.filter(\n (i) => i.status === 'resolved' || i.status === 'closed'\n );\n const slaBreached = incidents.filter((i) => i.slaBreached);\n const completedMaintenance = maintenanceRecords.filter((m) => m.status === 'completed');\n const totalMaintenanceCost = maintenanceRecords.reduce((sum, m) => sum + m.cost, 0);\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-3xl font-bold\">Analytics & Business Intelligence</h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n Comprehensive asset management analytics and insights\n </p>\n </div>\n <div className=\"flex gap-2\">\n <select\n value={timeRange}\n onChange={(e) => setTimeRange(e.target.value as typeof timeRange)}\n className=\"rounded-md border border-input bg-background px-3 py-1.5 text-sm\"\n >\n <option value=\"7d\">Last 7 days</option>\n <option value=\"30d\">Last 30 days</option>\n <option value=\"90d\">Last 90 days</option>\n <option value=\"1y\">Last year</option>\n </select>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n <Button size=\"sm\">Generate Report</Button>\n </div>\n </div>\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"financial\">Financial</TabsTrigger>\n <TabsTrigger value=\"operational\">Operational</TabsTrigger>\n <TabsTrigger value=\"insights\">Insights</TabsTrigger>\n </TabsList>\n\n {/* Overview Tab */}\n <TabsContent value=\"overview\" className=\"space-y-6 mt-6\">\n {/* Key Metrics */}\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Portfolio Value</CardTitle>\n <DollarSign className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${portfolio.totalValue.toLocaleString()}</div>\n <p className=\"text-xs text-muted-foreground flex items-center mt-1\">\n <ArrowUpRight className=\"mr-1 h-3 w-3 text-green-600\" />\n <span className=\"text-green-600\">+5.6%</span> from last quarter\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Depreciation</CardTitle>\n <TrendingDown className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold text-red-600\">\n -${depreciationTotal.toLocaleString()}\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {depreciationPct}% of original value\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Assets</CardTitle>\n <Box className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{portfolio.totalAssets}</div>\n <p className=\"text-xs text-muted-foreground\">\n {assets.filter((a) => a.status === 'active').length} currently active\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg. Asset Value</CardTitle>\n <BarChart3 className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${avgAssetValue.toLocaleString()}</div>\n <p className=\"text-xs text-muted-foreground\">Across all categories</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Category & Status Breakdown */}\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <PieChart className=\"h-4 w-4\" />\n Category Distribution\n </CardTitle>\n <CardDescription>Assets by category with values</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {Object.entries(categoryBreakdown)\n .sort((a, b) => b[1].value - a[1].value)\n .map(([cat, data]) => {\n const pct = Math.round((data.count / assets.length) * 100);\n return (\n <div key={cat} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"font-medium capitalize\">{cat}</span>\n <span className=\"text-muted-foreground\">\n {data.count} · ${(data.value / 1000).toFixed(1)}K\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-muted overflow-hidden\">\n <div\n className=\"h-full rounded-full bg-primary\"\n style={{ width: `${pct}%` }}\n />\n </div>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Activity className=\"h-4 w-4\" />\n Status Breakdown\n </CardTitle>\n <CardDescription>Current asset status distribution</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {Object.entries(statusBreakdown).map(([status, count]) => {\n const pct = Math.round((count / assets.length) * 100);\n return (\n <div key={status} className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <Badge\n variant={\n status === 'active'\n ? 'default'\n : status === 'under_maintenance'\n ? 'secondary'\n : 'outline'\n }\n >\n {status.replace('_', ' ')}\n </Badge>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"h-2 w-24 rounded-full bg-muted overflow-hidden\">\n <div\n className=\"h-full rounded-full bg-primary\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-8 text-right\">{count}</span>\n </div>\n </div>\n );\n })}\n </div>\n\n <Separator className=\"my-4\" />\n\n <div>\n <h4 className=\"text-sm font-medium mb-3\">By Department</h4>\n <div className=\"space-y-2\">\n {Object.entries(departmentBreakdown)\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, 5)\n .map(([dept, data]) => (\n <div key={dept} className=\"flex items-center justify-between text-sm\">\n <span>{dept}</span>\n <span className=\"text-muted-foreground\">{data.count} assets</span>\n </div>\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Depreciation Trend */}\n <Card>\n <CardHeader>\n <CardTitle>Depreciation Trend</CardTitle>\n <CardDescription>Portfolio depreciation over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-end gap-2 h-40\">\n {portfolio.depreciationTrend.map((point) => {\n const maxVal = Math.max(...portfolio.depreciationTrend.map((p) => p.value));\n const height = maxVal > 0 ? (point.value / maxVal) * 100 : 0;\n return (\n <div key={point.month} className=\"flex-1 flex flex-col items-center gap-1\">\n <span className=\"text-[10px] text-muted-foreground\">\n ${(point.value / 1000000).toFixed(2)}M\n </span>\n <div\n className=\"w-full bg-primary/80 rounded-t\"\n style={{ height: `${height}%` }}\n />\n <span className=\"text-[10px] text-muted-foreground\">\n {point.month.replace(' 20', \"'\")}\n </span>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Financial Tab */}\n <TabsContent value=\"financial\" className=\"space-y-6 mt-6\">\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Transactions</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{transactions.length}</div>\n <p className=\"text-xs text-muted-foreground\">\n ${transactions.reduce((s, t) => s + Math.abs(t.amount), 0).toLocaleString()} total\n value\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Maintenance Cost</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${totalMaintenanceCost.toLocaleString()}</div>\n <p className=\"text-xs text-muted-foreground\">\n {maintenanceRecords.length} maintenance records\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Acquisitions (6mo)</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {portfolio.acquisitionTrend.reduce((s, a) => s + a.count, 0)}\n </div>\n <p className=\"text-xs text-muted-foreground\">\n ${(portfolio.acquisitionTrend.reduce((s, a) => s + a.value, 0) / 1000).toFixed(0)}\n K total spend\n </p>\n </CardContent>\n </Card>\n </div>\n\n {/* Acquisition Trend */}\n <Card>\n <CardHeader>\n <CardTitle>Acquisition Trend</CardTitle>\n <CardDescription>New assets acquired over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-end gap-2 h-40\">\n {portfolio.acquisitionTrend.map((point) => {\n const maxVal = Math.max(...portfolio.acquisitionTrend.map((p) => p.count));\n const height = maxVal > 0 ? (point.count / maxVal) * 100 : 0;\n return (\n <div key={point.month} className=\"flex-1 flex flex-col items-center gap-1\">\n <span className=\"text-[10px] text-muted-foreground\">{point.count} units</span>\n <div\n className=\"w-full bg-green-500/80 rounded-t\"\n style={{ height: `${height}%` }}\n />\n <span className=\"text-[10px] text-muted-foreground\">\n {point.month.replace(' 20', \"'\")}\n </span>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n {/* Recent Transactions */}\n <Card>\n <CardHeader>\n <CardTitle>Recent Transactions</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n <th className=\"text-left py-2 font-medium\">ID</th>\n <th className=\"text-left py-2 font-medium\">Type</th>\n <th className=\"text-left py-2 font-medium\">Description</th>\n <th className=\"text-right py-2 font-medium\">Amount</th>\n <th className=\"text-left py-2 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {transactions.slice(0, 5).map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-muted/50\">\n <td className=\"py-2 font-mono text-xs\">{txn.id}</td>\n <td className=\"py-2 capitalize\">{txn.type}</td>\n <td className=\"py-2 truncate max-w-xs\">{txn.description}</td>\n <td\n className={`py-2 text-right font-medium ${txn.amount < 0 ? 'text-red-600' : ''}`}\n >\n ${Math.abs(txn.amount).toLocaleString()}\n </td>\n <td className=\"py-2\">\n <Badge variant=\"outline\">{txn.status}</Badge>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Operational Tab */}\n <TabsContent value=\"operational\" className=\"space-y-6 mt-6\">\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Incidents</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{incidents.length}</div>\n <p className=\"text-xs text-muted-foreground\">{resolvedIncidents.length} resolved</p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">SLA Breaches</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold text-red-600\">{slaBreached.length}</div>\n <p className=\"text-xs text-muted-foreground\">\n {((1 - slaBreached.length / Math.max(incidents.length, 1)) * 100).toFixed(1)}%\n compliance\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Maintenance Done</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{completedMaintenance.length}</div>\n <p className=\"text-xs text-muted-foreground\">\n of {maintenanceRecords.length} total\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Workflow Success</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {(\n workflows.reduce((s, w) => s + w.successRate, 0) / Math.max(workflows.length, 1)\n ).toFixed(1)}\n %\n </div>\n <p className=\"text-xs text-muted-foreground\">{workflows.length} active workflows</p>\n </CardContent>\n </Card>\n </div>\n </TabsContent>\n\n {/* Insights Tab */}\n <TabsContent value=\"insights\" className=\"space-y-6 mt-6\">\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card className=\"border-blue-200 bg-blue-50/50\">\n <CardHeader>\n <CardTitle className=\"text-blue-900 text-base\">Diversification</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-blue-800\">\n Your portfolio spans {Object.keys(categoryBreakdown).length} categories across{' '}\n {Object.keys(departmentBreakdown).length} departments. IT Hardware represents the\n largest segment at {portfolio.byCategory[0]?.count || 0} assets.\n </p>\n </CardContent>\n </Card>\n <Card className=\"border-green-200 bg-green-50/50\">\n <CardHeader>\n <CardTitle className=\"text-green-900 text-base\">Performance</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-green-800\">\n Portfolio depreciated value stands at $\n {(portfolio.depreciatedValue / 1000000).toFixed(2)}M. Depreciation rate is within\n expected range at {depreciationPct}% of original cost.\n </p>\n </CardContent>\n </Card>\n <Card className=\"border-amber-200 bg-amber-50/50\">\n <CardHeader>\n <CardTitle className=\"text-amber-900 text-base\">Maintenance</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-amber-800\">\n {maintenanceRecords.filter((m) => m.status === 'scheduled').length} maintenance\n tasks are scheduled. Total maintenance spend is $\n {totalMaintenanceCost.toLocaleString()}. Stay on top of preventive maintenance.\n </p>\n </CardContent>\n </Card>\n </div>\n\n {/* Top Assets by Value */}\n <Card>\n <CardHeader>\n <CardTitle>Top Assets by Value</CardTitle>\n <CardDescription>Highest value assets in your portfolio</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {[...assets]\n .sort((a, b) => b.currentValue - a.currentValue)\n .slice(0, 5)\n .map((asset, i) => (\n <div\n key={asset.id}\n className=\"flex items-center justify-between p-3 rounded-lg border\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-xs font-medium text-primary\">\n {i + 1}\n </div>\n <div>\n <p className=\"text-sm font-medium\">{asset.name}</p>\n <p className=\"text-xs text-muted-foreground\">\n {asset.department} · {asset.category.replace('_', ' ')}\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">\n ${asset.currentValue.toLocaleString()}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {asset.currentValue < asset.value ? (\n <span className=\"text-red-600\">\n -{((1 - asset.currentValue / asset.value) * 100).toFixed(1)}%\n </span>\n ) : (\n <span className=\"text-green-600\">No depreciation</span>\n )}\n </p>\n </div>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":";;;;;;AA6BA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,WAAQ,cAAW,iBAAc,cAAW,uBAAoB,iBACtE,GAAsB,EAClB,CAAC,GAAW,KAAgB,EAAsC,MAAM,EAExE,IAAa,EAAO,QAAQ,GAAK,MAAM,IAAM,EAAE,cAAc,EAAE,EAC/D,IAAgB,EAAO,QAAQ,GAAK,MAAM,IAAM,EAAE,OAAO,EAAE,EAC3D,IAAoB,IAAgB,GACpC,IACJ,IAAgB,KAAM,IAAoB,IAAiB,KAAK,QAAQ,EAAE,GAAG,KACzE,IAAgB,EAAO,SAAS,IAAI,KAAK,MAAM,IAAa,EAAO,OAAO,GAAG,GAE7E,IAAoB,EAAO,QAC9B,GAAK,MAAM;EACV,IAAM,IAAM,EAAE,SAAS,QAAQ,KAAK,IAAI;AAIxC,SAHK,EAAI,OAAM,EAAI,KAAO;GAAE,OAAO;GAAG,OAAO;GAAG,GAChD,EAAI,GAAK,SACT,EAAI,GAAK,SAAS,EAAE,cACb;IAET,EAAE,CACH,EAEK,IAAkB,EAAO,QAAgC,GAAK,OAClE,EAAI,EAAE,WAAW,EAAI,EAAE,WAAW,KAAK,GAChC,IACN,EAAE,CAAC,EAEA,IAAsB,EAAO,QAChC,GAAK,OACC,EAAI,EAAE,gBAAa,EAAI,EAAE,cAAc;EAAE,OAAO;EAAG,OAAO;EAAG,GAClE,EAAI,EAAE,YAAY,SAClB,EAAI,EAAE,YAAY,SAAS,EAAE,cACtB,IAET,EAAE,CACH,EAEK,IAAoB,EAAU,QACjC,MAAM,EAAE,WAAW,cAAc,EAAE,WAAW,SAChD,EACK,IAAc,EAAU,QAAQ,MAAM,EAAE,YAAY,EACpD,IAAuB,EAAmB,QAAQ,MAAM,EAAE,WAAW,YAAY,EACjF,IAAuB,EAAmB,QAAQ,GAAK,MAAM,IAAM,EAAE,MAAM,EAAE;AAEnF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAqB;IAAsC,CAAA,EACzE,kBAAC,KAAD;IAAG,WAAU;cAAqC;IAE9C,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,UAAD;MACE,OAAO;MACP,WAAW,MAAM,EAAa,EAAE,OAAO,MAA0B;MACjE,WAAU;gBAHZ;OAKE,kBAAC,UAAD;QAAQ,OAAM;kBAAK;QAAoB,CAAA;OACvC,kBAAC,UAAD;QAAQ,OAAM;kBAAM;QAAqB,CAAA;OACzC,kBAAC,UAAD;QAAQ,OAAM;kBAAM;QAAqB,CAAA;OACzC,kBAAC,UAAD;QAAQ,OAAM;kBAAK;QAAkB,CAAA;OAC9B;;KACT,kBAAC,GAAD;MAAQ,SAAQ;MAAU,MAAK;gBAA/B,CACE,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,EAAA,SAE9B;;KACT,kBAAC,GAAD;MAAQ,MAAK;gBAAK;MAAwB,CAAA;KACtC;MACF;MAEN,kBAAC,GAAD;GAAM,cAAa;aAAnB;IACE,kBAAC,GAAD,EAAA,UAAA;KACE,kBAAC,GAAD;MAAa,OAAM;gBAAW;MAAsB,CAAA;KACpD,kBAAC,GAAD;MAAa,OAAM;gBAAY;MAAuB,CAAA;KACtD,kBAAC,GAAD;MAAa,OAAM;gBAAc;MAAyB,CAAA;KAC1D,kBAAC,GAAD;MAAa,OAAM;gBAAW;MAAsB,CAAA;KAC3C,EAAA,CAAA;IAGX,kBAAC,GAAD;KAAa,OAAM;KAAW,WAAU;eAAxC;MAEE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAY,WAAU;mBAAtB,CACE,kBAAC,GAAD;UAAW,WAAU;oBAAsB;UAAiC,CAAA,EAC5E,kBAAC,GAAD,EAAY,WAAU,iCAAkC,CAAA,CAC7C;YACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CAAoC,KAAE,EAAU,WAAW,gBAAgB,CAAO;YAClF,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACE,kBAAC,GAAD,EAAc,WAAU,+BAAgC,CAAA;UACxD,kBAAC,QAAD;WAAM,WAAU;qBAAiB;WAAY,CAAA;;UAC3C;WACQ,EAAA,CAAA,CACT,EAAA,CAAA;QACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAY,WAAU;mBAAtB,CACE,kBAAC,GAAD;UAAW,WAAU;oBAAsB;UAA8B,CAAA,EACzE,kBAAC,GAAD,EAAc,WAAU,iCAAkC,CAAA,CAC/C;YACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CAAiD,MAC5C,EAAkB,gBAAgB,CACjC;YACN,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACG,GAAgB,sBACf;WACQ,EAAA,CAAA,CACT,EAAA,CAAA;QACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAY,WAAU;mBAAtB,CACE,kBAAC,GAAD;UAAW,WAAU;oBAAsB;UAAwB,CAAA,EACnE,kBAAC,GAAD,EAAK,WAAU,iCAAkC,CAAA,CACtC;YACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAsB,EAAU;SAAkB,CAAA,EACjE,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACG,EAAO,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC,QAAO,oBAClD;WACQ,EAAA,CAAA,CACT,EAAA,CAAA;QACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAY,WAAU;mBAAtB,CACE,kBAAC,GAAD;UAAW,WAAU;oBAAsB;UAA4B,CAAA,EACvE,kBAAC,GAAD,EAAW,WAAU,iCAAkC,CAAA,CAC5C;YACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CAAoC,KAAE,EAAc,gBAAgB,CAAO;YAC3E,kBAAC,KAAD;SAAG,WAAU;mBAAgC;SAAyB,CAAA,CAC1D,EAAA,CAAA,CACT,EAAA,CAAA;QACH;;MAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAW,WAAU;kBAArB,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAAA,wBAEtB;WACZ,kBAAC,GAAD,EAAA,UAAiB,kCAAgD,CAAA,CACtD,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;QAAK,WAAU;kBACZ,OAAO,QAAQ,EAAkB,CAC/B,MAAM,GAAG,MAAM,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,CACvC,KAAK,CAAC,GAAK,OAAU;SACpB,IAAM,IAAM,KAAK,MAAO,EAAK,QAAQ,EAAO,SAAU,IAAI;AAC1D,gBACE,kBAAC,OAAD;UAAe,WAAU;oBAAzB,CACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,QAAD;YAAM,WAAU;sBAA0B;YAAW,CAAA,EACrD,kBAAC,QAAD;YAAM,WAAU;sBAAhB;aACG,EAAK;aAAM;cAAa,EAAK,QAAQ,KAAM,QAAQ,EAAE;aAAC;aAClD;cACH;cACN,kBAAC,OAAD;WAAK,WAAU;qBACb,kBAAC,OAAD;YACE,WAAU;YACV,OAAO,EAAE,OAAO,GAAG,EAAI,IAAI;YAC3B,CAAA;WACE,CAAA,CACF;YAbI,EAaJ;UAER;QACA,CAAA,EACM,CAAA,CACT,EAAA,CAAA,EAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAW,WAAU;kBAArB,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAAA,mBAEtB;WACZ,kBAAC,GAAD,EAAA,UAAiB,qCAAmD,CAAA,CACzD,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA;QACE,kBAAC,OAAD;SAAK,WAAU;mBACZ,OAAO,QAAQ,EAAgB,CAAC,KAAK,CAAC,GAAQ,OAAW;UACxD,IAAM,IAAM,KAAK,MAAO,IAAQ,EAAO,SAAU,IAAI;AACrD,iBACE,kBAAC,OAAD;WAAkB,WAAU;qBAA5B,CACE,kBAAC,OAAD;YAAK,WAAU;sBACb,kBAAC,GAAD;aACE,SACE,MAAW,WACP,YACA,MAAW,sBACT,cACA;uBAGP,EAAO,QAAQ,KAAK,IAAI;aACnB,CAAA;YACJ,CAAA,EACN,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,OAAD;aAAK,WAAU;uBACb,kBAAC,OAAD;cACE,WAAU;cACV,OAAO,EAAE,OAAO,GAAG,EAAI,IAAI;cAC3B,CAAA;aACE,CAAA,EACN,kBAAC,QAAD;aAAM,WAAU;uBAAsC;aAAa,CAAA,CAC/D;cACF;aAvBI,EAuBJ;WAER;SACE,CAAA;QAEN,kBAAC,GAAD,EAAW,WAAU,QAAS,CAAA;QAE9B,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAA2B;SAAkB,CAAA,EAC3D,kBAAC,OAAD;SAAK,WAAU;mBACZ,OAAO,QAAQ,EAAoB,CACjC,MAAM,GAAG,MAAM,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,CACvC,MAAM,GAAG,EAAE,CACX,KAAK,CAAC,GAAM,OACX,kBAAC,OAAD;UAAgB,WAAU;oBAA1B,CACE,kBAAC,QAAD,EAAA,UAAO,GAAY,CAAA,EACnB,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CAAyC,EAAK,OAAM,UAAc;aAC9D;YAHI,EAGJ,CACN;SACA,CAAA,CACF,EAAA,CAAA;QACM,EAAA,CAAA,CACT,EAAA,CAAA,CACH;;MAGN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,sBAA8B,CAAA,EACzC,kBAAC,GAAD,EAAA,UAAiB,iDAA+D,CAAA,CACrE,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAU,kBAAkB,KAAK,MAAU;QAC1C,IAAM,IAAS,KAAK,IAAI,GAAG,EAAU,kBAAkB,KAAK,MAAM,EAAE,MAAM,CAAC,EACrE,IAAS,IAAS,IAAK,EAAM,QAAQ,IAAU,MAAM;AAC3D,eACE,kBAAC,OAAD;SAAuB,WAAU;mBAAjC;UACE,kBAAC,QAAD;WAAM,WAAU;qBAAhB;YAAoD;aAC/C,EAAM,QAAQ,KAAS,QAAQ,EAAE;YAAC;YAChC;;UACP,kBAAC,OAAD;WACE,WAAU;WACV,OAAO,EAAE,QAAQ,GAAG,EAAO,IAAI;WAC/B,CAAA;UACF,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAM,MAAM,QAAQ,OAAO,IAAI;WAC3B,CAAA;UACH;WAXI,EAAM,MAWV;SAER;OACE,CAAA,EACM,CAAA,CACT,EAAA,CAAA;MACK;;IAGd,kBAAC,GAAD;KAAa,OAAM;KAAY,WAAU;eAAzC;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAY,WAAU;mBACpB,kBAAC,GAAD;UAAW,WAAU;oBAAsB;UAA8B,CAAA;SAC9D,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAsB,EAAa;SAAa,CAAA,EAC/D,kBAAC,KAAD;SAAG,WAAU;mBAAb;UAA6C;UACzC,EAAa,QAAQ,GAAG,MAAM,IAAI,KAAK,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,gBAAgB;UAAC;UAE1E;WACQ,EAAA,CAAA,CACT,EAAA,CAAA;QACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAY,WAAU;mBACpB,kBAAC,GAAD;UAAW,WAAU;oBAAsB;UAA4B,CAAA;SAC5D,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CAAoC,KAAE,EAAqB,gBAAgB,CAAO;YAClF,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACG,EAAmB,QAAO,uBACzB;WACQ,EAAA,CAAA,CACT,EAAA,CAAA;QACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAY,WAAU;mBACpB,kBAAC,GAAD;UAAW,WAAU;oBAAsB;UAA8B,CAAA;SAC9D,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAU,iBAAiB,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,EAAE;SACxD,CAAA,EACN,kBAAC,KAAD;SAAG,WAAU;mBAAb;UAA6C;WACxC,EAAU,iBAAiB,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,EAAE,GAAG,KAAM,QAAQ,EAAE;UAAC;UAEhF;WACQ,EAAA,CAAA,CACT,EAAA,CAAA;QACH;;MAGN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,qBAA6B,CAAA,EACxC,kBAAC,GAAD,EAAA,UAAiB,8CAA4D,CAAA,CAClE,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAU,iBAAiB,KAAK,MAAU;QACzC,IAAM,IAAS,KAAK,IAAI,GAAG,EAAU,iBAAiB,KAAK,MAAM,EAAE,MAAM,CAAC,EACpE,IAAS,IAAS,IAAK,EAAM,QAAQ,IAAU,MAAM;AAC3D,eACE,kBAAC,OAAD;SAAuB,WAAU;mBAAjC;UACE,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CAAqD,EAAM,OAAM,SAAa;;UAC9E,kBAAC,OAAD;WACE,WAAU;WACV,OAAO,EAAE,QAAQ,GAAG,EAAO,IAAI;WAC/B,CAAA;UACF,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAM,MAAM,QAAQ,OAAO,IAAI;WAC3B,CAAA;UACH;WATI,EAAM,MASV;SAER;OACE,CAAA,EACM,CAAA,CACT,EAAA,CAAA;MAGP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,uBAA+B,CAAA,EAC/B,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;SAAI,WAAU;mBAAd;UACE,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAO,CAAA;UAClD,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAS,CAAA;UACpD,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAgB,CAAA;UAC3D,kBAAC,MAAD;WAAI,WAAU;qBAA8B;WAAW,CAAA;UACvD,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAW,CAAA;UACnD;YACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAa,MAAM,GAAG,EAAE,CAAC,KAAK,MAC7B,kBAAC,MAAD;SAAiB,WAAU;mBAA3B;UACE,kBAAC,MAAD;WAAI,WAAU;qBAA0B,EAAI;WAAQ,CAAA;UACpD,kBAAC,MAAD;WAAI,WAAU;qBAAmB,EAAI;WAAU,CAAA;UAC/C,kBAAC,MAAD;WAAI,WAAU;qBAA0B,EAAI;WAAiB,CAAA;UAC7D,kBAAC,MAAD;WACE,WAAW,+BAA+B,EAAI,SAAS,IAAI,iBAAiB;qBAD9E,CAEC,KACG,KAAK,IAAI,EAAI,OAAO,CAAC,gBAAgB,CACpC;;UACL,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,GAAD;YAAO,SAAQ;sBAAW,EAAI;YAAe,CAAA;WAC1C,CAAA;UACF;WAZI,EAAI,GAYR,CACL,EACI,CAAA,CACF;;OACJ,CAAA,EACM,CAAA,CACT,EAAA,CAAA;MACK;;IAGd,kBAAC,GAAD;KAAa,OAAM;KAAc,WAAU;eACzC,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,WAAU;kBACpB,kBAAC,GAAD;SAAW,WAAU;mBAAsB;SAAqB,CAAA;QACrD,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAsB,EAAU;QAAa,CAAA,EAC5D,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAA8C,EAAkB,QAAO,YAAa;UACxE,EAAA,CAAA,CACT,EAAA,CAAA;OACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,WAAU;kBACpB,kBAAC,GAAD;SAAW,WAAU;mBAAsB;SAAwB,CAAA;QACxD,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAmC,EAAY;QAAa,CAAA,EAC3E,kBAAC,KAAD;QAAG,WAAU;kBAAb,GACK,IAAI,EAAY,SAAS,KAAK,IAAI,EAAU,QAAQ,EAAE,IAAI,KAAK,QAAQ,EAAE,EAAC,eAE3E;UACQ,EAAA,CAAA,CACT,EAAA,CAAA;OACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,WAAU;kBACpB,kBAAC,GAAD;SAAW,WAAU;mBAAsB;SAA4B,CAAA;QAC5D,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAsB,EAAqB;QAAa,CAAA,EACvE,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAA6C;SACvC,EAAmB;SAAO;SAC5B;UACQ,EAAA,CAAA,CACT,EAAA,CAAA;OACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,WAAU;kBACpB,kBAAC,GAAD;SAAW,WAAU;mBAAsB;SAA4B,CAAA;QAC5D,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,EAEI,EAAU,QAAQ,GAAG,MAAM,IAAI,EAAE,aAAa,EAAE,GAAG,KAAK,IAAI,EAAU,QAAQ,EAAE,EAChF,QAAQ,EAAE,EAAC,IAET;WACN,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAA8C,EAAU,QAAO,oBAAqB;UACxE,EAAA,CAAA,CACT,EAAA,CAAA;OACH;;KACM,CAAA;IAGd,kBAAC,GAAD;KAAa,OAAM;KAAW,WAAU;eAAxC,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;SAAW,WAAU;mBAA0B;SAA2B,CAAA,EAC/D,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,KAAD;SAAG,WAAU;mBAAb;UAAqC;UACb,OAAO,KAAK,EAAkB,CAAC;UAAO;UAAmB;UAC9E,OAAO,KAAK,EAAoB,CAAC;UAAO;UACrB,EAAU,WAAW,IAAI,SAAS;UAAE;UACtD;YACQ,CAAA,CACT;;OACP,kBAAC,GAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;SAAW,WAAU;mBAA2B;SAAuB,CAAA,EAC5D,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,KAAD;SAAG,WAAU;mBAAb;UAAsC;WAElC,EAAU,mBAAmB,KAAS,QAAQ,EAAE;UAAC;UAChC;UAAgB;UACjC;YACQ,CAAA,CACT;;OACP,kBAAC,GAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;SAAW,WAAU;mBAA2B;SAAuB,CAAA,EAC5D,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAmB,QAAQ,MAAM,EAAE,WAAW,YAAY,CAAC;UAAO;UAElE,EAAqB,gBAAgB;UAAC;UACrC;YACQ,CAAA,CACT;;OACH;SAGN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,uBAA+B,CAAA,EAC1C,kBAAC,GAAD,EAAA,UAAiB,0CAAwD,CAAA,CAC9D,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,CAAC,GAAG,EAAO,CACT,MAAM,GAAG,MAAM,EAAE,eAAe,EAAE,aAAa,CAC/C,MAAM,GAAG,EAAE,CACX,KAAK,GAAO,MACX,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACZ,IAAI;SACD,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAuB,EAAM;SAAS,CAAA,EACnD,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAM;UAAW;UAAW,EAAM,SAAS,QAAQ,KAAK,IAAI;UAC3D;WACA,EAAA,CAAA,CACF;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAAmC,KAC/B,EAAM,aAAa,gBAAgB,CACnC;YACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAM,eAAe,EAAM,QAC1B,kBAAC,QAAD;UAAM,WAAU;oBAAhB;WAA+B;aACzB,IAAI,EAAM,eAAe,EAAM,SAAS,KAAK,QAAQ,EAAE;WAAC;WACvD;cAEP,kBAAC,QAAD;UAAM,WAAU;oBAAiB;UAAsB,CAAA;SAEvD,CAAA,CACA;UACF;SA5BC,EAAM,GA4BP,CACN;MACA,CAAA,EACM,CAAA,CACT,EAAA,CAAA,CACK;;IACT;KACH"}
|
|
1
|
+
{"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../src/assethandler/pages/AnalyticsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Separator,\n} from '@burdenoff/fe-libs/ui';\nimport {\n BarChart3,\n TrendingUp,\n TrendingDown,\n DollarSign,\n Box,\n PieChart,\n Activity,\n Download,\n ArrowUpRight,\n ArrowDownRight,\n} from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nexport function AnalyticsPage() {\n const { assets, portfolio, transactions, incidents, maintenanceRecords, workflows } =\n useAssetHandlerStore();\n const [timeRange, setTimeRange] = useState<'7d' | '30d' | '90d' | '1y'>('30d');\n\n const totalValue = assets.reduce((sum, a) => sum + a.currentValue, 0);\n const totalOriginal = assets.reduce((sum, a) => sum + a.value, 0);\n const depreciationTotal = totalOriginal - totalValue;\n const depreciationPct =\n totalOriginal > 0 ? ((depreciationTotal / totalOriginal) * 100).toFixed(1) : '0';\n const avgAssetValue = assets.length > 0 ? Math.round(totalValue / assets.length) : 0;\n\n const categoryBreakdown = assets.reduce<Record<string, { count: number; value: number }>>(\n (acc, a) => {\n const cat = a.category.replace('_', ' ');\n if (!acc[cat]) acc[cat] = { count: 0, value: 0 };\n acc[cat].count++;\n acc[cat].value += a.currentValue;\n return acc;\n },\n {}\n );\n\n const statusBreakdown = assets.reduce<Record<string, number>>((acc, a) => {\n acc[a.status] = (acc[a.status] || 0) + 1;\n return acc;\n }, {});\n\n const departmentBreakdown = assets.reduce<Record<string, { count: number; value: number }>>(\n (acc, a) => {\n if (!acc[a.department]) acc[a.department] = { count: 0, value: 0 };\n acc[a.department].count++;\n acc[a.department].value += a.currentValue;\n return acc;\n },\n {}\n );\n\n const resolvedIncidents = incidents.filter(\n (i) => i.status === 'resolved' || i.status === 'closed'\n );\n const slaBreached = incidents.filter((i) => i.slaBreached);\n const completedMaintenance = maintenanceRecords.filter((m) => m.status === 'completed');\n const totalMaintenanceCost = maintenanceRecords.reduce((sum, m) => sum + m.cost, 0);\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-3xl font-bold\">Analytics & Business Intelligence</h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n Comprehensive asset management analytics and insights\n </p>\n </div>\n <div className=\"flex gap-2\">\n <select\n value={timeRange}\n onChange={(e) => setTimeRange(e.target.value as typeof timeRange)}\n className=\"rounded-md border border-border-default bg-bg-surface px-3 py-1.5 text-sm\"\n >\n <option value=\"7d\">Last 7 days</option>\n <option value=\"30d\">Last 30 days</option>\n <option value=\"90d\">Last 90 days</option>\n <option value=\"1y\">Last year</option>\n </select>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n <Button size=\"sm\">Generate Report</Button>\n </div>\n </div>\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"financial\">Financial</TabsTrigger>\n <TabsTrigger value=\"operational\">Operational</TabsTrigger>\n <TabsTrigger value=\"insights\">Insights</TabsTrigger>\n </TabsList>\n\n {/* Overview Tab */}\n <TabsContent value=\"overview\" className=\"space-y-6 mt-6\">\n {/* Key Metrics */}\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Portfolio Value</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${portfolio.totalValue.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary flex items-center mt-1\">\n <ArrowUpRight className=\"mr-1 h-3 w-3 text-green-600\" />\n <span className=\"text-green-600\">+5.6%</span> from last quarter\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Depreciation</CardTitle>\n <TrendingDown className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold text-red-600\">\n -${depreciationTotal.toLocaleString()}\n </div>\n <p className=\"text-xs text-text-secondary\">\n {depreciationPct}% of original value\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Assets</CardTitle>\n <Box className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{portfolio.totalAssets}</div>\n <p className=\"text-xs text-text-secondary\">\n {assets.filter((a) => a.status === 'active').length} currently active\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg. Asset Value</CardTitle>\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${avgAssetValue.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">Across all categories</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Category & Status Breakdown */}\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <PieChart className=\"h-4 w-4\" />\n Category Distribution\n </CardTitle>\n <CardDescription>Assets by category with values</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {Object.entries(categoryBreakdown)\n .sort((a, b) => b[1].value - a[1].value)\n .map(([cat, data]) => {\n const pct = Math.round((data.count / assets.length) * 100);\n return (\n <div key={cat} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"font-medium capitalize\">{cat}</span>\n <span className=\"text-text-secondary\">\n {data.count} · ${(data.value / 1000).toFixed(1)}K\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg\"\n style={{ width: `${pct}%` }}\n />\n </div>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Activity className=\"h-4 w-4\" />\n Status Breakdown\n </CardTitle>\n <CardDescription>Current asset status distribution</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {Object.entries(statusBreakdown).map(([status, count]) => {\n const pct = Math.round((count / assets.length) * 100);\n return (\n <div key={status} className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <Badge\n variant={\n status === 'active'\n ? 'default'\n : status === 'under_maintenance'\n ? 'secondary'\n : 'outline'\n }\n >\n {status.replace('_', ' ')}\n </Badge>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"h-2 w-24 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"text-sm font-medium w-8 text-right\">{count}</span>\n </div>\n </div>\n );\n })}\n </div>\n\n <Separator className=\"my-4\" />\n\n <div>\n <h4 className=\"text-sm font-medium mb-3\">By Department</h4>\n <div className=\"space-y-2\">\n {Object.entries(departmentBreakdown)\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, 5)\n .map(([dept, data]) => (\n <div key={dept} className=\"flex items-center justify-between text-sm\">\n <span>{dept}</span>\n <span className=\"text-text-secondary\">{data.count} assets</span>\n </div>\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Depreciation Trend */}\n <Card>\n <CardHeader>\n <CardTitle>Depreciation Trend</CardTitle>\n <CardDescription>Portfolio depreciation over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-end gap-2 h-40\">\n {portfolio.depreciationTrend.map((point) => {\n const maxVal = Math.max(...portfolio.depreciationTrend.map((p) => p.value));\n const height = maxVal > 0 ? (point.value / maxVal) * 100 : 0;\n return (\n <div key={point.month} className=\"flex-1 flex flex-col items-center gap-1\">\n <span className=\"text-[10px] text-text-secondary\">\n ${(point.value / 1000000).toFixed(2)}M\n </span>\n <div\n className=\"w-full bg-action-primary-bg/80 rounded-t\"\n style={{ height: `${height}%` }}\n />\n <span className=\"text-[10px] text-text-secondary\">\n {point.month.replace(' 20', \"'\")}\n </span>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Financial Tab */}\n <TabsContent value=\"financial\" className=\"space-y-6 mt-6\">\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Transactions</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{transactions.length}</div>\n <p className=\"text-xs text-text-secondary\">\n ${transactions.reduce((s, t) => s + Math.abs(t.amount), 0).toLocaleString()} total\n value\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Maintenance Cost</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">${totalMaintenanceCost.toLocaleString()}</div>\n <p className=\"text-xs text-text-secondary\">\n {maintenanceRecords.length} maintenance records\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Acquisitions (6mo)</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {portfolio.acquisitionTrend.reduce((s, a) => s + a.count, 0)}\n </div>\n <p className=\"text-xs text-text-secondary\">\n ${(portfolio.acquisitionTrend.reduce((s, a) => s + a.value, 0) / 1000).toFixed(0)}\n K total spend\n </p>\n </CardContent>\n </Card>\n </div>\n\n {/* Acquisition Trend */}\n <Card>\n <CardHeader>\n <CardTitle>Acquisition Trend</CardTitle>\n <CardDescription>New assets acquired over the last 6 months</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-end gap-2 h-40\">\n {portfolio.acquisitionTrend.map((point) => {\n const maxVal = Math.max(...portfolio.acquisitionTrend.map((p) => p.count));\n const height = maxVal > 0 ? (point.count / maxVal) * 100 : 0;\n return (\n <div key={point.month} className=\"flex-1 flex flex-col items-center gap-1\">\n <span className=\"text-[10px] text-text-secondary\">{point.count} units</span>\n <div\n className=\"w-full bg-green-500/80 rounded-t\"\n style={{ height: `${height}%` }}\n />\n <span className=\"text-[10px] text-text-secondary\">\n {point.month.replace(' 20', \"'\")}\n </span>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n {/* Recent Transactions */}\n <Card>\n <CardHeader>\n <CardTitle>Recent Transactions</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n <th className=\"text-left py-2 font-medium\">ID</th>\n <th className=\"text-left py-2 font-medium\">Type</th>\n <th className=\"text-left py-2 font-medium\">Description</th>\n <th className=\"text-right py-2 font-medium\">Amount</th>\n <th className=\"text-left py-2 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {transactions.slice(0, 5).map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-bg-sunken/50\">\n <td className=\"py-2 font-mono text-xs\">{txn.id}</td>\n <td className=\"py-2 capitalize\">{txn.type}</td>\n <td className=\"py-2 truncate max-w-xs\">{txn.description}</td>\n <td\n className={`py-2 text-right font-medium ${txn.amount < 0 ? 'text-red-600' : ''}`}\n >\n ${Math.abs(txn.amount).toLocaleString()}\n </td>\n <td className=\"py-2\">\n <Badge variant=\"outline\">{txn.status}</Badge>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Operational Tab */}\n <TabsContent value=\"operational\" className=\"space-y-6 mt-6\">\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Incidents</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{incidents.length}</div>\n <p className=\"text-xs text-text-secondary\">{resolvedIncidents.length} resolved</p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">SLA Breaches</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold text-red-600\">{slaBreached.length}</div>\n <p className=\"text-xs text-text-secondary\">\n {((1 - slaBreached.length / Math.max(incidents.length, 1)) * 100).toFixed(1)}%\n compliance\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Maintenance Done</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{completedMaintenance.length}</div>\n <p className=\"text-xs text-text-secondary\">\n of {maintenanceRecords.length} total\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium\">Workflow Success</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">\n {(\n workflows.reduce((s, w) => s + w.successRate, 0) / Math.max(workflows.length, 1)\n ).toFixed(1)}\n %\n </div>\n <p className=\"text-xs text-text-secondary\">{workflows.length} active workflows</p>\n </CardContent>\n </Card>\n </div>\n </TabsContent>\n\n {/* Insights Tab */}\n <TabsContent value=\"insights\" className=\"space-y-6 mt-6\">\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card className=\"border-blue-200 bg-blue-50/50\">\n <CardHeader>\n <CardTitle className=\"text-blue-900 text-base\">Diversification</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-blue-800\">\n Your portfolio spans {Object.keys(categoryBreakdown).length} categories across{' '}\n {Object.keys(departmentBreakdown).length} departments. IT Hardware represents the\n largest segment at {portfolio.byCategory[0]?.count || 0} assets.\n </p>\n </CardContent>\n </Card>\n <Card className=\"border-green-200 bg-green-50/50\">\n <CardHeader>\n <CardTitle className=\"text-green-900 text-base\">Performance</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-green-800\">\n Portfolio depreciated value stands at $\n {(portfolio.depreciatedValue / 1000000).toFixed(2)}M. Depreciation rate is within\n expected range at {depreciationPct}% of original cost.\n </p>\n </CardContent>\n </Card>\n <Card className=\"border-amber-200 bg-amber-50/50\">\n <CardHeader>\n <CardTitle className=\"text-amber-900 text-base\">Maintenance</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-amber-800\">\n {maintenanceRecords.filter((m) => m.status === 'scheduled').length} maintenance\n tasks are scheduled. Total maintenance spend is $\n {totalMaintenanceCost.toLocaleString()}. Stay on top of preventive maintenance.\n </p>\n </CardContent>\n </Card>\n </div>\n\n {/* Top Assets by Value */}\n <Card>\n <CardHeader>\n <CardTitle>Top Assets by Value</CardTitle>\n <CardDescription>Highest value assets in your portfolio</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {[...assets]\n .sort((a, b) => b.currentValue - a.currentValue)\n .slice(0, 5)\n .map((asset, i) => (\n <div\n key={asset.id}\n className=\"flex items-center justify-between p-3 rounded-lg border\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-xs font-medium text-primary\">\n {i + 1}\n </div>\n <div>\n <p className=\"text-sm font-medium\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">\n {asset.department} · {asset.category.replace('_', ' ')}\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">\n ${asset.currentValue.toLocaleString()}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {asset.currentValue < asset.value ? (\n <span className=\"text-red-600\">\n -{((1 - asset.currentValue / asset.value) * 100).toFixed(1)}%\n </span>\n ) : (\n <span className=\"text-green-600\">No depreciation</span>\n )}\n </p>\n </div>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -48,7 +48,7 @@ function S() {
|
|
|
48
48
|
className: "text-2xl font-bold",
|
|
49
49
|
children: "Asset Categories"
|
|
50
50
|
}), /* @__PURE__ */ y("p", {
|
|
51
|
-
className: "text-sm text-
|
|
51
|
+
className: "text-sm text-text-secondary",
|
|
52
52
|
children: [
|
|
53
53
|
Object.keys(i).length,
|
|
54
54
|
" categories · ",
|
|
@@ -73,7 +73,7 @@ function S() {
|
|
|
73
73
|
/* @__PURE__ */ y("div", {
|
|
74
74
|
className: "flex items-center justify-between",
|
|
75
75
|
children: [/* @__PURE__ */ v("div", {
|
|
76
|
-
className: `p-2 rounded-lg ${x[e] || "bg-
|
|
76
|
+
className: `p-2 rounded-lg ${x[e] || "bg-bg-sunken"}`,
|
|
77
77
|
children: b[e] || /* @__PURE__ */ v(n, { className: "h-5 w-5" })
|
|
78
78
|
}), /* @__PURE__ */ y(u, {
|
|
79
79
|
variant: "outline",
|
|
@@ -92,7 +92,7 @@ function S() {
|
|
|
92
92
|
/* @__PURE__ */ y("div", {
|
|
93
93
|
className: "flex justify-between text-sm",
|
|
94
94
|
children: [/* @__PURE__ */ v("span", {
|
|
95
|
-
className: "text-
|
|
95
|
+
className: "text-text-secondary",
|
|
96
96
|
children: "Current Value"
|
|
97
97
|
}), /* @__PURE__ */ y("span", {
|
|
98
98
|
className: "font-medium",
|
|
@@ -102,7 +102,7 @@ function S() {
|
|
|
102
102
|
/* @__PURE__ */ y("div", {
|
|
103
103
|
className: "flex justify-between text-sm",
|
|
104
104
|
children: [/* @__PURE__ */ v("span", {
|
|
105
|
-
className: "text-
|
|
105
|
+
className: "text-text-secondary",
|
|
106
106
|
children: "Depreciation"
|
|
107
107
|
}), /* @__PURE__ */ y("span", {
|
|
108
108
|
className: "text-red-600",
|
|
@@ -110,15 +110,15 @@ function S() {
|
|
|
110
110
|
})]
|
|
111
111
|
}),
|
|
112
112
|
/* @__PURE__ */ v("div", {
|
|
113
|
-
className: "h-2 rounded-full bg-
|
|
113
|
+
className: "h-2 rounded-full bg-bg-sunken overflow-hidden",
|
|
114
114
|
children: /* @__PURE__ */ v("div", {
|
|
115
|
-
className: "h-full rounded-full bg-primary",
|
|
115
|
+
className: "h-full rounded-full bg-action-primary-bg",
|
|
116
116
|
style: { width: `${r}%` }
|
|
117
117
|
})
|
|
118
118
|
}),
|
|
119
119
|
/* @__PURE__ */ v(_, {}),
|
|
120
120
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
121
|
-
className: "text-xs font-medium text-
|
|
121
|
+
className: "text-xs font-medium text-text-secondary mb-2",
|
|
122
122
|
children: "Status breakdown"
|
|
123
123
|
}), /* @__PURE__ */ v("div", {
|
|
124
124
|
className: "flex flex-wrap gap-1",
|
|
@@ -134,7 +134,7 @@ function S() {
|
|
|
134
134
|
})] }),
|
|
135
135
|
/* @__PURE__ */ v(_, {}),
|
|
136
136
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
137
|
-
className: "text-xs font-medium text-
|
|
137
|
+
className: "text-xs font-medium text-text-secondary mb-2",
|
|
138
138
|
children: "Top Assets"
|
|
139
139
|
}), /* @__PURE__ */ v("div", {
|
|
140
140
|
className: "space-y-1.5",
|