127 lines
5.8 KiB
TypeScript
127 lines
5.8 KiB
TypeScript
import { useAuthStore } from '../hooks/use-auth';
|
|
import { motion } from 'framer-motion';
|
|
import type { Variants } from 'framer-motion';
|
|
import { FolderKanban, FileSignature, Users, ArrowUpRight, Activity, Zap, ShieldCheck } from 'lucide-react';
|
|
import { Link } from 'react-router-dom';
|
|
import { PageHeader } from '../components/ui/PageHeader';
|
|
|
|
const containerVariants: Variants = {
|
|
hidden: { opacity: 0 },
|
|
show: { opacity: 1, transition: { staggerChildren: 0.1 } }
|
|
};
|
|
|
|
const itemVariants: Variants = {
|
|
hidden: { opacity: 0, y: 30 },
|
|
show: { opacity: 1, y: 0, transition: { type: 'spring', stiffness: 300, damping: 24 } }
|
|
};
|
|
|
|
export const DashboardPage = () => {
|
|
const user = useAuthStore((state) => state.user);
|
|
|
|
const CARDS = user?.role === 'ADMIN' ? [
|
|
{
|
|
title: 'Asset Library',
|
|
description: 'Manage and assign premium marketing collateral, brand guidelines, and shared resources.',
|
|
icon: FolderKanban,
|
|
path: '/admin/assets',
|
|
metrics: 'View Catalog'
|
|
},
|
|
{
|
|
title: 'Legal Engine',
|
|
description: 'Strict version control for active NDAs, MSAs, and partner compliance tracking.',
|
|
icon: FileSignature,
|
|
path: '/admin/legal',
|
|
metrics: 'Legal Templates'
|
|
},
|
|
{
|
|
title: 'Partner Directory',
|
|
description: 'View active channel partners, audit logs, and their assigned enterprise content.',
|
|
icon: Users,
|
|
path: '/admin/partners',
|
|
metrics: 'Manage Partners'
|
|
}
|
|
] : [
|
|
{
|
|
title: 'Asset Library',
|
|
description: 'Browse, search, and download your assigned enterprise resources and pitch decks.',
|
|
icon: FolderKanban,
|
|
path: '/client/assets',
|
|
metrics: 'My Assets'
|
|
},
|
|
{
|
|
title: 'Legal Agreements',
|
|
description: 'View signed compliance documentation and download copies of active agreements.',
|
|
icon: FileSignature,
|
|
path: '/client/agreements',
|
|
metrics: 'My Agreements'
|
|
}
|
|
];
|
|
|
|
return (
|
|
<motion.div variants={containerVariants} initial="hidden" animate="show" className="w-full space-y-6 text-ink-900 animate-fade-in">
|
|
<PageHeader
|
|
title={`Welcome back, ${user?.email?.split('@')[0]}`}
|
|
subtitle={`You are authenticated as ${user?.role}. Manage your channel network, monitor compliance, and distribute assets globally.`}
|
|
badge={
|
|
<div className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-ink-900 border border-ink-800 text-[10px] font-bold text-ink-0 tracking-wider uppercase shrink-0">
|
|
<div className="w-1 h-1 rounded-full bg-ink-0 animate-pulse" />
|
|
<span>System Active</span>
|
|
</div>
|
|
}
|
|
/>
|
|
|
|
{/* Stats Grid */}
|
|
<motion.div variants={itemVariants} className="grid grid-cols-1 md:grid-cols-3 gap-4 pt-2">
|
|
{[
|
|
{ label: 'Global Network Uptime', value: '99.99%', icon: Activity, trend: '+0.01%' },
|
|
{ label: 'Active Data Streams', value: '1,492', icon: Zap, trend: '+12%' },
|
|
{ label: 'Security Compliance', value: 'Level 4', icon: ShieldCheck, trend: 'Verified' }
|
|
].map((stat, i) => (
|
|
<div key={i} className="relative group overflow-hidden rounded-xl bg-ink-0 border border-ink-200 p-4 transition-all duration-300 shadow-sm hover:shadow-md">
|
|
<div className="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity duration-500 group-hover:scale-110 transform">
|
|
<stat.icon className="w-16 h-16 text-ink-900" />
|
|
</div>
|
|
<p className="text-xs font-semibold uppercase tracking-wider text-ink-500 mb-1">{stat.label}</p>
|
|
<div className="flex items-end gap-3 mt-2">
|
|
<h3 className="text-xl font-bold text-ink-900 tracking-tight">{stat.value}</h3>
|
|
<span className="text-xs font-bold text-ink-900 bg-ink-100 px-2 py-0.5 rounded-md mb-0.5 border border-ink-200">{stat.trend}</span>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</motion.div>
|
|
|
|
{/* Main Action Cards */}
|
|
<motion.div variants={itemVariants} className="grid grid-cols-1 md:grid-cols-3 gap-4 pt-2">
|
|
{CARDS.map((card, idx) => (
|
|
<Link key={idx} to={card.path} className="group relative block h-full">
|
|
<div className="relative h-full bg-ink-0 border border-ink-200 rounded-xl p-5 hover:border-ink-400 transition-all duration-300 overflow-hidden shadow-sm hover:shadow-md hover:-translate-y-0.5 flex flex-col justify-between">
|
|
|
|
<div className="flex justify-between items-start mb-8 relative z-10">
|
|
<div className="w-10 h-10 rounded-lg bg-gradient-to-br from-ink-900 to-ink-800 shadow-sm group-hover:scale-105 transition-all duration-350 flex items-center justify-center text-ink-0">
|
|
<card.icon className="w-5 h-5" />
|
|
</div>
|
|
<div className="w-8 h-8 rounded-full bg-ink-50 flex items-center justify-center group-hover:bg-ink-100 transition-all duration-300 border border-ink-200 group-hover:border-ink-300">
|
|
<ArrowUpRight className="w-4 h-4 text-ink-400 group-hover:text-ink-900 transition-colors" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="relative z-10 mt-auto">
|
|
<div className="inline-block px-2 py-0.5 rounded-md bg-ink-50 border border-ink-200 text-xs font-bold text-ink-500 mb-3 shadow-sm">
|
|
{card.metrics}
|
|
</div>
|
|
<h3 className="text-lg font-bold text-ink-900 mb-2 tracking-tight">
|
|
{card.title}
|
|
</h3>
|
|
<p className="text-ink-500 leading-normal text-xs font-medium">
|
|
{card.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</motion.div>
|
|
</motion.div>
|
|
);
|
|
};
|
|
export default DashboardPage;
|