This commit is contained in:
2026-06-23 19:11:42 +02:00
parent 4fd9f7752a
commit b4be369f25
5 changed files with 83 additions and 18 deletions
+9 -2
View File
@@ -62,8 +62,15 @@ export default function DashboardPage() {
: []
return (
<div className="space-y-6">
<PageHeader title="Dashboard" description="Overview of your sales pipeline">
<div className="space-y-6 relative">
{/* Daily Bugle watermark */}
<div className="absolute top-12 right-4 pointer-events-none select-none z-0 opacity-[0.04] dark:opacity-[0.06]">
<span className="text-[96px] font-['Bangers',cursive] leading-none text-[#CC0000] dark:text-[#FF1111] tracking-wider">
DAILY BUGLE
</span>
</div>
<PageHeader title={<span style={{fontFamily:"'Bangers',cursive"}}>Dashboard</span>} description="Overview of your sales pipeline">
<Select value={period} onValueChange={setPeriod}>
<SelectTrigger className="h-9 w-[160px]">
<ListFilter className="mr-2 h-4 w-4" />
+15 -2
View File
@@ -68,11 +68,24 @@ export function LeadStatusChart({ data }: LeadStatusChartProps) {
transition={{ duration: 0.3, delay: 0.2 }}
className="h-full"
>
<Card className="h-full">
<Card className="h-full relative overflow-hidden">
{/* Spider watermark */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 pointer-events-none z-0 opacity-[0.03] dark:opacity-[0.05]">
<svg width="220" height="220" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
<line x1="90" y1="0" x2="90" y2="180" stroke="#CC0000" strokeWidth="1" />
<line x1="0" y1="90" x2="180" y2="90" stroke="#CC0000" strokeWidth="1" />
<line x1="30" y1="30" x2="150" y2="150" stroke="#0033CC" strokeWidth="1" />
<line x1="150" y1="30" x2="30" y2="150" stroke="#0033CC" strokeWidth="1" />
<circle cx="90" cy="90" r="40" stroke="#CC0000" strokeWidth="1" fill="none" />
<circle cx="90" cy="90" r="60" stroke="#0033CC" strokeWidth="0.8" fill="none" strokeDasharray="4 4" />
<circle cx="90" cy="90" r="80" stroke="#CC0000" strokeWidth="0.5" fill="none" strokeDasharray="2 6" />
</svg>
</div>
<CardHeader>
<CardTitle>Lead Status</CardTitle>
</CardHeader>
<CardContent className="flex flex-1 flex-col">
<CardContent className="flex flex-1 flex-col relative z-10">
<div className="flex flex-1 flex-col items-center justify-center">
{/* Donut */}
<svg width="100%" height="100%" viewBox="0 0 320 320" className="max-h-full overflow-visible" style={{ maxWidth: "280px" }}>
@@ -16,8 +16,8 @@ interface LeadsPerMonthChartProps {
data: IntervalData[]
}
const NEW_LEADS = "#0d9488"
const CLOSED = "#c9a96e"
const NEW_LEADS = "#CC0000"
const CLOSED = "#0033CC"
export function LeadsPerMonthChart({ data: initialData }: LeadsPerMonthChartProps) {
const [year, setYear] = useState(new Date().getFullYear())
+45 -7
View File
@@ -107,6 +107,10 @@ export function StatCard({ title, value, icon: Icon, description, index = 0, tre
const { path: sparkPath, area: sparkArea, goal, gridLines } = buildSparklineSvg()
const sparkColor = color.accent
const isRed = index % 2 === 0
const stripColor = isRed ? "from-[#CC0000] via-[#FF1111] to-[#CC0000]" : "from-[#0033CC] via-[#1144FF] to-[#0033CC]"
const stripGlow = isRed ? "shadow-[#CC0000]/20" : "shadow-[#0033CC]/20"
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
@@ -114,16 +118,50 @@ export function StatCard({ title, value, icon: Icon, description, index = 0, tre
transition={{ duration: 0.3, delay: index * 0.05 }}
className="relative"
>
<Card className="group h-full hover:shadow-md transition-all duration-200">
{/* Web overlay decorative */}
<div className="absolute inset-0 pointer-events-none z-0 opacity-[0.03] dark:opacity-[0.06]">
<svg width="100%" height="100%" viewBox="0 0 180 180" preserveAspectRatio="none" fill="none" xmlns="http://www.w3.org/2000/svg">
{Array.from({ length: 6 }).map((_, i) => (
<line key={`wl-${i}`} x1="0" y1={i * 36} x2="180" y2={i * 36} stroke="#CC0000" strokeWidth="0.5" />
))}
{Array.from({ length: 6 }).map((_, i) => (
<line key={`wc-${i}`} x1={i * 36} y1="0" x2={i * 36} y2="180" stroke="#CC0000" strokeWidth="0.5" />
))}
{Array.from({ length: 6 }).map((_, i) => (
<line key={`wd-${i}`} x1="0" y1={i * 36} x2={180 - i * 36} y2="180" stroke="#0033CC" strokeWidth="0.5" />
))}
</svg>
</div>
{/* Comic action lines on hover */}
<div className="absolute -inset-2 pointer-events-none z-0 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<svg width="100%" height="100%" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<line x1="100" y1="0" x2="100" y2="20" stroke="#CC0000" strokeWidth="2" strokeLinecap="round" />
<line x1="100" y1="180" x2="100" y2="200" stroke="#CC0000" strokeWidth="2" strokeLinecap="round" />
<line x1="0" y1="100" x2="20" y2="100" stroke="#CC0000" strokeWidth="2" strokeLinecap="round" />
<line x1="180" y1="100" x2="200" y2="100" stroke="#CC0000" strokeWidth="2" strokeLinecap="round" />
<line x1="30" y1="30" x2="44" y2="44" stroke="#0033CC" strokeWidth="1.5" strokeLinecap="round" />
<line x1="170" y1="30" x2="156" y2="44" stroke="#0033CC" strokeWidth="1.5" strokeLinecap="round" />
<line x1="30" y1="170" x2="44" y2="156" stroke="#0033CC" strokeWidth="1.5" strokeLinecap="round" />
<line x1="170" y1="170" x2="156" y2="156" stroke="#0033CC" strokeWidth="1.5" strokeLinecap="round" />
<circle cx="100" cy="100" r="90" stroke="#CC0000" strokeWidth="0.5" strokeDasharray="4 4" opacity="0.4" />
<circle cx="100" cy="100" r="80" stroke="#0033CC" strokeWidth="0.5" strokeDasharray="3 5" opacity="0.3" />
</svg>
</div>
<Card className="group h-full hover:shadow-xl transition-all duration-200 relative z-10 overflow-hidden">
{/* Red/Blue gradient top strip */}
<div className={`h-1 w-full bg-gradient-to-r ${stripColor} ${stripGlow} shadow-sm`} />
<CardContent className="p-6 flex flex-col">
<div className="flex items-center justify-between">
<div className="space-y-1">
<p className="text-sm font-medium text-muted-foreground">{title}</p>
<p className="text-3xl font-bold tracking-tight">
<p className="text-3xl font-bold tracking-tight text-[#111111] dark:text-white">
{isNumeric ? display : value}
</p>
{description && (
<p className="text-xs text-muted-foreground">{description}</p>
<p className="text-xs text-[#888888] dark:text-[#666666]">{description}</p>
)}
{trend && (
<span className={cn(
@@ -134,8 +172,8 @@ export function StatCard({ title, value, icon: Icon, description, index = 0, tre
</span>
)}
</div>
<div className={cn("flex h-12 w-12 items-center justify-center rounded-xl shrink-0", color.bg)}>
<Icon className={cn("h-6 w-6", color.text)} />
<div className={`flex h-12 w-12 items-center justify-center rounded-xl shrink-0 ${color.bg}`}>
<Icon className={`h-6 w-6 ${color.text}`} />
</div>
</div>
@@ -179,9 +217,9 @@ export function StatCard({ title, value, icon: Icon, description, index = 0, tre
{title === "Conversion Rate" && conversionRate !== undefined && (
<div className="mt-3">
<div className="w-full h-1.5 bg-muted rounded-full overflow-hidden">
<div className="h-full rounded-full bg-gradient-to-r from-[#f43f5e] to-[#fda4af]" style={{ width: `${Math.min(conversionRate, 100)}%` }} />
<div className="h-full rounded-full bg-gradient-to-r from-[#CC0000] to-[#0033CC]" style={{ width: `${Math.min(conversionRate, 100)}%` }} />
</div>
<p className="text-xs text-muted-foreground mt-1">{conversionRate}% conversion rate</p>
<p className="text-xs text-[#888888] dark:text-[#666666] mt-1">{conversionRate}% conversion rate</p>
</div>
)}
</CardContent>
+12 -5
View File
@@ -67,11 +67,18 @@ export function Topbar({ onMenuClick }: TopbarProps) {
.toUpperCase();
return (
<header className="sticky top-0 z-20 flex h-16 items-center gap-4 border-b bg-background px-4 lg:px-6">
<header className="sticky top-0 z-20 flex h-16 items-center gap-4 border-b bg-white dark:bg-[#141414] px-4 lg:px-6 relative overflow-hidden">
{/* Red/Blue diagonal split accent */}
<div className="absolute right-0 top-0 bottom-0 w-[6px] bg-gradient-to-b from-[#CC0000] via-[#0033CC] to-[#CC0000] dark:from-[#FF1111] dark:via-[#1144FF] dark:to-[#FF1111]" />
{/* Logo */}
<div className="flex items-center gap-2 mr-2 shrink-0">
<div className="w-3 h-3 rounded-full bg-[#0d9488]" />
<span className="text-[#0d9488] font-bold text-sm tracking-wide">
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="14" cy="14" r="13" fill="#CC0000" />
<circle cx="14" cy="14" r="8" fill="#0033CC" />
<path d="M14 6 L16 12 L22 12 L17 15 L19 21 L14 17 L9 21 L11 15 L6 12 L12 12 Z" fill="white" />
</svg>
<span className="text-[#CC0000] dark:text-[#FF1111] font-bold text-sm tracking-wide">
CRM
</span>
</div>
@@ -88,10 +95,10 @@ export function Topbar({ onMenuClick }: TopbarProps) {
{/* Search */}
<div className="relative hidden flex-1 sm:block md:w-80">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#888888] dark:text-[#666666]" />
<Input
placeholder="Search leads, companies..."
className="h-9 w-full max-w-sm pl-9 bg-muted/50"
className="h-9 w-full max-w-sm pl-9 bg-[#F0F0F0] dark:bg-[#1E1E1E] border-[#E0E0E0] dark:border-[#222222] text-[#111111] dark:text-white"
/>
</div>