+ {/* Header Section */}
+
+
Resource-Level Breakdown
+
+
+ {/* Controls Row: Search + Actions */}
+
+ {/* Search Box - Reduced Width */}
+
+
+
+
+ {/* Actions: Filter & Export on the right */}
+
+ {/* Type Filter */}
+ {typeFilterOptions.length > 0 && (
+ item?.text || ''}
+ selectedItem={typeFilterOptions.find((o) => o.id === selectedType)}
+ onChange={onTypeChange ? (e: { selectedItem: DropdownOption }) => e.selectedItem && onTypeChange(e.selectedItem) : undefined}
+ size="md"
+ className="white-bg-dropdown dropdown-min-width"
+ />
+ )}
+
+
+
+
+ {/* Table Container */}
+
+ {rows.length === 0 ? (
+
+ ) : (
+
+ {({
+ rows: tableDataRows,
+ headers: tableHeaders,
+ getTableProps,
+ getHeaderProps,
+ getRowProps,
+ }: any) => (
+
+
+
+
+ {tableHeaders.map((header: DataTableHeader) => (
+
+ {header.header}
+
+ ))}
+
+
+
+ {tableDataRows.length === 0 ? (
+
+
+ No resources match your search
+
+
+ ) : (
+ tableDataRows.map((row: DataTableRow) => (
+ onRowClick && onRowClick(row.id)}
+ className="clickable-row"
+ style={{ cursor: onRowClick ? 'pointer' : 'default' }}
+ >
+ {row.cells.map((cell: DataTableCell) => {
+ // Custom Cell Rendering
+ if (cell.info.header === 'type') {
+ return (
+
+
+ {getTypeIcon(cell.value)}
+ {cell.value}
+
+
+ );
+ }
+ if (cell.info.header === 'category') {
+ return (
+
+
+ {cell.value}
+
+
+ );
+ }
+ if (cell.info.header === 'cost') {
+ return (
+
+ {cell.value}
+
+ );
+ }
+ return {cell.value};
+ })}
+
+ ))
+ )}
+
+
+
+
+ )}
+
+ )}
+
+
+ );
+};
+
+export default React.memo(ResourceBreakdownTable);
diff --git a/src/components/Assets/index.tsx b/src/components/Assets/index.tsx
new file mode 100644
index 00000000..541f7342
--- /dev/null
+++ b/src/components/Assets/index.tsx
@@ -0,0 +1,15 @@
+/**
+ * Assets Components Index
+ * Re-export all modular TypeScript components for the Assets page
+ */
+
+export { default as KPICard, KPICardSkeleton } from './KPICard';
+export { default as KPICardRow } from './KPICardRow';
+export { default as CostByProviderChart } from './CostByProviderChart';
+export { default as CostByCategoryChart } from './CostByCategoryChart';
+export { default as CarbonEmissionChart } from './CarbonEmissionChart';
+export { default as ResourceBreakdownTable } from './ResourceBreakdownTable';
+export { default as AssetPageHeader } from './AssetPageHeader';
+export { default as CostOverTimeChart } from './CostOverTimeChart';
+export { default as CostByServiceChart } from './CostByServiceChart';
+export { default as AssetDetails } from './AssetDetails';
diff --git a/src/components/Assets/tokens.ts b/src/components/Assets/tokens.ts
new file mode 100644
index 00000000..17fcf8f0
--- /dev/null
+++ b/src/components/Assets/tokens.ts
@@ -0,0 +1,55 @@
+import { DropdownOption } from '../../types/assets';
+
+export const windowOptions: DropdownOption[] = [
+ { id: "Today", text: "today" },
+ { id: "Yesterday", text: "yesterday" },
+ { id: "Last 24h", text: "24h" },
+ { id: "Last 48h", text: "48h" },
+ { id: "Week-to-date", text: "week" },
+ { id: "Last week", text: "lastweek" },
+ { id: "Last 7 days", text: "7d" },
+ { id: "Last 14 days", text: "14d" },
+ { id: "Last 30 days", text: "30d" },
+];
+
+export const assetTypeOptions: DropdownOption[] = [
+ { id: 'all', text: 'All types' },
+ { id: 'Node', text: 'Node' },
+ { id: 'Disk', text: 'Disk' },
+ { id: 'LoadBalancer', text: 'LoadBalancer' },
+ { id: 'ClusterManagement', text: 'ClusterManagement' },
+];
+
+export const currencyOptions: DropdownOption[] = [
+ { id: 'USD', text: 'USD ($)' },
+ { id: 'EUR', text: 'EUR (€)' },
+ { id: 'GBP', text: 'GBP (£)' },
+ { id: 'JPY', text: 'JPY (¥)' },
+ { id: 'INR', text: 'INR (₹)' },
+];
+
+export const aggregationOptions: DropdownOption[] = [
+ { id: 'daily', text: 'Daily' },
+ { id: 'entire', text: 'Entire Window' },
+];
+
+export const serviceBreakdownOptions: DropdownOption[] = [
+ { id: 'service', text: 'Service' },
+ { id: 'cluster', text: 'Cluster' },
+];
+
+// Map internal IDs to display names if needed
+export const assetTypeMap: Record