From f208ab1ad0dcdaf9289a338e389912112464a355 Mon Sep 17 00:00:00 2001 From: Raymond Abiola Date: Sat, 27 Jun 2026 18:01:55 +0100 Subject: [PATCH] feat: add illustrated zero-state variants to dashboard KPI cards --- app/(dashboard)/dashboard/page.tsx | 61 ++++++------------- components/active-bets/ActiveBets.tsx | 20 +++--- components/cards/stat-card.tsx | 58 +++++++++++++++--- .../empty-states/dashboard/active-bets.svg | 13 ++++ .../empty-states/dashboard/leaderboard.svg | 15 +++++ .../empty-states/dashboard/predictions.svg | 14 +++++ .../assets/empty-states/dashboard/volume.svg | 17 ++++++ .../empty-states/dashboard/win-rate.svg | 13 ++++ 8 files changed, 153 insertions(+), 58 deletions(-) create mode 100644 public/assets/empty-states/dashboard/active-bets.svg create mode 100644 public/assets/empty-states/dashboard/leaderboard.svg create mode 100644 public/assets/empty-states/dashboard/predictions.svg create mode 100644 public/assets/empty-states/dashboard/volume.svg create mode 100644 public/assets/empty-states/dashboard/win-rate.svg diff --git a/app/(dashboard)/dashboard/page.tsx b/app/(dashboard)/dashboard/page.tsx index f8a0b5a..109d169 100644 --- a/app/(dashboard)/dashboard/page.tsx +++ b/app/(dashboard)/dashboard/page.tsx @@ -10,6 +10,8 @@ import { RecommendationProvenance, type RecommendationSignalKey } from "@/compon import { Skeleton } from "@/components/ui/skeleton" import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert" import { RecommendationsStrip } from "@/components/dashboard/RecommendationsStrip" +import { ActiveBets } from "@/components/active-bets/ActiveBets" +import { ActivityTimeline } from "@/components/activity-timeline" import { useEffect, useState } from "react" interface Stat { @@ -97,7 +99,8 @@ export default function DashboardPage() { } const renderStatCard = (stat: Stat, idx: number) => { - return + const variants: any[] = ['volume', 'predictions', 'win-rate', 'leaderboard']; + return } const renderCards = () => { @@ -112,13 +115,10 @@ export default function DashboardPage() { ) case 'empty': return ( -
- -

No KPI data available.

-

Create events to generate statistics.

- +
+ {(['volume', 'predictions', 'win-rate', 'leaderboard'] as const).map((variant, idx) => ( + + ))}
) case 'error': @@ -359,6 +359,11 @@ export default function DashboardPage() { {renderCards()} + console.log('Add bet')} + /> {renderRecommendationStrip()}
@@ -375,42 +380,14 @@ export default function DashboardPage() { - Pending Tasks - Tasks requiring admin attention + Recent Activity + Your latest actions on Predictify -
-
- -
-

8 events need outcome verification

-

Deadline: Today

-
- -
-
- -
-

12 disputes need resolution

-

3 high priority

-
- -
-
- -
-

Monthly financial report ready

-

April 2023

-
- -
-
+
diff --git a/components/active-bets/ActiveBets.tsx b/components/active-bets/ActiveBets.tsx index 8461d93..6893678 100644 --- a/components/active-bets/ActiveBets.tsx +++ b/components/active-bets/ActiveBets.tsx @@ -28,18 +28,22 @@ const ActiveBetCardSkeleton = () => ( // Empty state component const EmptyState = ({ onAddBet }: { onAddBet?: () => void }) => ( -
-
- +
+
+ No active bets
-

No Active Bets

-

- You don't have any active bets at the moment. Start by placing your first bet! +

No Active Bets

+

+ You haven't placed any bets yet. Explore live markets and start predicting today!

{onAddBet && ( - )}
diff --git a/components/cards/stat-card.tsx b/components/cards/stat-card.tsx index 8b81f3a..830c946 100644 --- a/components/cards/stat-card.tsx +++ b/components/cards/stat-card.tsx @@ -5,6 +5,8 @@ import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import Link from "next/link"; +export type StatEmptyVariant = 'volume' | 'predictions' | 'win-rate' | 'leaderboard'; + interface StatCardProps { stat?: Stat; index: number; @@ -15,23 +17,63 @@ interface StatCardProps { * - "error": shows an error alert with a retry button. */ status?: "loading" | "empty" | "error"; + /** The variant of empty state to show, which determines illustration and copy */ + emptyVariant?: StatEmptyVariant; /** Callback invoked when the retry button is clicked in error state */ onRetry?: () => void; } -export function StatCard({ stat, index, status, onRetry }: StatCardProps) { +const EMPTY_CONFIGS: Record = { + volume: { + illustration: "/assets/empty-states/dashboard/volume.svg", + title: "No Volume", + description: "Start trading to see activity.", + cta: "Explore Markets", + href: "/events" + }, + predictions: { + illustration: "/assets/empty-states/dashboard/predictions.svg", + title: "No Predictions", + description: "Make your first prediction.", + cta: "View Markets", + href: "/events" + }, + "win-rate": { + illustration: "/assets/empty-states/dashboard/win-rate.svg", + title: "0% Win Rate", + description: "Win bets to see your rate.", + cta: "Place a Bet", + href: "/events" + }, + leaderboard: { + illustration: "/assets/empty-states/dashboard/leaderboard.svg", + title: "Unranked", + description: "Compete to climb the ranks.", + cta: "Leaderboard", + href: "/leaderboard" + } +}; + +export function StatCard({ stat, index, status, emptyVariant = 'volume', onRetry }: StatCardProps) { if (status === "loading") { - return ; + return ; } if (status === "empty") { + const config = EMPTY_CONFIGS[emptyVariant]; return ( -
- -

No data available.

-

Create events to generate statistics.

-
); diff --git a/public/assets/empty-states/dashboard/active-bets.svg b/public/assets/empty-states/dashboard/active-bets.svg new file mode 100644 index 0000000..c213205 --- /dev/null +++ b/public/assets/empty-states/dashboard/active-bets.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/assets/empty-states/dashboard/leaderboard.svg b/public/assets/empty-states/dashboard/leaderboard.svg new file mode 100644 index 0000000..7bf7ddb --- /dev/null +++ b/public/assets/empty-states/dashboard/leaderboard.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/public/assets/empty-states/dashboard/predictions.svg b/public/assets/empty-states/dashboard/predictions.svg new file mode 100644 index 0000000..06d9f9d --- /dev/null +++ b/public/assets/empty-states/dashboard/predictions.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/assets/empty-states/dashboard/volume.svg b/public/assets/empty-states/dashboard/volume.svg new file mode 100644 index 0000000..033eaa5 --- /dev/null +++ b/public/assets/empty-states/dashboard/volume.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/public/assets/empty-states/dashboard/win-rate.svg b/public/assets/empty-states/dashboard/win-rate.svg new file mode 100644 index 0000000..5bd4b85 --- /dev/null +++ b/public/assets/empty-states/dashboard/win-rate.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + +