From 42f5033173b2dfe5081363c2279315396c516ba5 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 1 Jan 2025 14:08:50 -0500 Subject: [PATCH] Remove scrollbars and last updated --- dashboard/src/App.jsx | 4 +- .../components/dashboard/MiniStatCards.jsx | 355 +++++++++--------- 2 files changed, 185 insertions(+), 174 deletions(-) diff --git a/dashboard/src/App.jsx b/dashboard/src/App.jsx index d983ed4..a5ef211 100644 --- a/dashboard/src/App.jsx +++ b/dashboard/src/App.jsx @@ -63,7 +63,7 @@ const PinProtectedLayout = ({ children }) => { // Small Layout const SmallLayout = () => { const DATETIME_SCALE = 2; - const STATS_SCALE = 1.6; + const STATS_SCALE = 1.65; return (
@@ -80,7 +80,7 @@ const SmallLayout = () => { width: `${100/DATETIME_SCALE}%`, }} > - +
diff --git a/dashboard/src/components/dashboard/MiniStatCards.jsx b/dashboard/src/components/dashboard/MiniStatCards.jsx index 5ce5354..8f02268 100644 --- a/dashboard/src/components/dashboard/MiniStatCards.jsx +++ b/dashboard/src/components/dashboard/MiniStatCards.jsx @@ -32,7 +32,12 @@ import { Loader2, } from "lucide-react"; import { Skeleton } from "@/components/ui/skeleton"; -import { Tooltip, TooltipContent, TooltipTrigger, TooltipProvider } from "@/components/ui/tooltip"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, + TooltipProvider, +} from "@/components/ui/tooltip"; import { Table, TableBody, @@ -147,7 +152,7 @@ const MiniStatCards = ({ endDate, title = "Quick Stats", description = "", - compact = false + compact = false, }) => { const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); @@ -176,8 +181,10 @@ const MiniStatCards = ({ }, []); const calculateRevenueTrend = useCallback(() => { - if (!stats?.prevPeriodRevenue && stats?.prevPeriodRevenue !== 0) return null; - const currentRevenue = stats.periodProgress < 100 ? stats.projectedRevenue : stats.revenue; + if (!stats?.prevPeriodRevenue && stats?.prevPeriodRevenue !== 0) + return null; + const currentRevenue = + stats.periodProgress < 100 ? stats.projectedRevenue : stats.revenue; const prevRevenue = stats.prevPeriodRevenue; if (!currentRevenue || !prevRevenue) return null; @@ -213,8 +220,11 @@ const MiniStatCards = ({ setLoading(true); setStats(null); - const params = timeRange === "custom" ? { startDate, endDate } : { timeRange }; - const response = await axios.get("/api/klaviyo/events/stats", { params }); + const params = + timeRange === "custom" ? { startDate, endDate } : { timeRange }; + const response = await axios.get("/api/klaviyo/events/stats", { + params, + }); if (!isMounted) return; @@ -248,8 +258,11 @@ const MiniStatCards = ({ try { setProjectionLoading(true); - const params = timeRange === "custom" ? { startDate, endDate } : { timeRange }; - const response = await axios.get("/api/klaviyo/events/projection", { params }); + const params = + timeRange === "custom" ? { startDate, endDate } : { timeRange }; + const response = await axios.get("/api/klaviyo/events/projection", { + params, + }); if (!isMounted) return; setProjection(response.data); @@ -275,8 +288,12 @@ const MiniStatCards = ({ const interval = setInterval(async () => { try { const [statsResponse, projectionResponse] = await Promise.all([ - axios.get("/api/klaviyo/events/stats", { params: { timeRange: "today" } }), - axios.get("/api/klaviyo/events/projection", { params: { timeRange: "today" } }), + axios.get("/api/klaviyo/events/stats", { + params: { timeRange: "today" }, + }), + axios.get("/api/klaviyo/events/projection", { + params: { timeRange: "today" }, + }), ]); setStats(statsResponse.data.stats); @@ -291,26 +308,29 @@ const MiniStatCards = ({ }, [timeRange]); // Add function to fetch detail data - const fetchDetailData = useCallback(async (metric) => { - if (detailData[metric]) return; + const fetchDetailData = useCallback( + async (metric) => { + if (detailData[metric]) return; - setDetailDataLoading((prev) => ({ ...prev, [metric]: true })); - try { - const response = await axios.get("/api/klaviyo/events/stats/details", { - params: { - timeRange: "last30days", - metric, - daily: true, - }, - }); + setDetailDataLoading((prev) => ({ ...prev, [metric]: true })); + try { + const response = await axios.get("/api/klaviyo/events/stats/details", { + params: { + timeRange: "last30days", + metric, + daily: true, + }, + }); - setDetailData((prev) => ({ ...prev, [metric]: response.data.stats })); - } catch (error) { - console.error(`Error fetching detail data for ${metric}:`, error); - } finally { - setDetailDataLoading((prev) => ({ ...prev, [metric]: false })); - } - }, [detailData]); + setDetailData((prev) => ({ ...prev, [metric]: response.data.stats })); + } catch (error) { + console.error(`Error fetching detail data for ${metric}:`, error); + } finally { + setDetailDataLoading((prev) => ({ ...prev, [metric]: false })); + } + }, + [detailData] + ); // Add effect to load detail data when metric is selected useEffect(() => { @@ -323,7 +343,7 @@ const MiniStatCards = ({ useEffect(() => { // Preload all detail data when component mounts const metrics = ["revenue", "orders", "average_order", "shipping"]; - metrics.forEach(metric => { + metrics.forEach((metric) => { fetchDetailData(metric); }); }, []); // eslint-disable-line react-hooks/exhaustive-deps @@ -331,7 +351,6 @@ const MiniStatCards = ({ if (loading && !stats) { return ( -
{[...Array(4)].map((_, i) => ( @@ -360,156 +379,148 @@ const MiniStatCards = ({ const aovTrend = calculateAOVTrend(); return ( - <> -
-
- - {lastUpdate && !loading && ( - - Last updated {lastUpdate.toFormat("h:mm a")} - {projection?.confidence > 0 && !projectionLoading && ( - - - - - ({Math.round(projection.confidence * 100)}%) - - - -

Confidence level of revenue projection

-
-
-
+ <> +
+ + Proj: + {projectionLoading ? ( + + ) : ( + formatCurrency( + projection?.projectedRevenue || stats.projectedRevenue + ) )} - - )} -
- - -
- -
- - Proj: - {projectionLoading ? ( - - ) : ( - formatCurrency(projection?.projectedRevenue || stats.projectedRevenue) - )} -
- ) : null - } - progress={stats?.periodProgress < 100 ? stats.periodProgress : undefined} - trend={projectionLoading && stats?.periodProgress < 100 ? undefined : revenueTrend?.trend} - trendValue={revenueTrend?.value ? formatPercentage(revenueTrend.value) : null} - colorClass="text-green-600 dark:text-green-400" - icon={DollarSign} - iconColor="text-green-500" - onDetailsClick={() => setSelectedMetric("revenue")} - isLoading={loading || !stats} - /> +
+ ) : null + } + progress={ + stats?.periodProgress < 100 ? stats.periodProgress : undefined + } + trend={ + projectionLoading && stats?.periodProgress < 100 + ? undefined + : revenueTrend?.trend + } + trendValue={ + revenueTrend?.value ? formatPercentage(revenueTrend.value) : null + } + colorClass="text-green-600 dark:text-green-400" + icon={DollarSign} + iconColor="text-green-500" + onDetailsClick={() => setSelectedMetric("revenue")} + isLoading={loading || !stats} + /> - setSelectedMetric("orders")} - isLoading={loading || !stats} - /> + setSelectedMetric("orders")} + isLoading={loading || !stats} + /> - setSelectedMetric("average_order")} - isLoading={loading || !stats} - /> + setSelectedMetric("average_order")} + isLoading={loading || !stats} + /> - setSelectedMetric("shipping")} - isLoading={loading || !stats} - /> -
+ setSelectedMetric("shipping")} + isLoading={loading || !stats} + /> + - setSelectedMetric(null)}> - -
-
- - - {selectedMetric - ? `${selectedMetric - .split("_") - .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) - .join(" ")} Details` - : ""} - - -
- {detailDataLoading[selectedMetric] ? ( -
- {selectedMetric === "shipping" ? ( - - ) : ( - <> - - {selectedMetric === "orders" && ( -
-

Hourly Distribution

- -
- )} - - )} -
- ) : ( -
- {selectedMetric === "revenue" && ( - - )} - {selectedMetric === "orders" && ( - - )} - {selectedMetric === "average_order" && ( - setSelectedMetric(null)} + > + +
+
+ + + {selectedMetric + ? `${selectedMetric + .split("_") + .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) + .join(" ")} Details` + : ""} + + +
+ {detailDataLoading[selectedMetric] ? ( +
+ {selectedMetric === "shipping" ? ( + + ) : ( + <> + - )} - {selectedMetric === "shipping" && ( - - )} -
- )} -
+ {selectedMetric === "orders" && ( +
+

+ Hourly Distribution +

+ +
+ )} + + )} +
+ ) : ( +
+ {selectedMetric === "revenue" && ( + + )} + {selectedMetric === "orders" && ( + + )} + {selectedMetric === "average_order" && ( + + )} + {selectedMetric === "shipping" && ( + + )} +
+ )}
- -
- + + + + ); }; -export default MiniStatCards; \ No newline at end of file +export default MiniStatCards;