Fix details dialogs mobile width
This commit is contained in:
@@ -302,7 +302,7 @@ export const AnalyticsDashboard = () => {
|
|||||||
Details
|
Details
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="min-w-[600px] max-w-[90vw] w-fit max-h-[85vh] overflow-hidden flex flex-col bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
<DialogContent className="max-w-[95vw] w-fit max-h-[85vh] overflow-hidden flex flex-col bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
||||||
<DialogHeader className="flex-none">
|
<DialogHeader className="flex-none">
|
||||||
<DialogTitle className="text-gray-900 dark:text-gray-100">Daily Details</DialogTitle>
|
<DialogTitle className="text-gray-900 dark:text-gray-100">Daily Details</DialogTitle>
|
||||||
<div className="flex items-center justify-center gap-2 pt-4">
|
<div className="flex items-center justify-center gap-2 pt-4">
|
||||||
|
|||||||
@@ -530,7 +530,8 @@ const SkeletonChart = () => (
|
|||||||
<div
|
<div
|
||||||
className="absolute inset-0 bg-muted/50"
|
className="absolute inset-0 bg-muted/50"
|
||||||
style={{
|
style={{
|
||||||
clipPath: "polygon(0 50%, 20% 20%, 40% 40%, 60% 30%, 80% 60%, 100% 40%, 100% 100%, 0 100%)",
|
clipPath:
|
||||||
|
"polygon(0 50%, 20% 20%, 40% 40%, 60% 30%, 80% 60%, 100% 40%, 100% 100%, 0 100%)",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -540,7 +541,7 @@ const SkeletonChart = () => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const SkeletonStats = () => (
|
const SkeletonStats = () => (
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-2 md:gap-3">
|
<div className="grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4 gap-2 md:gap-3">
|
||||||
{[...Array(4)].map((_, i) => (
|
{[...Array(4)].map((_, i) => (
|
||||||
<Card key={i} className="bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
<Card key={i} className="bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
||||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 p-4 pb-2">
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 p-4 pb-2">
|
||||||
@@ -569,10 +570,7 @@ const SkeletonTable = () => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const SalesChart = ({
|
const SalesChart = ({ timeRange = "last30days", title = "Sales Overview" }) => {
|
||||||
timeRange = "last30days",
|
|
||||||
title = "Sales Overview",
|
|
||||||
}) => {
|
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
@@ -690,9 +688,11 @@ const SalesChart = ({
|
|||||||
Details
|
Details
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="min-w-[600px] max-w-[90vw] w-fit max-h-[85vh] overflow-hidden flex flex-col bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
<DialogContent className="p-4 max-w-[95vw] w-fit max-h-[85vh] overflow-hidden flex flex-col bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
||||||
<DialogHeader className="flex-none">
|
<DialogHeader className="flex-none">
|
||||||
<DialogTitle className="text-gray-900 dark:text-gray-100">Daily Details</DialogTitle>
|
<DialogTitle className="text-gray-900 dark:text-gray-100">
|
||||||
|
Daily Details
|
||||||
|
</DialogTitle>
|
||||||
<div className="flex items-center justify-center gap-2 pt-4">
|
<div className="flex items-center justify-center gap-2 pt-4">
|
||||||
<div className="flex flex-wrap gap-1">
|
<div className="flex flex-wrap gap-1">
|
||||||
<Button
|
<Button
|
||||||
@@ -720,7 +720,9 @@ const SalesChart = ({
|
|||||||
Orders
|
Orders
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant={metrics.movingAverage ? "default" : "outline"}
|
variant={
|
||||||
|
metrics.movingAverage ? "default" : "outline"
|
||||||
|
}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setMetrics((prev) => ({
|
setMetrics((prev) => ({
|
||||||
@@ -732,7 +734,9 @@ const SalesChart = ({
|
|||||||
7-Day Avg
|
7-Day Avg
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant={metrics.avgOrderValue ? "default" : "outline"}
|
variant={
|
||||||
|
metrics.avgOrderValue ? "default" : "outline"
|
||||||
|
}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setMetrics((prev) => ({
|
setMetrics((prev) => ({
|
||||||
@@ -761,57 +765,65 @@ const SalesChart = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="flex-1 overflow-y-auto mt-6">
|
<div className="flex-1 overflow-auto mt-6">
|
||||||
<div className="rounded-lg border bg-white dark:bg-gray-900/60 backdrop-blur-sm w-full">
|
<div className="rounded-lg border bg-white dark:bg-gray-900/60 backdrop-blur-sm w-full">
|
||||||
<Table className="w-full">
|
<Table className="w-full">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 w-[120px]">Date</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
{metrics.orders && (
|
Date
|
||||||
|
</TableHead>
|
||||||
|
|
||||||
|
{metrics.revenue && (
|
||||||
<>
|
<>
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 min-w-[100px]">Orders</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
|
Revenue
|
||||||
|
</TableHead>
|
||||||
{metrics.showPrevious && (
|
{metrics.showPrevious && (
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 min-w-[100px]">Prev Orders</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
|
Prev Revenue
|
||||||
|
</TableHead>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{metrics.revenue && (
|
{metrics.orders && (
|
||||||
<>
|
<>
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 min-w-[140px]">Revenue</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
|
Orders
|
||||||
|
</TableHead>
|
||||||
{metrics.showPrevious && (
|
{metrics.showPrevious && (
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 min-w-[140px]">Prev Revenue</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
|
Prev Orders
|
||||||
|
</TableHead>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{metrics.avgOrderValue && (
|
{metrics.avgOrderValue && (
|
||||||
<>
|
<>
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 min-w-[120px]">AOV</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
|
AOV
|
||||||
|
</TableHead>
|
||||||
{metrics.showPrevious && (
|
{metrics.showPrevious && (
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 min-w-[120px]">Prev AOV</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
|
Prev AOV
|
||||||
|
</TableHead>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{metrics.movingAverage && (
|
{metrics.movingAverage && (
|
||||||
<TableHead className="text-center whitespace-nowrap px-6 min-w-[140px]">7-Day Avg</TableHead>
|
<TableHead className="text-center whitespace-nowrap px-6">
|
||||||
|
7-Day Avg
|
||||||
|
</TableHead>
|
||||||
)}
|
)}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{data.map((day) => (
|
{data.map((day) => (
|
||||||
<TableRow key={day.timestamp}>
|
<TableRow key={day.timestamp}>
|
||||||
<TableCell className="text-center whitespace-nowrap px-6">{formatXAxis(day.timestamp)}</TableCell>
|
<TableCell className="text-center whitespace-nowrap px-6">
|
||||||
{metrics.orders && (
|
{formatXAxis(day.timestamp)}
|
||||||
<>
|
</TableCell>
|
||||||
<TableCell className="text-center whitespace-nowrap px-6">
|
|
||||||
{day.orders.toLocaleString()}
|
|
||||||
</TableCell>
|
|
||||||
{metrics.showPrevious && (
|
|
||||||
<TableCell className="text-center whitespace-nowrap px-6">
|
|
||||||
{day.prevOrders.toLocaleString()}
|
|
||||||
</TableCell>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{metrics.revenue && (
|
{metrics.revenue && (
|
||||||
<>
|
<>
|
||||||
<TableCell className="text-center whitespace-nowrap px-6">
|
<TableCell className="text-center whitespace-nowrap px-6">
|
||||||
@@ -823,6 +835,18 @@ const SalesChart = ({
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
)}
|
||||||
|
{metrics.orders && (
|
||||||
|
<>
|
||||||
|
<TableCell className="text-center whitespace-nowrap px-6">
|
||||||
|
{day.orders.toLocaleString()}
|
||||||
|
</TableCell>
|
||||||
|
{metrics.showPrevious && (
|
||||||
|
<TableCell className="text-center whitespace-nowrap px-6">
|
||||||
|
{day.prevOrders.toLocaleString()}
|
||||||
|
</TableCell>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{metrics.avgOrderValue && (
|
{metrics.avgOrderValue && (
|
||||||
<>
|
<>
|
||||||
@@ -869,7 +893,12 @@ const SalesChart = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Show stats only if not in error state */}
|
{/* Show stats only if not in error state */}
|
||||||
{!error && (loading ? <SkeletonStats /> : <SummaryStats stats={summaryStats} />)}
|
{!error &&
|
||||||
|
(loading ? (
|
||||||
|
<SkeletonStats />
|
||||||
|
) : (
|
||||||
|
<SummaryStats stats={summaryStats} />
|
||||||
|
))}
|
||||||
|
|
||||||
{/* Show metric toggles only if not in error state */}
|
{/* Show metric toggles only if not in error state */}
|
||||||
{!error && (
|
{!error && (
|
||||||
@@ -925,8 +954,14 @@ const SalesChart = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Separator orientation="vertical" className="h-6 hidden sm:block" />
|
<Separator
|
||||||
<Separator orientation="horizontal" className="sm:hidden w-20 my-2" />
|
orientation="vertical"
|
||||||
|
className="h-6 hidden sm:block"
|
||||||
|
/>
|
||||||
|
<Separator
|
||||||
|
orientation="horizontal"
|
||||||
|
className="sm:hidden w-20 my-2"
|
||||||
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant={metrics.showPrevious ? "default" : "outline"}
|
variant={metrics.showPrevious ? "default" : "outline"}
|
||||||
@@ -955,7 +990,10 @@ const SalesChart = ({
|
|||||||
{showDailyTable && <SkeletonTable />}
|
{showDailyTable && <SkeletonTable />}
|
||||||
</div>
|
</div>
|
||||||
) : error ? (
|
) : error ? (
|
||||||
<Alert variant="destructive" className="bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
<Alert
|
||||||
|
variant="destructive"
|
||||||
|
className="bg-white dark:bg-gray-900/60 backdrop-blur-sm"
|
||||||
|
>
|
||||||
<AlertCircle className="h-4 w-4" />
|
<AlertCircle className="h-4 w-4" />
|
||||||
<AlertTitle>Error</AlertTitle>
|
<AlertTitle>Error</AlertTitle>
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
@@ -966,7 +1004,9 @@ const SalesChart = ({
|
|||||||
<div className="flex items-center justify-center h-[400px] text-muted-foreground">
|
<div className="flex items-center justify-center h-[400px] text-muted-foreground">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<TrendingUp className="h-12 w-12 mx-auto mb-4" />
|
<TrendingUp className="h-12 w-12 mx-auto mb-4" />
|
||||||
<div className="font-medium mb-2 text-gray-900 dark:text-gray-100">No sales data available</div>
|
<div className="font-medium mb-2 text-gray-900 dark:text-gray-100">
|
||||||
|
No sales data available
|
||||||
|
</div>
|
||||||
<div className="text-sm text-muted-foreground">
|
<div className="text-sm text-muted-foreground">
|
||||||
Try selecting a different time range
|
Try selecting a different time range
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user