Tech4biz-channel/Channel-Frontend/src/pages/DashboardPage.tsx

140 lines
6.2 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';
import { PageLayout } from '../components/layout/PageLayout';
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'
}
];
// Header component
const headerNode = (
<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>
}
/>
);
return (
<PageLayout header={headerNode}>
<motion.div
variants={containerVariants}
initial="hidden"
animate="show"
className="p-5 space-y-6 flex flex-col min-h-0 flex-1 overflow-y-auto"
>
{/* Stats Grid */}
{user?.role === 'ADMIN' && (
<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 ${CARDS.length === 2 ? 'md:grid-cols-2' : '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 action-card-title font-bold text-ink-900 mb-2 tracking-tight">
{card.title}
</h3>
<p className="text-ink-500 action-card-desc leading-normal text-xs font-medium">
{card.description}
</p>
</div>
</div>
</Link>
))}
</motion.div>
</motion.div>
</PageLayout>
);
};
export default DashboardPage;