mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 17:29:45 +00:00
Rewrites the dashboard page as a data-driven analytics surface using existing Supabase tables only — no schema changes, no other pages touched. Widgets (all render independent skeletons while their data fetches, and show a shared empty state when there's not enough data to be useful): - Metric cards (Active Conversations, New Contacts Today, Open Deals Value, Messages Sent Today) with up/down/no-change delta indicator. - Quick actions row (New Contact / Deal / Broadcast / Automation). - Conversations Over Time: SVG line chart, 7/30/90-day tabs, per-day hover crosshair + tooltip. Cached per range so tab switches are instant. - Pipeline Value: SVG donut with per-stage arc segments, total in the center, legend with deal count + value. - Average First Response Time: SVG bar chart by weekday with a configurable dashed target line and this-week / last-week summary. - Activity feed: latest 20 items merged across messages, contacts, deals, broadcasts, and automation logs — click-through deep-links where applicable. Deviations from spec, noted up-front: - Strictly dark theme — spec's #f9fafb alternating rows translate to slate-900 / slate-900/40 stripes. - Kept Inter (tabular-nums, bold 28px) for metric values instead of Space Grotesk to avoid touching root layout. - Quick actions link to the relevant list pages (/contacts, etc.) rather than auto-opening their create modals — that would require modifying those pages. All aggregation is client-side via RLS-scoped queries. If a tenant's dataset outgrows a few thousand messages per range window, the response-time and line-chart queries should migrate to SQL RPCs — noted as follow-up, not shipped here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { BarChart3 } from 'lucide-react'
|
|
import type { ComponentType } from 'react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
/**
|
|
* Shared empty-state panel for charts that can't render meaningfully
|
|
* without a minimum amount of data. Kept minimal and uniform so the
|
|
* three empty states on the dashboard don't each feel like a
|
|
* different widget.
|
|
*/
|
|
export function EmptyState({
|
|
title = 'Not enough data yet',
|
|
hint,
|
|
icon: Icon = BarChart3,
|
|
className,
|
|
}: {
|
|
title?: string
|
|
hint?: string
|
|
icon?: ComponentType<{ className?: string }>
|
|
className?: string
|
|
}) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'flex h-full min-h-40 flex-col items-center justify-center gap-2 rounded-lg border border-dashed border-slate-800 bg-slate-900/40 px-4 py-6 text-center',
|
|
className,
|
|
)}
|
|
>
|
|
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-slate-800 text-slate-500">
|
|
<Icon className="h-5 w-5" />
|
|
</div>
|
|
<p className="text-sm font-medium text-slate-300">{title}</p>
|
|
{hint && <p className="max-w-xs text-xs text-slate-500">{hint}</p>}
|
|
</div>
|
|
)
|
|
}
|