xiaohongshu
xiaohongshu
dashboard-design
Design effective dashboards with clear layouts, KPI displays, data grids, and real-time updates. Covers dashboard patterns, information hierarchy, responsive grids, widget design, and admin panel layouts. Use for building analytics dashboards, admin interfaces, and monitoring displays.
Full skill instructions
Create effective dashboards that present data clearly and enable quick decision-making.
interface KPICardProps {
title: string;
value: string | number;
change?: number;
changeLabel?: string;
icon?: React.ReactNode;
}
function KPICard({ title, value, change, changeLabel, icon }: KPICardProps) {
const isPositive = change && change > 0;
const isNegative = change && change < 0;
return (
<div className="bg-white rounded-lg shadow p-6">
<div className="flex items-center justify-between">
<span className="text-sm font-medium text-gray-500">{title}</span>
{icon && <span className="text-gray-400">{icon}</span>}
</div>
<div className="mt-2">
<span className="text-3xl font-bold text-gray-900">{value}</span>
</div>
{change !== undefined && (
<div className="mt-2 flex items-center">
<span
className={`text-sm font-medium ${
isPositive ? 'text-green-600' : isNegative ? 'text-red-600' : 'text-gray-500'
}`}
>
{isPositive && '+'}
{change}%
</span>
{changeLabel && (
<span className="ml-2 text-sm text-gray-500">{changeLabel}</span>
)}
</div>
)}
</div>
);
}
function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-screen bg-gray-100">
{/* Header */}
<header className="bg-white shadow-sm">
<div className="max-w-7xl mx-auto px-4 py-4 flex items-center justify-between">
<h1 className="text-2xl font-bold text-gray-900">Dashboard</h1>
<div className="flex items-center gap-4">
<DateRangePicker />
<RefreshButton />
</div>
</div>
</header>
{/* Main Content */}
<main className="max-w-7xl mx-auto px-4 py-6">
{/* KPI Row */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
<KPICard title="Total Revenue" value="$45,231" change={12.5} changeLabel="vs last month" />
<KPICard title="Orders" value="1,234" change={-2.3} changeLabel="vs last month" />
<KPICard title="Customers" value="5,678" change={8.1} changeLabel="vs last month" />
<KPICard title="Avg. Order" value="$36.70" change={4.2} changeLabel="vs last month" />
</div>
{/* Charts Row */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<ChartCard title="Revenue Over Time">
<RevenueChart />
</ChartCard>
<ChartCard title="Sales by Category">
<CategoryChart />
</ChartCard>
</div>
{/* Table Section */}
<div className="bg-white rounded-lg shadow">
<DataTable />
</div>
</main>
</div>
);
}
interface ChartCardProps {
title: string;
subtitle?: string;
action?: React.ReactNode;
children: React.ReactNode;
}
function ChartCard({ title, subtitle, action, children }: ChartCardProps) {
return (
<div className="bg-white rounded-lg shadow">
<div className="px-6 py-4 border-b border-gray-200">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-medium text-gray-900">{title}</h3>
{subtitle && <p className="text-sm text-gray-500">{subtitle}</p>}
</div>
{action}
</div>
</div>
<div className="p-6">{children}</div>
</div>
);
}
interface Column<T> {
key: keyof T;
header: string;
sortable?: boolean;
render?: (value: T[keyof T], row: T) => React.ReactNode;
}
function DataTable<T extends { id: string }>({
data,
columns,
}: {
data: T[];
columns: Column<T>[];
}) {
const [sortKey, setSortKey] = useState<keyof T | null>(null);
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc');
const sortedData = useMemo(() => {
if (!sortKey) return data;
return [...data].sort((a, b) => {
const aVal = a[sortKey];
const bVal = b[sortKey];
const modifier = sortOrder === 'asc' ? 1 : -1;
return aVal < bVal ? -1 * modifier : aVal > bVal ? 1 * modifier : 0;
});
}, [data, sortKey, sortOrder]);
const handleSort = (key: keyof T) => {
if (sortKey === key) {
setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
} else {
setSortKey(key);
setSortOrder('asc');
}
};
return (
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
{columns.map((col) => (
<th
key={String(col.key)}
onClick={() => col.sortable && handleSort(col.key)}
className={`px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${
col.sortable ? 'cursor-pointer hover:bg-gray-100' : ''
}`}
>
<div className="flex items-center gap-2">
{col.header}
{col.sortable && sortKey === col.key && (
<span>{sortOrder === 'asc' ? '↑' : '↓'}</span>
)}
</div>
</th>
))}
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{sortedData.map((row) => (
<tr key={row.id} className="hover:bg-gray-50">
{columns.map((col) => (
<td key={String(col.key)} className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{col.render ? col.render(row[col.key], row) : String(row[col.key])}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}
function useAutoRefresh<T>(
fetcher: () => Promise<T>,
intervalMs: number = 30000
) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
const refresh = useCallback(async () => {
try {
const result = await fetcher();
setData(result);
setLastUpdated(new Date());
setError(null);
} catch (err) {
setError(err instanceof Error ? err : new Error('Fetch failed'));
} finally {
setLoading(false);
}
}, [fetcher]);
useEffect(() => {
refresh();
const interval = setInterval(refresh, intervalMs);
return () => clearInterval(interval);
}, [refresh, intervalMs]);
return { data, loading, error, lastUpdated, refresh };
}
function LiveIndicator({ lastUpdated }: { lastUpdated: Date | null }) {
const [, forceUpdate] = useState({});
useEffect(() => {
const interval = setInterval(() => forceUpdate({}), 1000);
return () => clearInterval(interval);
}, []);
if (!lastUpdated) return null;
const seconds = Math.floor((Date.now() - lastUpdated.getTime()) / 1000);
return (
<div className="flex items-center gap-2 text-sm text-gray-500">
<span className="relative flex h-2 w-2">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" />
<span className="relative inline-flex rounded-full h-2 w-2 bg-green-500" />
</span>
Updated {seconds < 60 ? `${seconds}s ago` : `${Math.floor(seconds / 60)}m ago`}
</div>
);
}
function ResponsiveDashboard() {
return (
<div className="space-y-6">
{/* KPIs - Stack on mobile, 4 columns on desktop */}
<div className="grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<KPICard title="Revenue" value="$45K" />
<KPICard title="Orders" value="1,234" />
<KPICard title="Users" value="5,678" />
<KPICard title="Growth" value="+12%" />
</div>
{/* Charts - Full width on mobile, side by side on desktop */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<ChartCard title="Revenue Trend">
<LineChart />
</ChartCard>
<ChartCard title="Distribution">
<PieChart />
</ChartCard>
</div>
{/* Table - Horizontal scroll on mobile */}
<div className="bg-white rounded-lg shadow overflow-hidden">
<div className="overflow-x-auto">
<DataTable />
</div>
</div>
</div>
);
}
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience