-
-
-
-
- Source
-
-
- Active Users
-
-
-
-
- {detailedData.sources.map((source, index) => (
-
-
- {source.source}
-
-
- {source.activeUsers}
-
-
- ))}
-
-
+
+ `${source.source}-${index}`}
+ maxHeight="sm"
+ compact
+ />
diff --git a/inventory/src/components/dashboard/SalesChart.jsx b/inventory/src/components/dashboard/SalesChart.jsx
index 585b3ce..85b0e52 100644
--- a/inventory/src/components/dashboard/SalesChart.jsx
+++ b/inventory/src/components/dashboard/SalesChart.jsx
@@ -1,13 +1,6 @@
-import React, { useState, useEffect, useMemo, useCallback, memo } from "react";
-import axios from "axios";
+import React, { useState, useEffect, useCallback, memo } from "react";
import { acotService } from "@/services/dashboard/acotService";
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
+import { Card, CardContent } from "@/components/ui/card";
import {
Select,
SelectContent,
@@ -15,16 +8,8 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
-import { Input } from "@/components/ui/input";
-import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
-import {
- Loader2,
- TrendingUp,
- TrendingDown,
- Info,
- AlertCircle,
-} from "lucide-react";
+import { TrendingUp } from "lucide-react";
import {
LineChart,
Line,
@@ -36,13 +21,7 @@ import {
Legend,
ReferenceLine,
} from "recharts";
-import {
- TIME_RANGES,
- GROUP_BY_OPTIONS,
- formatDateForInput,
- parseDateFromInput,
-} from "@/lib/dashboard/constants";
-import { Checkbox } from "@/components/ui/checkbox";
+import { TIME_RANGES } from "@/lib/dashboard/constants";
import {
Table,
TableHeader,
@@ -51,75 +30,26 @@ import {
TableBody,
TableCell,
} from "@/components/ui/table";
-import { debounce } from "lodash";
import {
Dialog,
DialogContent,
- DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Skeleton } from "@/components/ui/skeleton";
import { Separator } from "@/components/ui/separator";
-import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
-import {
- Collapsible,
- CollapsibleContent,
- CollapsibleTrigger,
-} from "@/components/ui/collapsible";
-import {
- CARD_STYLES,
- TYPOGRAPHY,
- METRIC_COLORS as SHARED_METRIC_COLORS,
-} from "@/lib/dashboard/designTokens";
+import { CARD_STYLES } from "@/lib/dashboard/designTokens";
import {
+ DashboardSectionHeader,
DashboardStatCard,
+ DashboardStatCardSkeleton,
+ DashboardChartTooltip,
ChartSkeleton,
- TableSkeleton,
DashboardEmptyState,
DashboardErrorState,
- TOOLTIP_STYLES,
} from "@/components/dashboard/shared";
-const METRIC_IDS = {
- PLACED_ORDER: "Y8cqcF",
- PAYMENT_REFUNDED: "R7XUYh",
-};
-
-// Map current periods to their previous equivalents
-const PREVIOUS_PERIOD_MAP = {
- today: "yesterday",
- thisWeek: "lastWeek",
- thisMonth: "lastMonth",
- last7days: "previous7days",
- last30days: "previous30days",
- last90days: "previous90days",
- yesterday: "twoDaysAgo",
-};
-
-// Add helper function to calculate previous period dates
-const calculatePreviousPeriodDates = (timeRange, startDate, endDate) => {
- if (timeRange && timeRange !== "custom") {
- return {
- timeRange: PREVIOUS_PERIOD_MAP[timeRange],
- };
- } else if (startDate && endDate) {
- const start = new Date(startDate);
- const end = new Date(endDate);
- const duration = end.getTime() - start.getTime();
-
- const prevEnd = new Date(start.getTime() - 1);
- const prevStart = new Date(prevEnd.getTime() - duration);
-
- return {
- startDate: prevStart.toISOString(),
- endDate: prevEnd.toISOString(),
- };
- }
- return null;
-};
-
// Move formatCurrency to top and export it
export const formatCurrency = (value, minimumFractionDigits = 0) => {
if (!value || isNaN(value)) return "$0";
@@ -131,60 +61,23 @@ export const formatCurrency = (value, minimumFractionDigits = 0) => {
}).format(value);
};
-// Add a helper function for percentage formatting
-const formatPercentage = (value) => {
- if (typeof value !== "number") return "0%";
- return `${Math.abs(Math.round(value))}%`;
-};
-
-// Add color mapping for metrics - using shared tokens where applicable
-const METRIC_COLORS = {
- revenue: SHARED_METRIC_COLORS.aov, // Purple for revenue
- orders: SHARED_METRIC_COLORS.revenue, // Emerald for orders
- avgOrderValue: "#9333ea", // Deep purple for AOV
- movingAverage: SHARED_METRIC_COLORS.comparison, // Amber for moving average
- prevRevenue: SHARED_METRIC_COLORS.expense, // Orange for prev revenue
- prevOrders: SHARED_METRIC_COLORS.secondary, // Cyan for prev orders
- prevAvgOrderValue: SHARED_METRIC_COLORS.comparison, // Amber for prev AOV
-};
-
-// Export CustomTooltip
-export const CustomTooltip = ({ active, payload, label }) => {
- if (active && payload && payload.length) {
- const date = new Date(label);
- const formattedDate = date.toLocaleDateString("en-US", {
- weekday: "short",
- month: "short",
- day: "numeric",
- });
-
- return (
-
-
{formattedDate}
-
- {payload.map((entry, index) => {
- const value = entry.dataKey.toLowerCase().includes('revenue') || entry.dataKey === 'avgOrderValue'
- ? formatCurrency(entry.value)
- : entry.value.toLocaleString();
-
- return (
-
-
-
- {entry.name}
-
-
{value}
-
- );
- })}
-
-
- );
+// Sales chart tooltip formatter - formats revenue/AOV as currency, others as numbers
+const salesValueFormatter = (value, name) => {
+ const nameLower = (name || "").toLowerCase();
+ if (nameLower.includes('revenue') || nameLower.includes('order value') || nameLower.includes('average')) {
+ return formatCurrency(value);
}
- return null;
+ return typeof value === 'number' ? value.toLocaleString() : value;
+};
+
+// Sales chart label formatter - formats timestamp as readable date
+const salesLabelFormatter = (label) => {
+ const date = new Date(label);
+ return date.toLocaleDateString("en-US", {
+ weekday: "short",
+ month: "short",
+ day: "numeric",
+ });
};
const calculate7DayAverage = (data) => {
@@ -434,18 +327,9 @@ SummaryStats.displayName = "SummaryStats";
// Note: Using ChartSkeleton and TableSkeleton from @/components/dashboard/shared
const SkeletonStats = () => (
-
+
{[...Array(4)].map((_, i) => (
-
-
-
-
-
-
-
-
-
-
+
))}
);
@@ -565,19 +449,28 @@ const SalesChart = ({ timeRange = "last30days", title = "Sales Overview" }) => {
? data.reduce((sum, day) => sum + day.revenue, 0) / data.length
: 0;
- return (
-
-
-
-
-
-
- {title}
-
-
-
- {!error && (
-
+ // Time selector for DashboardSectionHeader
+ const timeSelector = (
+
+
+
+
+
+ {TIME_RANGES.map((range) => (
+
+ {range.label}
+
+ ))}
+
+
+ );
+
+ // Actions (Details dialog) for DashboardSectionHeader
+ const headerActions = !error ? (
+
Details
@@ -768,118 +661,107 @@ const SalesChart = ({ timeRange = "last30days", title = "Sales Overview" }) => {
- )}
-
-
-
-
-
- {TIME_RANGES.map((range) => (
-
- {range.label}
-
- ))}
-
-
-
-
+ ) : null;
- {/* Show stats only if not in error state */}
- {!error &&
- (loading ? (
-
- ) : (
-
- ))}
+ return (
+
+
- {/* Show metric toggles only if not in error state */}
- {!error && (
-
-
-
- setMetrics((prev) => ({
- ...prev,
- revenue: !prev.revenue,
- }))
- }
- >
- Revenue
-
-
- setMetrics((prev) => ({
- ...prev,
- orders: !prev.orders,
- }))
- }
- >
- Orders
-
-
- setMetrics((prev) => ({
- ...prev,
- movingAverage: !prev.movingAverage,
- }))
- }
- >
- 7-Day Avg
-
-
- setMetrics((prev) => ({
- ...prev,
- avgOrderValue: !prev.avgOrderValue,
- }))
- }
- >
- AOV
-
-
-
-
-
+
+ {/* Show stats only if not in error state */}
+ {!error && (
+ loading ? (
+
+ ) : (
+
+ )
+ )}
+ {/* Show metric toggles only if not in error state */}
+ {!error && (
+
+
setMetrics((prev) => ({
...prev,
- showPrevious: !prev.showPrevious,
+ revenue: !prev.revenue,
}))
}
>
- Compare Prev Period
+ Revenue
+
+
+ setMetrics((prev) => ({
+ ...prev,
+ orders: !prev.orders,
+ }))
+ }
+ >
+ Orders
+
+
+ setMetrics((prev) => ({
+ ...prev,
+ movingAverage: !prev.movingAverage,
+ }))
+ }
+ >
+ 7-Day Avg
+
+
+ setMetrics((prev) => ({
+ ...prev,
+ avgOrderValue: !prev.avgOrderValue,
+ }))
+ }
+ >
+ AOV
- )}
-
-
-
+
+
+
+
+ setMetrics((prev) => ({
+ ...prev,
+ showPrevious: !prev.showPrevious,
+ }))
+ }
+ >
+ Compare Prev Period
+
+
+ )}
{loading ? (
@@ -927,7 +809,7 @@ const SalesChart = ({ timeRange = "last30days", title = "Sales Overview" }) => {
className="text-xs text-muted-foreground"
tick={{ fill: "currentColor" }}
/>
- } />
+ } />
(
{(reasonsAnswer?.choices?.labels || []).map((label, idx) => (
-
+
{label}
-
+
))}
{reasonsAnswer?.choices?.other && (
-
+
{reasonsAnswer.choices.other}
-
+
)}
{feedbackAnswer?.text && (
@@ -325,6 +317,28 @@ const TypeformDashboard = () => {
const newestResponse = getNewestResponse();
+ // Column definitions for reasons table
+ const reasonsColumns = [
+ {
+ key: "reason",
+ header: "Reason",
+ render: (value) => {value} ,
+ },
+ {
+ key: "count",
+ header: "Count",
+ align: "right",
+ render: (value) => {value} ,
+ },
+ {
+ key: "percentage",
+ header: "%",
+ align: "right",
+ width: "w-[80px]",
+ render: (value) => {value}% ,
+ },
+ ];
+
if (error) {
return (
@@ -554,41 +568,13 @@ const TypeformDashboard = () => {
-
-
-
-
-
- Reason
-
-
- Count
-
-
- %
-
-
-
-
- {metrics.winback.reasons.map((reason, index) => (
-
-
- {reason.reason}
-
-
- {reason.count}
-
-
- {reason.percentage}%
-
-
- ))}
-
-
-
+ `${reason.reason}-${index}`}
+ maxHeight="md"
+ compact
+ />
diff --git a/inventory/src/components/dashboard/UserBehaviorDashboard.jsx b/inventory/src/components/dashboard/UserBehaviorDashboard.jsx
index 1fd3697..6de6cac 100644
--- a/inventory/src/components/dashboard/UserBehaviorDashboard.jsx
+++ b/inventory/src/components/dashboard/UserBehaviorDashboard.jsx
@@ -8,14 +8,6 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
-import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
-} from "@/components/ui/table";
import {
PieChart,
Pie,
@@ -26,6 +18,8 @@ import {
import { CARD_STYLES } from "@/lib/dashboard/designTokens";
import {
DashboardSectionHeader,
+ DashboardTable,
+ DashboardChartTooltip,
TableSkeleton,
ChartSkeleton,
TOOLTIP_STYLES,
@@ -104,10 +98,7 @@ export const UserBehaviorDashboard = () => {
throw new Error("Invalid response structure");
}
- // Handle both data structures
const rawData = result.data?.data || result.data;
-
- // Try to access the data differently based on the structure
const pageResponse = rawData?.pageResponse || rawData?.reports?.[0];
const deviceResponse = rawData?.deviceResponse || rawData?.reports?.[1];
const sourceResponse = rawData?.sourceResponse || rawData?.reports?.[2];
@@ -122,7 +113,7 @@ export const UserBehaviorDashboard = () => {
sourceData: processSourceData(sourceResponse),
},
};
-
+
setData(processed);
} catch (error) {
console.error("Failed to fetch behavior data:", error);
@@ -133,6 +124,74 @@ export const UserBehaviorDashboard = () => {
fetchData();
}, [timeRange]);
+ const formatDuration = (seconds) => {
+ const minutes = Math.floor(seconds / 60);
+ const remainingSeconds = Math.floor(seconds % 60);
+ return `${minutes}m ${remainingSeconds}s`;
+ };
+
+ // Column definitions for pages table
+ const pagesColumns = [
+ {
+ key: "path",
+ header: "Page Path",
+ render: (value) =>
{value} ,
+ },
+ {
+ key: "pageViews",
+ header: "Views",
+ align: "right",
+ render: (value) =>
{value.toLocaleString()} ,
+ },
+ {
+ key: "bounceRate",
+ header: "Bounce Rate",
+ align: "right",
+ render: (value) =>
{value.toFixed(1)}% ,
+ },
+ {
+ key: "avgSessionDuration",
+ header: "Avg. Duration",
+ align: "right",
+ render: (value) =>
{formatDuration(value)} ,
+ },
+ ];
+
+ // Column definitions for sources table
+ const sourcesColumns = [
+ {
+ key: "source",
+ header: "Source",
+ width: "w-[35%] min-w-[120px]",
+ render: (value) =>
{value} ,
+ },
+ {
+ key: "sessions",
+ header: "Sessions",
+ align: "right",
+ width: "w-[20%] min-w-[80px]",
+ render: (value) =>
{value.toLocaleString()} ,
+ },
+ {
+ key: "conversions",
+ header: "Conv.",
+ align: "right",
+ width: "w-[20%] min-w-[80px]",
+ render: (value) =>
{value.toLocaleString()} ,
+ },
+ {
+ key: "conversionRate",
+ header: "Conv. Rate",
+ align: "right",
+ width: "w-[25%] min-w-[80px]",
+ render: (_, row) => (
+
+ {((row.conversions / row.sessions) * 100).toFixed(1)}%
+
+ ),
+ },
+ ];
+
if (loading) {
return (
@@ -180,41 +239,33 @@ export const UserBehaviorDashboard = () => {
0
);
- const CustomTooltip = ({ active, payload }) => {
- if (active && payload && payload.length) {
- const data = payload[0].payload;
- const percentage = ((data.pageViews / totalViews) * 100).toFixed(1);
- const sessionPercentage = ((data.sessions / totalSessions) * 100).toFixed(1);
- const color = COLORS[data.device.toLowerCase()];
- return (
-
-
{data.device}
-
-
-
-
- Views
-
-
{data.pageViews.toLocaleString()} ({percentage}%)
-
-
-
-
- Sessions
-
-
{data.sessions.toLocaleString()} ({sessionPercentage}%)
-
-
-
- );
- }
- return null;
- };
+ // Custom item renderer for the device tooltip - renders both Views and Sessions rows
+ const deviceTooltipRenderer = (item, index) => {
+ if (index > 0) return null; // Only render for the first item (pie chart sends single slice)
- const formatDuration = (seconds) => {
- const minutes = Math.floor(seconds / 60);
- const remainingSeconds = Math.floor(seconds % 60);
- return `${minutes}m ${remainingSeconds}s`;
+ const deviceData = item.payload;
+ const color = COLORS[deviceData.device.toLowerCase()];
+ const viewsPercentage = ((deviceData.pageViews / totalViews) * 100).toFixed(1);
+ const sessionsPercentage = ((deviceData.sessions / totalSessions) * 100).toFixed(1);
+
+ return (
+ <>
+
+
+
+ Views
+
+
{deviceData.pageViews.toLocaleString()} ({viewsPercentage}%)
+
+
+
+
+ Sessions
+
+
{deviceData.sessions.toLocaleString()} ({sessionsPercentage}%)
+
+ >
+ );
};
return (
@@ -249,78 +300,27 @@ export const UserBehaviorDashboard = () => {
Device Usage
-
-
-
-
- Page Path
- Views
- Bounce Rate
- Avg. Duration
-
-
-
- {data?.data?.pageData?.pageData.map((page, index) => (
-
-
- {page.path}
-
-
- {page.pageViews.toLocaleString()}
-
-
- {page.bounceRate.toFixed(1)}%
-
-
- {formatDuration(page.avgSessionDuration)}
-
-
- ))}
-
-
+
+ `${page.path}-${index}`}
+ maxHeight="xl"
+ compact
+ />
-
-
-
-
- Source
- Sessions
- Conv.
- Conv. Rate
-
-
-
- {data?.data?.sourceData?.map((source, index) => (
-
-
- {source.source}
-
-
- {source.sessions.toLocaleString()}
-
-
- {source.conversions.toLocaleString()}
-
-
- {((source.conversions / source.sessions) * 100).toFixed(1)}%
-
-
- ))}
-
-
+
+ `${source.source}-${index}`}
+ maxHeight="xl"
+ compact
+ />
-
+
@@ -343,7 +343,14 @@ export const UserBehaviorDashboard = () => {
/>
))}
- } />
+ payload?.[0]?.payload?.device || ""}
+ itemRenderer={deviceTooltipRenderer}
+ />
+ }
+ />
@@ -354,4 +361,4 @@ export const UserBehaviorDashboard = () => {
);
};
-export default UserBehaviorDashboard;
\ No newline at end of file
+export default UserBehaviorDashboard;
diff --git a/inventory/src/components/dashboard/shared/DashboardSkeleton.tsx b/inventory/src/components/dashboard/shared/DashboardSkeleton.tsx
index 9ec362b..5b527fa 100644
--- a/inventory/src/components/dashboard/shared/DashboardSkeleton.tsx
+++ b/inventory/src/components/dashboard/shared/DashboardSkeleton.tsx
@@ -210,6 +210,8 @@ export const ChartSkeleton: React.FC = ({
// TABLE SKELETON
// =============================================================================
+export type TableSkeletonVariant = "simple" | "detailed";
+
export interface TableSkeletonProps {
/** Number of rows to show */
rows?: number;
@@ -227,6 +229,14 @@ export interface TableSkeletonProps {
scrollable?: boolean;
/** Max height for scrollable (uses SCROLL_STYLES keys) */
maxHeight?: "sm" | "md" | "lg" | "xl";
+ /**
+ * Cell layout variant:
+ * - "simple": single-line cells (default)
+ * - "detailed": multi-line cells with icon in first column and value+sublabel in others
+ */
+ variant?: TableSkeletonVariant;
+ /** Show icon placeholder in first column (only for detailed variant) */
+ hasIcon?: boolean;
}
export const TableSkeleton: React.FC = ({
@@ -238,6 +248,8 @@ export const TableSkeleton: React.FC = ({
className,
scrollable = false,
maxHeight = "md",
+ variant = "simple",
+ hasIcon = true,
}) => {
const columnCount = Array.isArray(columns) ? columns.length : columns;
const columnWidths = Array.isArray(columns)
@@ -245,13 +257,50 @@ export const TableSkeleton: React.FC = ({
: Array(columnCount).fill("w-24");
const colors = COLOR_VARIANT_CLASSES[colorVariant];
+ // Simple variant - single line cells
+ const renderSimpleCell = (colIndex: number) => (
+
+ );
+
+ // Detailed variant - first column has icon + stacked text, others have value + sublabel
+ const renderDetailedFirstCell = () => (
+
+ {hasIcon &&
}
+
+
+
+
+
+
+ );
+
+ const renderDetailedMetricCell = () => (
+
+
+
+
+ );
+
const tableContent = (
{Array.from({ length: columnCount }).map((_, i) => (
-
-
+
+
))}
@@ -260,14 +309,12 @@ export const TableSkeleton: React.FC = ({
{Array.from({ length: rows }).map((_, rowIndex) => (
{Array.from({ length: columnCount }).map((_, colIndex) => (
-
-
+
+ {variant === "detailed" ? (
+ colIndex === 0 ? renderDetailedFirstCell() : renderDetailedMetricCell()
+ ) : (
+ renderSimpleCell(colIndex)
+ )}
))}
diff --git a/inventory/src/components/dashboard/shared/DashboardTable.tsx b/inventory/src/components/dashboard/shared/DashboardTable.tsx
index f7021e7..0f30491 100644
--- a/inventory/src/components/dashboard/shared/DashboardTable.tsx
+++ b/inventory/src/components/dashboard/shared/DashboardTable.tsx
@@ -55,6 +55,7 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
+import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
import {
@@ -86,6 +87,17 @@ export interface TableColumn> {
className?: string;
/** Whether to use tabular-nums for numeric values */
numeric?: boolean;
+ /** Whether this column is sortable */
+ sortable?: boolean;
+ /** Custom sort key if different from column key */
+ sortKey?: string;
+}
+
+export type SortDirection = "asc" | "desc";
+
+export interface SortConfig {
+ key: string;
+ direction: SortDirection;
}
export interface DashboardTableProps> {
@@ -119,6 +131,10 @@ export interface DashboardTableProps> {
className?: string;
/** Additional className for the table element */
tableClassName?: string;
+ /** Current sort configuration (for controlled sorting) */
+ sortConfig?: SortConfig;
+ /** Callback when a sortable column header is clicked */
+ onSort?: (key: string, direction: SortDirection) => void;
}
// =============================================================================
@@ -159,10 +175,50 @@ export function DashboardTable>({
bordered = false,
className,
tableClassName,
+ sortConfig,
+ onSort,
}: DashboardTableProps): React.ReactElement {
const paddingClass = compact ? "px-3 py-2" : "px-4 py-3";
const scrollClass = maxHeight !== "none" ? MAX_HEIGHT_CLASSES[maxHeight] : "";
+ // Handle sort click - toggles direction or sets new sort key
+ const handleSortClick = (col: TableColumn) => {
+ if (!onSort || !col.sortable) return;
+
+ const sortKey = col.sortKey || col.key;
+ const currentDirection = sortConfig?.key === sortKey ? sortConfig.direction : null;
+ const newDirection: SortDirection = currentDirection === "desc" ? "asc" : "desc";
+
+ onSort(sortKey, newDirection);
+ };
+
+ // Render header cell content - either plain text or sortable button
+ const renderHeaderContent = (col: TableColumn) => {
+ if (!col.sortable || !onSort) {
+ return col.header;
+ }
+
+ const sortKey = col.sortKey || col.key;
+ const isActive = sortConfig?.key === sortKey;
+
+ return (
+ handleSortClick(col)}
+ className={cn(
+ "h-8 font-medium",
+ col.align === "center" && "w-full justify-center",
+ col.align === "right" && "w-full justify-end",
+ col.align === "left" && "justify-start",
+ !col.align && "justify-start"
+ )}
+ >
+ {col.header}
+
+ );
+ };
+
// Loading skeleton
if (loading) {
return (
@@ -241,13 +297,14 @@ export function DashboardTable>({
key={col.key}
className={cn(
TABLE_STYLES.headerCell,
- paddingClass,
+ // Reduce padding when sortable since button has its own padding
+ col.sortable && onSort ? "p-1" : paddingClass,
ALIGNMENT_CLASSES[col.align || "left"],
col.width,
col.hideOnMobile && "hidden sm:table-cell"
)}
>
- {col.header}
+ {renderHeaderContent(col)}
))}
diff --git a/inventory/src/components/dashboard/shared/index.ts b/inventory/src/components/dashboard/shared/index.ts
index 9d3d97d..615c6e5 100644
--- a/inventory/src/components/dashboard/shared/index.ts
+++ b/inventory/src/components/dashboard/shared/index.ts
@@ -72,6 +72,8 @@ export {
type CellAlignment,
type SimpleTableProps,
type SimpleTableRow,
+ type SortDirection,
+ type SortConfig,
} from "./DashboardTable";
// =============================================================================
@@ -133,6 +135,7 @@ export {
// Types
type ChartSkeletonProps,
type TableSkeletonProps,
+ type TableSkeletonVariant,
type StatCardSkeletonProps,
type GridSkeletonProps,
type ListSkeletonProps,
diff --git a/inventory/tsconfig.tsbuildinfo b/inventory/tsconfig.tsbuildinfo
index 1b9639d..339c2a4 100644
--- a/inventory/tsconfig.tsbuildinfo
+++ b/inventory/tsconfig.tsbuildinfo
@@ -1 +1 @@
-{"root":["./src/app.tsx","./src/config.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/config.ts","./src/components/analytics/categoryperformance.tsx","./src/components/analytics/priceanalysis.tsx","./src/components/analytics/profitanalysis.tsx","./src/components/analytics/stockanalysis.tsx","./src/components/analytics/vendorperformance.tsx","./src/components/auth/firstaccessiblepage.tsx","./src/components/auth/protected.tsx","./src/components/auth/requireauth.tsx","./src/components/chat/chatroom.tsx","./src/components/chat/chattest.tsx","./src/components/chat/roomlist.tsx","./src/components/chat/searchresults.tsx","./src/components/dashboard/financialoverview.tsx","./src/components/dashboard/periodselectionpopover.tsx","./src/components/discount-simulator/configpanel.tsx","./src/components/discount-simulator/resultschart.tsx","./src/components/discount-simulator/resultstable.tsx","./src/components/discount-simulator/summarycard.tsx","./src/components/forecasting/daterangepickerquick.tsx","./src/components/forecasting/quickorderbuilder.tsx","./src/components/forecasting/columns.tsx","./src/components/layout/appsidebar.tsx","./src/components/layout/mainlayout.tsx","./src/components/layout/navuser.tsx","./src/components/overview/bestsellers.tsx","./src/components/overview/forecastmetrics.tsx","./src/components/overview/overstockmetrics.tsx","./src/components/overview/overview.tsx","./src/components/overview/purchasemetrics.tsx","./src/components/overview/replenishmentmetrics.tsx","./src/components/overview/salesmetrics.tsx","./src/components/overview/stockmetrics.tsx","./src/components/overview/topoverstockedproducts.tsx","./src/components/overview/topreplenishproducts.tsx","./src/components/overview/vendorperformance.tsx","./src/components/product-import/createproductcategorydialog.tsx","./src/components/product-import/reactspreadsheetimport.tsx","./src/components/product-import/config.ts","./src/components/product-import/index.ts","./src/components/product-import/translationsrsiprops.ts","./src/components/product-import/types.ts","./src/components/product-import/components/modalwrapper.tsx","./src/components/product-import/components/providers.tsx","./src/components/product-import/components/table.tsx","./src/components/product-import/hooks/usersi.ts","./src/components/product-import/steps/steps.tsx","./src/components/product-import/steps/uploadflow.tsx","./src/components/product-import/steps/imageuploadstep/imageuploadstep.tsx","./src/components/product-import/steps/imageuploadstep/types.ts","./src/components/product-import/steps/imageuploadstep/components/droppablecontainer.tsx","./src/components/product-import/steps/imageuploadstep/components/genericdropzone.tsx","./src/components/product-import/steps/imageuploadstep/components/unassignedimagessection.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/copybutton.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/imagedropzone.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/productcard.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/sortableimage.tsx","./src/components/product-import/steps/imageuploadstep/components/unassignedimagessection/unassignedimageitem.tsx","./src/components/product-import/steps/imageuploadstep/hooks/usebulkimageupload.ts","./src/components/product-import/steps/imageuploadstep/hooks/usedraganddrop.ts","./src/components/product-import/steps/imageuploadstep/hooks/useproductimageoperations.ts","./src/components/product-import/steps/imageuploadstep/hooks/useproductimagesinit.ts","./src/components/product-import/steps/imageuploadstep/hooks/useurlimageupload.ts","./src/components/product-import/steps/matchcolumnsstep/matchcolumnsstep.tsx","./src/components/product-import/steps/matchcolumnsstep/types.ts","./src/components/product-import/steps/matchcolumnsstep/components/matchicon.tsx","./src/components/product-import/steps/matchcolumnsstep/components/templatecolumn.tsx","./src/components/product-import/steps/matchcolumnsstep/utils/findmatch.ts","./src/components/product-import/steps/matchcolumnsstep/utils/findunmatchedrequiredfields.ts","./src/components/product-import/steps/matchcolumnsstep/utils/getfieldoptions.ts","./src/components/product-import/steps/matchcolumnsstep/utils/getmatchedcolumns.ts","./src/components/product-import/steps/matchcolumnsstep/utils/normalizecheckboxvalue.ts","./src/components/product-import/steps/matchcolumnsstep/utils/normalizetabledata.ts","./src/components/product-import/steps/matchcolumnsstep/utils/setcolumn.ts","./src/components/product-import/steps/matchcolumnsstep/utils/setignorecolumn.ts","./src/components/product-import/steps/matchcolumnsstep/utils/setsubcolumn.ts","./src/components/product-import/steps/matchcolumnsstep/utils/uniqueentries.ts","./src/components/product-import/steps/selectheaderstep/selectheaderstep.tsx","./src/components/product-import/steps/selectheaderstep/components/selectheadertable.tsx","./src/components/product-import/steps/selectheaderstep/components/columns.tsx","./src/components/product-import/steps/selectsheetstep/selectsheetstep.tsx","./src/components/product-import/steps/uploadstep/uploadstep.tsx","./src/components/product-import/steps/uploadstep/components/dropzone.tsx","./src/components/product-import/steps/uploadstep/components/columns.tsx","./src/components/product-import/steps/uploadstep/utils/readfilesasync.ts","./src/components/product-import/steps/validationstepnew/index.tsx","./src/components/product-import/steps/validationstepnew/types.ts","./src/components/product-import/steps/validationstepnew/components/aivalidationdialogs.tsx","./src/components/product-import/steps/validationstepnew/components/basecellcontent.tsx","./src/components/product-import/steps/validationstepnew/components/initializingvalidation.tsx","./src/components/product-import/steps/validationstepnew/components/searchabletemplateselect.tsx","./src/components/product-import/steps/validationstepnew/components/upcvalidationtableadapter.tsx","./src/components/product-import/steps/validationstepnew/components/validationcell.tsx","./src/components/product-import/steps/validationstepnew/components/validationcontainer.tsx","./src/components/product-import/steps/validationstepnew/components/validationtable.tsx","./src/components/product-import/steps/validationstepnew/components/cells/checkboxcell.tsx","./src/components/product-import/steps/validationstepnew/components/cells/inputcell.tsx","./src/components/product-import/steps/validationstepnew/components/cells/multiselectcell.tsx","./src/components/product-import/steps/validationstepnew/components/cells/multilineinput.tsx","./src/components/product-import/steps/validationstepnew/components/cells/selectcell.tsx","./src/components/product-import/steps/validationstepnew/hooks/useaivalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usefieldvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usefiltermanagement.tsx","./src/components/product-import/steps/validationstepnew/hooks/useinitialvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/useproductlinesfetching.tsx","./src/components/product-import/steps/validationstepnew/hooks/userowoperations.tsx","./src/components/product-import/steps/validationstepnew/hooks/usetemplatemanagement.tsx","./src/components/product-import/steps/validationstepnew/hooks/useuniqueitemnumbersvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/useuniquevalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/useupcvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usevalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usevalidationstate.tsx","./src/components/product-import/steps/validationstepnew/hooks/validationtypes.ts","./src/components/product-import/steps/validationstepnew/types/index.ts","./src/components/product-import/steps/validationstepnew/utils/aivalidationutils.ts","./src/components/product-import/steps/validationstepnew/utils/countryutils.ts","./src/components/product-import/steps/validationstepnew/utils/datamutations.ts","./src/components/product-import/steps/validationstepnew/utils/priceutils.ts","./src/components/product-import/steps/validationstepnew/utils/upcutils.ts","./src/components/product-import/utils/exceedsmaxrecords.ts","./src/components/product-import/utils/mapdata.ts","./src/components/product-import/utils/mapworkbook.ts","./src/components/product-import/utils/steps.ts","./src/components/products/productdetail.tsx","./src/components/products/productfilters.tsx","./src/components/products/producttable.tsx","./src/components/products/producttableskeleton.tsx","./src/components/products/productviews.tsx","./src/components/products/products.tsx","./src/components/purchase-orders/categorymetricscard.tsx","./src/components/purchase-orders/filtercontrols.tsx","./src/components/purchase-orders/ordermetricscard.tsx","./src/components/purchase-orders/paginationcontrols.tsx","./src/components/purchase-orders/purchaseorderaccordion.tsx","./src/components/purchase-orders/purchaseorderstable.tsx","./src/components/purchase-orders/vendormetricscard.tsx","./src/components/settings/datamanagement.tsx","./src/components/settings/globalsettings.tsx","./src/components/settings/permissionselector.tsx","./src/components/settings/productsettings.tsx","./src/components/settings/promptmanagement.tsx","./src/components/settings/reusableimagemanagement.tsx","./src/components/settings/templatemanagement.tsx","./src/components/settings/userform.tsx","./src/components/settings/userlist.tsx","./src/components/settings/usermanagement.tsx","./src/components/settings/vendorsettings.tsx","./src/components/templates/searchproducttemplatedialog.tsx","./src/components/templates/templateform.tsx","./src/components/ui/accordion.tsx","./src/components/ui/alert-dialog.tsx","./src/components/ui/alert.tsx","./src/components/ui/avatar.tsx","./src/components/ui/badge.tsx","./src/components/ui/button.tsx","./src/components/ui/calendar.tsx","./src/components/ui/card.tsx","./src/components/ui/checkbox.tsx","./src/components/ui/code.tsx","./src/components/ui/collapsible.tsx","./src/components/ui/command.tsx","./src/components/ui/date-range-picker-narrow.tsx","./src/components/ui/date-range-picker.tsx","./src/components/ui/dialog.tsx","./src/components/ui/drawer.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/form.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/page-loading.tsx","./src/components/ui/pagination.tsx","./src/components/ui/popover.tsx","./src/components/ui/progress.tsx","./src/components/ui/radio-group.tsx","./src/components/ui/scroll-area.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/sheet.tsx","./src/components/ui/sidebar.tsx","./src/components/ui/skeleton.tsx","./src/components/ui/sonner.tsx","./src/components/ui/switch.tsx","./src/components/ui/table.tsx","./src/components/ui/tabs.tsx","./src/components/ui/textarea.tsx","./src/components/ui/toast.tsx","./src/components/ui/toaster.tsx","./src/components/ui/toggle-group.tsx","./src/components/ui/toggle.tsx","./src/components/ui/tooltip.tsx","./src/config/dashboard.ts","./src/contexts/authcontext.tsx","./src/contexts/dashboardscrollcontext.tsx","./src/hooks/use-mobile.tsx","./src/hooks/use-toast.ts","./src/hooks/usedebounce.ts","./src/lib/utils.ts","./src/pages/analytics.tsx","./src/pages/blackfridaydashboard.tsx","./src/pages/brands.tsx","./src/pages/categories.tsx","./src/pages/chat.tsx","./src/pages/dashboard.tsx","./src/pages/discountsimulator.tsx","./src/pages/forecasting.tsx","./src/pages/htslookup.tsx","./src/pages/import.tsx","./src/pages/login.tsx","./src/pages/overview.tsx","./src/pages/products.tsx","./src/pages/purchaseorders.tsx","./src/pages/settings.tsx","./src/pages/smalldashboard.tsx","./src/pages/vendors.tsx","./src/services/apiv2.ts","./src/types/dashboard-shims.d.ts","./src/types/dashboard.d.ts","./src/types/discount-simulator.ts","./src/types/globals.d.ts","./src/types/products.ts","./src/types/react-data-grid.d.ts","./src/types/status-codes.ts","./src/utils/emojiutils.ts","./src/utils/naturallanguageperiod.ts","./src/utils/productutils.ts"],"version":"5.6.3"}
\ No newline at end of file
+{"root":["./src/app.tsx","./src/config.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/config.ts","./src/components/analytics/categoryperformance.tsx","./src/components/analytics/priceanalysis.tsx","./src/components/analytics/profitanalysis.tsx","./src/components/analytics/stockanalysis.tsx","./src/components/analytics/vendorperformance.tsx","./src/components/auth/firstaccessiblepage.tsx","./src/components/auth/protected.tsx","./src/components/auth/requireauth.tsx","./src/components/chat/chatroom.tsx","./src/components/chat/chattest.tsx","./src/components/chat/roomlist.tsx","./src/components/chat/searchresults.tsx","./src/components/dashboard/financialoverview.tsx","./src/components/dashboard/periodselectionpopover.tsx","./src/components/dashboard/shared/dashboardbadge.tsx","./src/components/dashboard/shared/dashboardcharttooltip.tsx","./src/components/dashboard/shared/dashboardsectionheader.tsx","./src/components/dashboard/shared/dashboardskeleton.tsx","./src/components/dashboard/shared/dashboardstatcard.tsx","./src/components/dashboard/shared/dashboardstatcardmini.tsx","./src/components/dashboard/shared/dashboardstates.tsx","./src/components/dashboard/shared/dashboardtable.tsx","./src/components/dashboard/shared/index.ts","./src/components/discount-simulator/configpanel.tsx","./src/components/discount-simulator/resultschart.tsx","./src/components/discount-simulator/resultstable.tsx","./src/components/discount-simulator/summarycard.tsx","./src/components/forecasting/daterangepickerquick.tsx","./src/components/forecasting/quickorderbuilder.tsx","./src/components/forecasting/columns.tsx","./src/components/layout/appsidebar.tsx","./src/components/layout/mainlayout.tsx","./src/components/layout/navuser.tsx","./src/components/overview/bestsellers.tsx","./src/components/overview/forecastmetrics.tsx","./src/components/overview/overstockmetrics.tsx","./src/components/overview/overview.tsx","./src/components/overview/purchasemetrics.tsx","./src/components/overview/replenishmentmetrics.tsx","./src/components/overview/salesmetrics.tsx","./src/components/overview/stockmetrics.tsx","./src/components/overview/topoverstockedproducts.tsx","./src/components/overview/topreplenishproducts.tsx","./src/components/overview/vendorperformance.tsx","./src/components/product-import/createproductcategorydialog.tsx","./src/components/product-import/reactspreadsheetimport.tsx","./src/components/product-import/config.ts","./src/components/product-import/index.ts","./src/components/product-import/translationsrsiprops.ts","./src/components/product-import/types.ts","./src/components/product-import/components/modalwrapper.tsx","./src/components/product-import/components/providers.tsx","./src/components/product-import/components/table.tsx","./src/components/product-import/hooks/usersi.ts","./src/components/product-import/steps/steps.tsx","./src/components/product-import/steps/uploadflow.tsx","./src/components/product-import/steps/imageuploadstep/imageuploadstep.tsx","./src/components/product-import/steps/imageuploadstep/types.ts","./src/components/product-import/steps/imageuploadstep/components/droppablecontainer.tsx","./src/components/product-import/steps/imageuploadstep/components/genericdropzone.tsx","./src/components/product-import/steps/imageuploadstep/components/unassignedimagessection.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/copybutton.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/imagedropzone.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/productcard.tsx","./src/components/product-import/steps/imageuploadstep/components/productcard/sortableimage.tsx","./src/components/product-import/steps/imageuploadstep/components/unassignedimagessection/unassignedimageitem.tsx","./src/components/product-import/steps/imageuploadstep/hooks/usebulkimageupload.ts","./src/components/product-import/steps/imageuploadstep/hooks/usedraganddrop.ts","./src/components/product-import/steps/imageuploadstep/hooks/useproductimageoperations.ts","./src/components/product-import/steps/imageuploadstep/hooks/useproductimagesinit.ts","./src/components/product-import/steps/imageuploadstep/hooks/useurlimageupload.ts","./src/components/product-import/steps/matchcolumnsstep/matchcolumnsstep.tsx","./src/components/product-import/steps/matchcolumnsstep/types.ts","./src/components/product-import/steps/matchcolumnsstep/components/matchicon.tsx","./src/components/product-import/steps/matchcolumnsstep/components/templatecolumn.tsx","./src/components/product-import/steps/matchcolumnsstep/utils/findmatch.ts","./src/components/product-import/steps/matchcolumnsstep/utils/findunmatchedrequiredfields.ts","./src/components/product-import/steps/matchcolumnsstep/utils/getfieldoptions.ts","./src/components/product-import/steps/matchcolumnsstep/utils/getmatchedcolumns.ts","./src/components/product-import/steps/matchcolumnsstep/utils/normalizecheckboxvalue.ts","./src/components/product-import/steps/matchcolumnsstep/utils/normalizetabledata.ts","./src/components/product-import/steps/matchcolumnsstep/utils/setcolumn.ts","./src/components/product-import/steps/matchcolumnsstep/utils/setignorecolumn.ts","./src/components/product-import/steps/matchcolumnsstep/utils/setsubcolumn.ts","./src/components/product-import/steps/matchcolumnsstep/utils/uniqueentries.ts","./src/components/product-import/steps/selectheaderstep/selectheaderstep.tsx","./src/components/product-import/steps/selectheaderstep/components/selectheadertable.tsx","./src/components/product-import/steps/selectheaderstep/components/columns.tsx","./src/components/product-import/steps/selectsheetstep/selectsheetstep.tsx","./src/components/product-import/steps/uploadstep/uploadstep.tsx","./src/components/product-import/steps/uploadstep/components/dropzone.tsx","./src/components/product-import/steps/uploadstep/components/columns.tsx","./src/components/product-import/steps/uploadstep/utils/readfilesasync.ts","./src/components/product-import/steps/validationstep/index.tsx","./src/components/product-import/steps/validationstep/components/copydownbanner.tsx","./src/components/product-import/steps/validationstep/components/floatingselectionbar.tsx","./src/components/product-import/steps/validationstep/components/initializingoverlay.tsx","./src/components/product-import/steps/validationstep/components/searchabletemplateselect.tsx","./src/components/product-import/steps/validationstep/components/validationcontainer.tsx","./src/components/product-import/steps/validationstep/components/validationfooter.tsx","./src/components/product-import/steps/validationstep/components/validationtable.tsx","./src/components/product-import/steps/validationstep/components/validationtoolbar.tsx","./src/components/product-import/steps/validationstep/components/cells/checkboxcell.tsx","./src/components/product-import/steps/validationstep/components/cells/comboboxcell.tsx","./src/components/product-import/steps/validationstep/components/cells/inputcell.tsx","./src/components/product-import/steps/validationstep/components/cells/multiselectcell.tsx","./src/components/product-import/steps/validationstep/components/cells/multilineinput.tsx","./src/components/product-import/steps/validationstep/components/cells/selectcell.tsx","./src/components/product-import/steps/validationstep/dialogs/aidebugdialog.tsx","./src/components/product-import/steps/validationstep/dialogs/aivalidationprogress.tsx","./src/components/product-import/steps/validationstep/dialogs/aivalidationresults.tsx","./src/components/product-import/steps/validationstep/hooks/usefieldoptions.ts","./src/components/product-import/steps/validationstep/hooks/useproductlines.ts","./src/components/product-import/steps/validationstep/hooks/usetemplatemanagement.ts","./src/components/product-import/steps/validationstep/hooks/useupcvalidation.ts","./src/components/product-import/steps/validationstep/hooks/usevalidationactions.ts","./src/components/product-import/steps/validationstep/hooks/useaivalidation/index.ts","./src/components/product-import/steps/validationstep/hooks/useaivalidation/useaiapi.ts","./src/components/product-import/steps/validationstep/hooks/useaivalidation/useaiprogress.ts","./src/components/product-import/steps/validationstep/hooks/useaivalidation/useaitransform.ts","./src/components/product-import/steps/validationstep/store/selectors.ts","./src/components/product-import/steps/validationstep/store/types.ts","./src/components/product-import/steps/validationstep/store/validationstore.ts","./src/components/product-import/steps/validationstep/utils/aivalidationutils.ts","./src/components/product-import/steps/validationstep/utils/countryutils.ts","./src/components/product-import/steps/validationstep/utils/datamutations.ts","./src/components/product-import/steps/validationstep/utils/priceutils.ts","./src/components/product-import/steps/validationstep/utils/upcutils.ts","./src/components/product-import/steps/validationstepnew/index.tsx","./src/components/product-import/steps/validationstepnew/types.ts","./src/components/product-import/steps/validationstepnew/components/aivalidationdialogs.tsx","./src/components/product-import/steps/validationstepnew/components/basecellcontent.tsx","./src/components/product-import/steps/validationstepnew/components/initializingvalidation.tsx","./src/components/product-import/steps/validationstepnew/components/searchabletemplateselect.tsx","./src/components/product-import/steps/validationstepnew/components/upcvalidationtableadapter.tsx","./src/components/product-import/steps/validationstepnew/components/validationcell.tsx","./src/components/product-import/steps/validationstepnew/components/validationcontainer.tsx","./src/components/product-import/steps/validationstepnew/components/validationtable.tsx","./src/components/product-import/steps/validationstepnew/components/cells/checkboxcell.tsx","./src/components/product-import/steps/validationstepnew/components/cells/inputcell.tsx","./src/components/product-import/steps/validationstepnew/components/cells/multiselectcell.tsx","./src/components/product-import/steps/validationstepnew/components/cells/multilineinput.tsx","./src/components/product-import/steps/validationstepnew/components/cells/selectcell.tsx","./src/components/product-import/steps/validationstepnew/hooks/useaivalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usefieldvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usefiltermanagement.tsx","./src/components/product-import/steps/validationstepnew/hooks/useinitialvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/useproductlinesfetching.tsx","./src/components/product-import/steps/validationstepnew/hooks/userowoperations.tsx","./src/components/product-import/steps/validationstepnew/hooks/usetemplatemanagement.tsx","./src/components/product-import/steps/validationstepnew/hooks/useuniqueitemnumbersvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/useuniquevalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/useupcvalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usevalidation.tsx","./src/components/product-import/steps/validationstepnew/hooks/usevalidationstate.tsx","./src/components/product-import/steps/validationstepnew/hooks/validationtypes.ts","./src/components/product-import/steps/validationstepnew/types/index.ts","./src/components/product-import/steps/validationstepnew/utils/aivalidationutils.ts","./src/components/product-import/steps/validationstepnew/utils/countryutils.ts","./src/components/product-import/steps/validationstepnew/utils/datamutations.ts","./src/components/product-import/steps/validationstepnew/utils/priceutils.ts","./src/components/product-import/steps/validationstepnew/utils/upcutils.ts","./src/components/product-import/utils/exceedsmaxrecords.ts","./src/components/product-import/utils/mapdata.ts","./src/components/product-import/utils/mapworkbook.ts","./src/components/product-import/utils/steps.ts","./src/components/products/productdetail.tsx","./src/components/products/productfilters.tsx","./src/components/products/producttable.tsx","./src/components/products/producttableskeleton.tsx","./src/components/products/productviews.tsx","./src/components/products/products.tsx","./src/components/purchase-orders/categorymetricscard.tsx","./src/components/purchase-orders/filtercontrols.tsx","./src/components/purchase-orders/ordermetricscard.tsx","./src/components/purchase-orders/paginationcontrols.tsx","./src/components/purchase-orders/purchaseorderaccordion.tsx","./src/components/purchase-orders/purchaseorderstable.tsx","./src/components/purchase-orders/vendormetricscard.tsx","./src/components/settings/datamanagement.tsx","./src/components/settings/globalsettings.tsx","./src/components/settings/permissionselector.tsx","./src/components/settings/productsettings.tsx","./src/components/settings/promptmanagement.tsx","./src/components/settings/reusableimagemanagement.tsx","./src/components/settings/templatemanagement.tsx","./src/components/settings/userform.tsx","./src/components/settings/userlist.tsx","./src/components/settings/usermanagement.tsx","./src/components/settings/vendorsettings.tsx","./src/components/templates/searchproducttemplatedialog.tsx","./src/components/templates/templateform.tsx","./src/components/ui/accordion.tsx","./src/components/ui/alert-dialog.tsx","./src/components/ui/alert.tsx","./src/components/ui/avatar.tsx","./src/components/ui/badge.tsx","./src/components/ui/button.tsx","./src/components/ui/calendar.tsx","./src/components/ui/card.tsx","./src/components/ui/checkbox.tsx","./src/components/ui/code.tsx","./src/components/ui/collapsible.tsx","./src/components/ui/command.tsx","./src/components/ui/date-range-picker-narrow.tsx","./src/components/ui/date-range-picker.tsx","./src/components/ui/dialog.tsx","./src/components/ui/drawer.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/form.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/page-loading.tsx","./src/components/ui/pagination.tsx","./src/components/ui/popover.tsx","./src/components/ui/progress.tsx","./src/components/ui/radio-group.tsx","./src/components/ui/scroll-area.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/sheet.tsx","./src/components/ui/sidebar.tsx","./src/components/ui/skeleton.tsx","./src/components/ui/sonner.tsx","./src/components/ui/switch.tsx","./src/components/ui/table.tsx","./src/components/ui/tabs.tsx","./src/components/ui/textarea.tsx","./src/components/ui/toast.tsx","./src/components/ui/toaster.tsx","./src/components/ui/toggle-group.tsx","./src/components/ui/toggle.tsx","./src/components/ui/tooltip.tsx","./src/config/dashboard.ts","./src/contexts/authcontext.tsx","./src/contexts/dashboardscrollcontext.tsx","./src/hooks/use-mobile.tsx","./src/hooks/use-toast.ts","./src/hooks/usedebounce.ts","./src/lib/utils.ts","./src/lib/dashboard/chartconfig.ts","./src/lib/dashboard/designtokens.ts","./src/pages/analytics.tsx","./src/pages/blackfridaydashboard.tsx","./src/pages/brands.tsx","./src/pages/categories.tsx","./src/pages/chat.tsx","./src/pages/dashboard.tsx","./src/pages/discountsimulator.tsx","./src/pages/forecasting.tsx","./src/pages/htslookup.tsx","./src/pages/import.tsx","./src/pages/login.tsx","./src/pages/overview.tsx","./src/pages/products.tsx","./src/pages/purchaseorders.tsx","./src/pages/settings.tsx","./src/pages/smalldashboard.tsx","./src/pages/vendors.tsx","./src/services/apiv2.ts","./src/types/dashboard-shims.d.ts","./src/types/dashboard.d.ts","./src/types/discount-simulator.ts","./src/types/globals.d.ts","./src/types/products.ts","./src/types/react-data-grid.d.ts","./src/types/status-codes.ts","./src/utils/emojiutils.ts","./src/utils/naturallanguageperiod.ts","./src/utils/productutils.ts"],"errors":true,"version":"5.6.3"}
\ No newline at end of file