From 90b0dfa70011236a6674f65f624f814aa98217ca Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 29 Dec 2024 01:37:45 -0500 Subject: [PATCH] Add and standardize skeletons --- .../components/dashboard/AircallDashboard.jsx | 209 +++++++++++++----- .../dashboard/AnalyticsDashboard.jsx | 173 +++++++++------ .../src/components/dashboard/EventFeed.jsx | 35 ++- .../components/dashboard/GorgiasOverview.jsx | 198 ++++++++++------- .../components/dashboard/KlaviyoCampaigns.jsx | 96 +++++++- .../components/dashboard/MetaCampaigns.jsx | 82 ++++++- .../src/components/dashboard/ProductGrid.jsx | 119 +++++++--- .../dashboard/RealtimeAnalytics.jsx | 108 ++++++++- .../src/components/dashboard/SalesChart.jsx | 99 ++++++--- .../src/components/dashboard/StatCards.jsx | 147 +++++++----- .../dashboard/UserBehaviorDashboard.jsx | 85 ++++++- 11 files changed, 995 insertions(+), 356 deletions(-) diff --git a/dashboard/src/components/dashboard/AircallDashboard.jsx b/dashboard/src/components/dashboard/AircallDashboard.jsx index cdb7480..dba16b5 100644 --- a/dashboard/src/components/dashboard/AircallDashboard.jsx +++ b/dashboard/src/components/dashboard/AircallDashboard.jsx @@ -165,6 +165,81 @@ const AgentPerformanceTable = ({ agents, onSort }) => { ); }; +const SkeletonMetricCard = () => ( + + + + +
+ + +
+
+
+); + +const SkeletonChart = ({ type = "line" }) => ( +
+
+
+ {type === "bar" ? ( +
+ {[...Array(24)].map((_, i) => ( +
+ ))} +
+ ) : ( +
+ {[...Array(5)].map((_, i) => ( +
+ ))} +
+
+ )} +
+
+
+); + +const SkeletonTable = ({ rows = 5 }) => ( + + + + + + + + + + + + {[...Array(rows)].map((_, i) => ( + + + + + + + + ))} + +
+); + const AircallDashboard = () => { const [timeRange, setTimeRange] = useState("last7days"); const [metrics, setMetrics] = useState(null); @@ -316,7 +391,7 @@ const AircallDashboard = () => {
{isLoading ? ( [...Array(4)].map((_, i) => ( - + )) ) : metrics ? ( <> @@ -407,24 +482,28 @@ const AircallDashboard = () => { Daily Call Volume - - - - - - } /> - - - - - + {isLoading ? ( + + ) : ( + + + + + + } /> + + + + + + )} @@ -434,23 +513,27 @@ const AircallDashboard = () => { Hourly Distribution - - - - - - } /> - - - + {isLoading ? ( + + ) : ( + + + + + + } /> + + + + )}
@@ -463,10 +546,14 @@ const AircallDashboard = () => { Agent Performance - setAgentSort({ key, direction })} - /> + {isLoading ? ( + + ) : ( + setAgentSort({ key, direction })} + /> + )} @@ -476,26 +563,30 @@ const AircallDashboard = () => { Missed Call Reasons - - - - Reason - Count - - - - {chartData.missedReasons.map((reason, index) => ( - - - {reason.reason} - - - {reason.count} - + {isLoading ? ( + + ) : ( +
+ + + Reason + Count - ))} - -
+ + + {chartData.missedReasons.map((reason, index) => ( + + + {reason.reason} + + + {reason.count} + + + ))} + + + )}
diff --git a/dashboard/src/components/dashboard/AnalyticsDashboard.jsx b/dashboard/src/components/dashboard/AnalyticsDashboard.jsx index 5399da6..5bb75d3 100644 --- a/dashboard/src/components/dashboard/AnalyticsDashboard.jsx +++ b/dashboard/src/components/dashboard/AnalyticsDashboard.jsx @@ -56,29 +56,50 @@ const SkeletonChart = () => ( clipPath: "polygon(0 50%, 100% 20%, 100% 100%, 0 100%)", }} /> +
+ {[...Array(8)].map((_, i) => ( +
+ ))} +
+
+ {[...Array(6)].map((_, i) => ( + + ))} +
); const SkeletonStats = () => ( -
+
{[...Array(4)].map((_, i) => ( - - - + + - - - + + + ))}
); +const SkeletonButtons = () => ( +
+ {[...Array(4)].map((_, i) => ( + + ))} +
+); + // Add StatCard component const StatCard = ({ title, @@ -264,17 +285,21 @@ export const AnalyticsDashboard = () => { Analytics Overview - + {loading ? ( + + ) : ( + + )}
{loading ? ( @@ -317,60 +342,64 @@ export const AnalyticsDashboard = () => { ) : null}
-
- - - - -
+ {loading ? ( + + ) : ( +
+ + + + +
+ )}
diff --git a/dashboard/src/components/dashboard/EventFeed.jsx b/dashboard/src/components/dashboard/EventFeed.jsx index 4391862..9302c3e 100644 --- a/dashboard/src/components/dashboard/EventFeed.jsx +++ b/dashboard/src/components/dashboard/EventFeed.jsx @@ -142,18 +142,33 @@ const formatShipMethodSimple = (method) => { // Loading State Component const LoadingState = () => ( -
-
- {[...Array(5)].map((_, i) => ( -
-
-
-
-
+
+ {[...Array(8)].map((_, i) => ( +
+
+ +
+
+
+
+ +
+
+ +
+
+ + + +
- ))} -
+
+ + +
+
+ ))}
); diff --git a/dashboard/src/components/dashboard/GorgiasOverview.jsx b/dashboard/src/components/dashboard/GorgiasOverview.jsx index e59f876..022161c 100644 --- a/dashboard/src/components/dashboard/GorgiasOverview.jsx +++ b/dashboard/src/components/dashboard/GorgiasOverview.jsx @@ -111,32 +111,40 @@ const MetricCard = ({
-

{title}

{loading ? ( - + <> + +
+ + +
+ ) : ( -
-

- {typeof value === "number" - ? value.toLocaleString() + suffix - : value} -

- {delta !== undefined && delta !== 0 && ( -
- {delta > 0 ? ( - - ) : ( - - )} - - {formatDelta(delta)} - -
- )} -
+ <> +

{title}

+
+

+ {typeof value === "number" + ? value.toLocaleString() + suffix + : value} +

+ {delta !== undefined && delta !== 0 && ( +
+ {delta > 0 ? ( + + ) : ( + + )} + + {formatDelta(delta)} + +
+ )} +
+ )}
- {Icon && ( + {!loading && Icon && ( )} + {loading && ( + + )}
); }; +const SkeletonMetricCard = () => ( + + +
+
+ +
+ + +
+
+ +
+
+
+); + const TableSkeleton = () => ( -
- - - - -
+ + + + + + + + + + + {[...Array(5)].map((_, i) => ( + + + + + + + ))} + +
); const GorgiasOverview = () => { @@ -324,48 +366,56 @@ const GorgiasOverview = () => {
{/* Message & Response Metrics */} -
- -
-
- -
-
- -
-
- -
+ {loading ? ( + [...Array(8)].map((_, i) => ( + + )) + ) : ( + <> +
+ +
+
+ +
+
+ +
+
+ +
+ + )} {/* Satisfaction & Efficiency */}
@@ -423,9 +473,7 @@ const GorgiasOverview = () => {
{loading ? ( -
- -
+ ) : ( @@ -487,9 +535,7 @@ const GorgiasOverview = () => { {loading ? ( -
- -
+ ) : (
diff --git a/dashboard/src/components/dashboard/KlaviyoCampaigns.jsx b/dashboard/src/components/dashboard/KlaviyoCampaigns.jsx index 7617f48..4b2b568 100644 --- a/dashboard/src/components/dashboard/KlaviyoCampaigns.jsx +++ b/dashboard/src/components/dashboard/KlaviyoCampaigns.jsx @@ -17,6 +17,7 @@ import { import { Button } from "@/components/ui/button"; import { TIME_RANGES } from "@/lib/constants"; import { Mail, MessageSquare, ArrowUpDown } from "lucide-react"; +import { Skeleton } from "@/components/ui/skeleton"; // Helper functions for formatting const formatRate = (value, isSMS = false, hideForSMS = false) => { @@ -37,14 +38,76 @@ const formatCurrency = (value) => { // Loading skeleton component const TableSkeleton = () => ( -
- {[...Array(5)].map((_, i) => ( -
- ))} -
+
+ + + + + + + + + + + + {[...Array(15)].map((_, i) => ( + + + + + + + + + ))} + +
+ + + + + + + + + + + +
+
+ +
+ + + +
+
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
); // Error alert component @@ -167,10 +230,21 @@ const KlaviyoCampaigns = ({ className }) => { if (isLoading) { return ( - -
+ +
+ + + +
+
+ + +
+ +
+
- + diff --git a/dashboard/src/components/dashboard/MetaCampaigns.jsx b/dashboard/src/components/dashboard/MetaCampaigns.jsx index 00dbcc4..6998abf 100644 --- a/dashboard/src/components/dashboard/MetaCampaigns.jsx +++ b/dashboard/src/components/dashboard/MetaCampaigns.jsx @@ -28,6 +28,7 @@ import { Hash, } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Skeleton } from "@/components/ui/skeleton"; // Helper functions for formatting const formatCurrency = (value, decimalPlaces = 2) => @@ -250,6 +251,63 @@ const processCampaignData = (campaign) => { }; }; +const SkeletonMetricCard = () => ( + + +
+
+ +
+ +
+
+ +
+
+
+); + +const SkeletonTable = () => ( +
+
+ + + + + {[...Array(8)].map((_, i) => ( + + ))} + + + + {[...Array(5)].map((_, rowIndex) => ( + + + {[...Array(8)].map((_, colIndex) => ( + + ))} + + ))} + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+
+); + const MetaCampaigns = () => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -392,8 +450,28 @@ const MetaCampaigns = () => { if (loading) { return ( - - + +
+ + Meta Ads Performance + + +
+
+ {[...Array(12)].map((_, i) => ( + + ))} +
+
+ +
); diff --git a/dashboard/src/components/dashboard/ProductGrid.jsx b/dashboard/src/components/dashboard/ProductGrid.jsx index a406dee..2ebcbcf 100644 --- a/dashboard/src/components/dashboard/ProductGrid.jsx +++ b/dashboard/src/components/dashboard/ProductGrid.jsx @@ -100,59 +100,75 @@ const ProductGrid = ({ ); const SkeletonProduct = () => ( - + - + -
- - +
+ +
- + - + - + ); const LoadingState = () => ( -
+
- - - - - {[...Array(10)].map((_, i) => ( + {[...Array(20)].map((_, i) => ( ))} @@ -161,6 +177,39 @@ const ProductGrid = ({ ); + if (loading) { + return ( + + +
+
+
+ + + + {description && ( + + + + )} +
+
+ + +
+
+
+
+ + +
+ +
+
+
+ ); + } + return ( @@ -230,9 +279,7 @@ const ProductGrid = ({
- {loading ? ( - - ) : error ? ( + {error ? ( Error @@ -247,13 +294,13 @@ const ProductGrid = ({

Try selecting a different time range

) : ( -
+
- -
- -
+
+ + -
- -
+
+ -
- -
+
+ -
- -
+
+
- - - -
- + + + + +