dashboard-4
efferd-/dashboard-4FreeBlock
Commerce dashboard with revenue trends, refund rates, category ranking pie, and quick action items.
Install it
npx shadcn@latest add http://efferd.com/r/dashboard-4.jsonSource
1"use client";23import React from "react";4import { LabelList, Pie, PieChart } from "recharts";5import {6 Card,7 CardContent,8 CardDescription,9 CardHeader,10 CardTitle,11} from "@/components/ui/card";12import {13 type ChartConfig,14 ChartContainer,15 ChartLegend,16 ChartLegendContent,17} from "@/components/ui/chart";1819export type CategoryMixDatum = {20 category: string;21 /** Percent of total (0–100). Usually sums to 100. */22 share: number;23};2425const SLICE_PALETTE = [26 "var(--chart-1)",27 "var(--chart-2)",28 "var(--chart-3)",29 "var(--chart-4)",30 "var(--chart-5)",31] as const;3233/** At most four named slices; remaining share rolls into a fifth slice, “Others”. */34const MAX_NAMED_SLICES = 4;3536/** Rolling window for the mix (days). */37const periodDays = 7;3839/** Demo mix (sums to 100). Replace or pass `data` on the component. */40const data = [41 { category: "Apparel", share: 22 },42 { category: "Accessories", share: 22 },43 { category: "Footwear", share: 18 },44 { category: "Home & living", share: 14 },45 { category: "Beauty", share: 11 },46 { category: "Outlet", share: 8 },47 { category: "Sports", share: 5 },48] as const satisfies readonly CategoryMixDatum[];4950/** Sort by share descending, keep top four, merge the rest into “Others” (max five slices). */51function consolidateTopFourAndOthers(52 data: readonly CategoryMixDatum[]53): CategoryMixDatum[] {54 if (data.length <= MAX_NAMED_SLICES) {55 return [...data];56 }5758 const sorted = [...data].sort((a, b) => b.share - a.share);59 const head = sorted.slice(0, MAX_NAMED_SLICES);60 const tail = sorted.slice(MAX_NAMED_SLICES);61 const othersShare = tail.reduce((sum, row) => sum + row.share, 0);6263 return [...head, { category: "Others", share: othersShare }];64}6566type SliceRow = {67 key: string;68 category: string;69 share: number;70 fill: string;71};7273function buildSlices(data: readonly CategoryMixDatum[]): {74 chartConfig: ChartConfig;75 pieData: SliceRow[];76} {77 const chartConfig: ChartConfig = {78 share: {79 label: "Share",80 },81 };8283 const pieData: SliceRow[] = data.map((row, i) => {84 const key = `s${i}`;85 const color = SLICE_PALETTE[i % SLICE_PALETTE.length];86 chartConfig[key] = {87 label: row.category,88 color,89 };90 return {91 key,92 category: row.category,93 share: row.share,94 fill: `var(--color-${key})`,95 };96 });9798 return { chartConfig, pieData };99}100101export function CategoryRankChart() {102 const { chartConfig, pieData } = React.useMemo(103 () => buildSlices(consolidateTopFourAndOthers(data)),104 []105 );106107 return (108 <Card>109// … truncated
What it pulls in
Other registry items
Files it writes
More from efferd
All 201 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| app-shell-1app-shell-1 | efferd | Blocks | Paid | no deps · 7 files | |
| app-shell-10app-shell-10 | efferd | Blocks | Paid | 1 dep · 13 files | |
| app-shell-2app-shell-2 | efferd | Blocks | Paid | no deps · 9 files | |
| app-shell-3app-shell-3 | efferd | Blocks | Paid | no deps · 9 files | |
| app-shell-4app-shell-4 | efferd | Blocks | Paid | no deps · 9 files | |
| app-shell-5app-shell-5 | efferd | Blocks | Free | 1 dep · 9 files | |
| app-shell-6app-shell-6 | efferd | Blocks | Paid | no deps · 11 files | |
| app-shell-7app-shell-7 | efferd | Blocks | Paid | no deps · 12 files |
