feat: scaffold initial dashboard layout and base pages for all modules

This commit is contained in:
Poyraz Avsever
2026-05-08 17:29:02 +03:00
parent 8f63998d34
commit 1c9eca814e
12 changed files with 3129 additions and 1147 deletions
+154 -116
View File
@@ -1,21 +1,15 @@
"use client"; "use client";
import { ArrowUpRight, Brain, TrendingUp, Zap, Target, ArrowDownRight, BarChart3, Filter } from "lucide-react"; import { useState } from "react";
import { import {
Area, ArrowUpRight, Brain, TrendingUp, Zap, Target, ArrowDownRight,
AreaChart, BarChart3, Filter, Download, Info, CheckCircle2, AlertCircle
Bar, } from "lucide-react";
BarChart, import {
CartesianGrid, Area, AreaChart, Bar, BarChart, CartesianGrid, ResponsiveContainer,
ResponsiveContainer, Tooltip, XAxis, YAxis, Radar, RadarChart, PolarGrid, PolarAngleAxis, Cell
Tooltip,
XAxis,
YAxis,
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
} from "recharts"; } from "recharts";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const productivityTrend = [ const productivityTrend = [
@@ -29,10 +23,10 @@ const productivityTrend = [
]; ];
const habitCompletion = [ const habitCompletion = [
{ name: "Reading", completed: 85, missed: 15 }, { name: "Reading", completed: 85, missed: 15, color: "#6C5BB0" },
{ name: "Workout", completed: 60, missed: 40 }, { name: "Workout", completed: 60, missed: 40, color: "#a798e8" },
{ name: "Meditation", completed: 90, missed: 10 }, { name: "Meditation", completed: 90, missed: 10, color: "#10b981" },
{ name: "Coding", completed: 75, missed: 25 }, { name: "Coding", completed: 75, missed: 25, color: "#3b82f6" },
]; ];
const focusRadarData = [ const focusRadarData = [
@@ -44,8 +38,16 @@ const focusRadarData = [
]; ];
export default function AnalyticsPage() { export default function AnalyticsPage() {
const [isExporting, setIsExporting] = useState(false);
const [activeInsight, setActiveInsight] = useState<string | null>(null);
const handleExport = () => {
setIsExporting(true);
setTimeout(() => setIsExporting(false), 3000);
};
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4">
@@ -61,95 +63,116 @@ export default function AnalyticsPage() {
<option className="bg-[#0A0710]">This Year</option> <option className="bg-[#0A0710]">This Year</option>
</select> </select>
</div> </div>
<button className="bg-white/5 hover:bg-white/10 text-foreground border border-white/10 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <button
<BarChart3 className="h-4 w-4" /> onClick={handleExport}
EXPORT REPORT disabled={isExporting}
className={`min-w-[140px] px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center justify-center gap-2 transition-all ${isExporting ? 'bg-emerald-500/20 text-emerald-400 border border-emerald-500/30' : 'bg-white/5 hover:bg-white/10 text-foreground border border-white/10'}`}
>
{isExporting ? (
<>
<motion.div animate={{ rotate: 360 }} transition={{ repeat: Infinity, duration: 1, ease: "linear" }}>
<Download className="h-4 w-4" />
</motion.div>
GENERATING...
</>
) : (
<>
<BarChart3 className="h-4 w-4" />
EXPORT REPORT
</>
)}
</button> </button>
</div> </div>
</div> </div>
{/* KPI Row */} {/* KPI Row */}
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6">
<KpiCard title="Total Focus Hours" value="124.5" change="+12%" icon={Zap} trend="up" />
<KpiCard title="Goal Completion" value="82%" change="+4%" icon={Target} trend="up" color="emerald" />
<KpiCard title="Productivity Score" value="9.2" change="-2%" icon={TrendingUp} trend="down" color="blue" />
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 relative overflow-hidden group"> {/* Dynamic AI Score Ring */}
<div className="absolute top-0 right-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity"> <div className="rounded-sm border border-primary/20 bg-primary/5 p-6 relative overflow-hidden group flex items-center justify-between">
<Zap className="h-16 w-16 text-primary" /> <div>
<h3 className="text-[10px] font-bold uppercase tracking-widest text-primary mb-2">Strategic Readiness</h3>
<div className="text-3xl font-black text-foreground">94<span className="text-sm font-normal opacity-60 ml-1">%</span></div>
<p className="text-[10px] text-muted-foreground mt-2 font-medium">Optimal alignment with goals.</p>
</div> </div>
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4">Total Focus Hours</h3> <div className="relative w-16 h-16">
<div className="flex items-end gap-3 mb-1"> <svg className="w-full h-full" viewBox="0 0 36 36">
<span className="text-4xl font-bold text-foreground">124.5</span> <path className="text-white/5" stroke="currentColor" strokeWidth="3" fill="none" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" />
<span className="text-xs text-emerald-500 flex items-center font-medium mb-1"> <motion.path
<ArrowUpRight className="h-3 w-3 mr-0.5" /> 12% initial={{ pathLength: 0 }}
</span> animate={{ pathLength: 0.94 }}
transition={{ duration: 1.5, ease: "easeOut" }}
className="text-primary"
stroke="currentColor"
strokeWidth="3"
strokeDasharray="100, 100"
fill="none"
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
/>
</svg>
<div className="absolute inset-0 flex items-center justify-center">
<Brain className="h-4 w-4 text-primary" />
</div>
</div> </div>
<div className="text-[11px] text-muted-foreground">vs previous 30 days</div>
</div> </div>
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 relative overflow-hidden group">
<div className="absolute top-0 right-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
<Target className="h-16 w-16 text-emerald-500" />
</div>
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4">Goal Completion</h3>
<div className="flex items-end gap-3 mb-1">
<span className="text-4xl font-bold text-foreground">82%</span>
<span className="text-xs text-emerald-500 flex items-center font-medium mb-1">
<ArrowUpRight className="h-3 w-3 mr-0.5" /> 4%
</span>
</div>
<div className="text-[11px] text-muted-foreground">vs previous 30 days</div>
</div>
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 relative overflow-hidden group">
<div className="absolute top-0 right-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
<TrendingUp className="h-16 w-16 text-blue-500" />
</div>
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4">Productivity Score</h3>
<div className="flex items-end gap-3 mb-1">
<span className="text-4xl font-bold text-foreground">9.2</span>
<span className="text-xs text-rose-500 flex items-center font-medium mb-1">
<ArrowDownRight className="h-3 w-3 mr-0.5" /> 2%
</span>
</div>
<div className="text-[11px] text-muted-foreground">Out of 10.0 max</div>
</div>
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 relative overflow-hidden group flex flex-col justify-between">
<div className="flex items-center gap-2 mb-2">
<Brain className="h-4 w-4 text-primary" />
<h3 className="text-xs font-semibold uppercase tracking-wider text-primary">AI Insight</h3>
</div>
<p className="text-xs text-foreground/80 leading-relaxed font-medium">
Your energy peaks consistently around <span className="text-primary font-bold">10:00 AM</span>. Consider scheduling complex tasks during this block to maximize output.
</p>
</div>
</div> </div>
{/* Charts Grid */} {/* Main Analysis Area */}
<div className="grid grid-cols-1 xl:grid-cols-3 gap-6 flex-1 min-h-[400px]"> <div className="grid grid-cols-1 xl:grid-cols-3 gap-6 flex-1 min-h-[400px]">
{/* Main Area Chart */} {/* Productivity Chart with Hotspots */}
<div className="xl:col-span-2 rounded-sm border border-white/5 bg-[#0A0710] p-6 flex flex-col"> <div className="xl:col-span-2 rounded-sm border border-white/5 bg-[#0A0710] p-8 flex flex-col relative">
<div className="flex justify-between items-start mb-6"> <div className="flex justify-between items-start mb-8">
<div> <div>
<h3 className="text-sm font-semibold mb-1">Productivity vs Energy Correlation</h3> <h3 className="text-lg font-bold mb-1">Correlation: Focus vs Energy</h3>
<p className="text-xs text-muted-foreground">How your physical energy levels impact deep work output.</p> <p className="text-sm text-muted-foreground">Detailed visual mapping of biological energy impact on focus output.</p>
</div> </div>
<div className="flex gap-4 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground"> <div className="flex gap-4 text-[10px] font-bold uppercase tracking-widest text-muted-foreground">
<div className="flex items-center gap-2"><div className="w-2 h-2 rounded-sm bg-[#6C5BB0]"></div> Focus Score</div> <div className="flex items-center gap-2"><div className="w-2 h-2 rounded-full bg-[#6C5BB0]"></div> Focus</div>
<div className="flex items-center gap-2"><div className="w-2 h-2 rounded-sm bg-emerald-500"></div> Energy Level</div> <div className="flex items-center gap-2"><div className="w-2 h-2 rounded-full bg-emerald-500"></div> Energy</div>
</div> </div>
</div> </div>
{/* Chart Interaction Layer */}
<div className="absolute top-24 left-1/2 -translate-x-1/2 z-10 flex gap-4">
<button
onMouseEnter={() => setActiveInsight("Your energy and focus peaked together on May 20. This suggests your evening rest was highly effective.")}
onMouseLeave={() => setActiveInsight(null)}
className="p-2 bg-primary/20 border border-primary/40 rounded-full text-primary hover:scale-110 transition-transform animate-pulse"
>
<Info className="h-4 w-4" />
</button>
</div>
<AnimatePresence>
{activeInsight && (
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
className="absolute top-36 left-1/2 -translate-x-1/2 z-20 w-64 p-3 bg-[#1F172B] border border-primary/30 rounded-sm shadow-2xl text-[11px] leading-relaxed text-foreground"
>
<div className="flex items-center gap-2 mb-1 text-primary font-bold uppercase tracking-widest">
<Brain className="h-3 w-3" /> AI Observation
</div>
{activeInsight}
</motion.div>
)}
</AnimatePresence>
<div className="flex-1 w-full min-h-[300px]"> <div className="flex-1 w-full min-h-[300px]">
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
<AreaChart data={productivityTrend}> <AreaChart data={productivityTrend}>
<defs> <defs>
<linearGradient id="colorFocus" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="colorFocus" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#6C5BB0" stopOpacity={0.3}/> <stop offset="5%" stopColor="#6C5BB0" stopOpacity={0.4}/>
<stop offset="95%" stopColor="#6C5BB0" stopOpacity={0}/> <stop offset="95%" stopColor="#6C5BB0" stopOpacity={0}/>
</linearGradient> </linearGradient>
<linearGradient id="colorEnergy" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="colorEnergy" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#10b981" stopOpacity={0.3}/> <stop offset="5%" stopColor="#10b981" stopOpacity={0.4}/>
<stop offset="95%" stopColor="#10b981" stopOpacity={0}/> <stop offset="95%" stopColor="#10b981" stopOpacity={0}/>
</linearGradient> </linearGradient>
</defs> </defs>
@@ -157,61 +180,76 @@ export default function AnalyticsPage() {
<XAxis dataKey="date" axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5' }} dy={10} /> <XAxis dataKey="date" axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5' }} dy={10} />
<YAxis axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5' }} dx={-10} /> <YAxis axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5' }} dx={-10} />
<Tooltip <Tooltip
contentStyle={{ backgroundColor: "#1F172B", border: "none", fontSize: "12px", color: "#FBF9FE", borderRadius: "4px" }} cursor={{ stroke: '#6C5BB0', strokeWidth: 1 }}
itemStyle={{ color: "#FBF9FE" }} contentStyle={{ backgroundColor: "#150F1D", border: "1px solid rgba(255,255,255,0.05)", fontSize: "12px", color: "#FBF9FE", borderRadius: "4px" }}
/> />
<Area type="monotone" dataKey="focus" stroke="#6C5BB0" strokeWidth={2} fillOpacity={1} fill="url(#colorFocus)" /> <Area type="monotone" dataKey="focus" stroke="#6C5BB0" strokeWidth={3} fillOpacity={1} fill="url(#colorFocus)" />
<Area type="monotone" dataKey="energy" stroke="#10b981" strokeWidth={2} fillOpacity={1} fill="url(#colorEnergy)" /> <Area type="monotone" dataKey="energy" stroke="#10b981" strokeWidth={3} fillOpacity={1} fill="url(#colorEnergy)" />
</AreaChart> </AreaChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>
</div> </div>
{/* Side Charts Stack */} {/* Sidebar Insights */}
<div className="flex flex-col gap-6"> <div className="flex flex-col gap-6">
{/* Radar Chart */}
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 flex-1 flex flex-col"> <div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 flex-1 flex flex-col">
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4">Effort Distribution</h3> <h3 className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground mb-6">Effort Distribution</h3>
<div className="flex-1 w-full min-h-[200px] flex items-center justify-center"> <div className="flex-1 flex items-center justify-center">
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
<RadarChart cx="50%" cy="50%" outerRadius="70%" data={focusRadarData}> <RadarChart cx="50%" cy="50%" outerRadius="80%" data={focusRadarData}>
<PolarGrid stroke="#ffffff10" /> <PolarGrid stroke="#ffffff05" />
<PolarAngleAxis dataKey="subject" tick={{ fill: '#8F89A5', fontSize: 10 }} /> <PolarAngleAxis dataKey="subject" tick={{ fill: '#8F89A5', fontSize: 10, fontWeight: 600 }} />
<Radar name="Effort" dataKey="A" stroke="#6C5BB0" fill="#6C5BB0" fillOpacity={0.3} /> <Radar name="Effort" dataKey="A" stroke="#6C5BB0" strokeWidth={2} fill="#6C5BB0" fillOpacity={0.4} />
<Tooltip <Tooltip contentStyle={{ backgroundColor: "#1F172B", border: "none", fontSize: "12px" }} />
contentStyle={{ backgroundColor: "#1F172B", border: "none", fontSize: "12px", color: "#FBF9FE" }}
itemStyle={{ color: "#FBF9FE" }}
/>
</RadarChart> </RadarChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>
</div> </div>
{/* Bar Chart */} <div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 flex-1">
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 flex-1 flex flex-col"> <h3 className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground mb-6">Strategic Alerts</h3>
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4">Habit Consistency</h3> <div className="space-y-4">
<div className="flex-1 w-full min-h-[150px]"> <div className="flex items-start gap-3 p-3 rounded-sm bg-emerald-500/5 border border-emerald-500/10">
<ResponsiveContainer width="100%" height="100%"> <CheckCircle2 className="h-4 w-4 text-emerald-500 mt-0.5" />
<BarChart data={habitCompletion} layout="vertical" margin={{ left: 0, right: 0, top: 0, bottom: 0 }}> <div>
<XAxis type="number" hide /> <div className="text-xs font-bold text-emerald-400">Habit Streak Maintained</div>
<YAxis dataKey="name" type="category" axisLine={false} tickLine={false} tick={{ fontSize: 10, fill: '#8F89A5' }} width={70} /> <div className="text-[10px] text-muted-foreground mt-1">Reading streak is now at 12 days. Energy levels are correlating positively.</div>
<Tooltip </div>
cursor={{ fill: '#ffffff05' }} </div>
contentStyle={{ backgroundColor: "#1F172B", border: "none", fontSize: "12px", color: "#FBF9FE" }} <div className="flex items-start gap-3 p-3 rounded-sm bg-orange-500/5 border border-orange-500/10">
itemStyle={{ color: "#FBF9FE" }} <AlertCircle className="h-4 w-4 text-orange-500 mt-0.5" />
/> <div>
<Bar dataKey="completed" stackId="a" fill="#6C5BB0" radius={[2, 0, 0, 2]} barSize={12} /> <div className="text-xs font-bold text-orange-400">Admin Overload</div>
<Bar dataKey="missed" stackId="a" fill="#2B2538" radius={[0, 2, 2, 0]} barSize={12} /> <div className="text-[10px] text-muted-foreground mt-1">Admin tasks have increased by 15%. Consider automating these via Cognis AI.</div>
</BarChart> </div>
</ResponsiveContainer> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
);
}
function KpiCard({ title, value, change, icon: Icon, trend, color = "primary" }: any) {
const isUp = trend === "up";
const trendColor = isUp ? "text-emerald-500" : "text-rose-500";
return (
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 relative overflow-hidden group">
<div className={`absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity ${color === 'primary' ? 'text-primary' : color === 'emerald' ? 'text-emerald-500' : 'text-blue-500'}`}>
<Icon className="h-16 w-16" />
</div>
<h3 className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground mb-4">{title}</h3>
<div className="flex items-end gap-3 mb-1">
<span className="text-4xl font-black text-foreground tracking-tight">{value}</span>
<span className={`text-[10px] flex items-center font-bold mb-1.5 px-1.5 py-0.5 rounded-sm bg-white/5 ${trendColor}`}>
{isUp ? <ArrowUpRight className="h-3 w-3 mr-0.5" /> : <ArrowDownRight className="h-3 w-3 mr-0.5" />} {change}
</span>
</div>
<div className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">vs previous 30 days</div>
</div> </div>
); );
} }
+170 -46
View File
@@ -1,6 +1,11 @@
"use client"; "use client";
import { ChevronLeft, ChevronRight, Plus, Search, Calendar as CalendarIcon, Clock, Filter, MoreHorizontal, Brain } from "lucide-react"; import { useState } from "react";
import {
ChevronLeft, ChevronRight, Plus, Search, Calendar as CalendarIcon,
Clock, Filter, MoreHorizontal, Brain, X, Check, ArrowRight
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const categories = [ const categories = [
@@ -25,16 +30,13 @@ const mockEvents = [
const daysOfWeek = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; const daysOfWeek = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
// Generates a mock calendar grid for a 30-day month starting on a Tuesday
const generateCalendarDays = () => { const generateCalendarDays = () => {
const days = []; const days = [];
// 1 empty slot for Monday before the 1st
days.push({ empty: true, key: "empty-0" }); days.push({ empty: true, key: "empty-0" });
for (let i = 1; i <= 30; i++) { for (let i = 1; i <= 30; i++) {
const events = mockEvents.filter((e) => e.day === i); const events = mockEvents.filter((e) => e.day === i);
days.push({ empty: false, day: i, events, isToday: i === 15 }); days.push({ empty: false, day: i, events, isToday: i === 15 });
} }
// Fill the rest of the grid (35 total cells for a 5-week view)
const remaining = 35 - days.length; const remaining = 35 - days.length;
for (let i = 1; i <= remaining; i++) { for (let i = 1; i <= remaining; i++) {
days.push({ empty: true, key: `empty-end-${i}` }); days.push({ empty: true, key: `empty-end-${i}` });
@@ -43,13 +45,53 @@ const generateCalendarDays = () => {
}; };
export default function CalendarPage() { export default function CalendarPage() {
const [selectedDay, setSelectedDay] = useState<any>(null);
const [isOptimizing, setIsOptimizing] = useState(false);
const calendarDays = generateCalendarDays(); const calendarDays = generateCalendarDays();
const handleOptimize = () => {
setIsOptimizing(true);
setTimeout(() => setIsOptimizing(false), 2500);
};
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans relative">
{/* Optimization Overlay */}
<AnimatePresence>
{isOptimizing && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="absolute inset-0 z-50 bg-[#0A0710]/80 backdrop-blur-md flex flex-col items-center justify-center"
>
<motion.div
animate={{
scale: [1, 1.2, 1],
rotate: [0, 10, -10, 0]
}}
transition={{ repeat: Infinity, duration: 1.5 }}
className="mb-6"
>
<Brain className="h-16 w-16 text-primary" />
</motion.div>
<h2 className="text-xl font-bold mb-2">AI Schedule Optimization</h2>
<p className="text-muted-foreground text-sm">Analyzing energy trends and focus blocks...</p>
<div className="w-48 h-1 bg-white/10 rounded-full mt-6 overflow-hidden">
<motion.div
initial={{ x: "-100%" }}
animate={{ x: "100%" }}
transition={{ repeat: Infinity, duration: 1, ease: "linear" }}
className="w-full h-full bg-primary"
/>
</div>
</motion.div>
)}
</AnimatePresence>
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mb-6"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mb-6 mt-4">
<h1 className="text-lg font-medium text-muted-foreground"> <h1 className="text-lg font-medium text-muted-foreground">
<span className="text-foreground">Calendar</span> / Monthly View <span className="text-foreground">Calendar</span> / Monthly View
</h1> </h1>
@@ -62,7 +104,10 @@ export default function CalendarPage() {
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground" className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/> />
</div> </div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <button
onClick={() => setSelectedDay({ day: 15, events: mockEvents.filter(e => e.day === 15) })}
className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-all active:scale-95 shadow-lg shadow-primary/20"
>
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
NEW EVENT NEW EVENT
</button> </button>
@@ -92,15 +137,11 @@ export default function CalendarPage() {
{[...Array(30)].map((_, i) => ( {[...Array(30)].map((_, i) => (
<div <div
key={i} key={i}
className={`py-1 rounded-sm cursor-pointer hover:bg-white/5 ${i + 1 === 15 ? 'bg-primary/20 text-primary font-bold' : ''}`} className={`py-1 rounded-sm cursor-pointer hover:bg-white/5 transition-colors ${i + 1 === 15 ? 'bg-primary/20 text-primary font-bold' : ''}`}
> >
{i + 1} {i + 1}
</div> </div>
))} ))}
<div className="text-muted-foreground/30 py-1">1</div>
<div className="text-muted-foreground/30 py-1">2</div>
<div className="text-muted-foreground/30 py-1">3</div>
<div className="text-muted-foreground/30 py-1">4</div>
</div> </div>
</div> </div>
@@ -113,40 +154,35 @@ export default function CalendarPage() {
<div className="space-y-3"> <div className="space-y-3">
{categories.map((cat, idx) => ( {categories.map((cat, idx) => (
<label key={idx} className="flex items-center gap-3 cursor-pointer group"> <label key={idx} className="flex items-center gap-3 cursor-pointer group">
<div className={`w-3 h-3 rounded-sm ${cat.color} ring-2 ring-transparent group-hover:ring-white/10 transition-all`}></div> <div className={`w-3 h-3 rounded-sm ${cat.color} ring-2 ring-transparent group-hover:ring-white/10 transition-all shadow-[0_0_8px_rgba(108,91,176,0.3)]`}></div>
<span className="text-sm text-muted-foreground group-hover:text-foreground transition-colors">{cat.name}</span> <span className="text-sm text-muted-foreground group-hover:text-foreground transition-colors">{cat.name}</span>
</label> </label>
))} ))}
</div> </div>
<div className="mt-8 mb-5 border-t border-white/5 pt-5">
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Shared Context</h3>
</div>
<div className="space-y-3">
<label className="flex items-center gap-3 cursor-pointer group">
<div className="w-3 h-3 rounded-sm border border-muted-foreground/40 group-hover:border-muted-foreground transition-all"></div>
<span className="text-sm text-muted-foreground group-hover:text-foreground transition-colors">Team Holidays</span>
</label>
<label className="flex items-center gap-3 cursor-pointer group">
<div className="w-3 h-3 rounded-sm bg-muted-foreground/40 group-hover:bg-muted-foreground transition-all"></div>
<span className="text-sm text-muted-foreground group-hover:text-foreground transition-colors">Company Events</span>
</label>
</div>
</div> </div>
{/* AI Features */} {/* AI Optimizer Card */}
<div className="rounded-sm border border-primary/20 bg-primary/5 p-5 flex flex-col gap-3"> <motion.div
whileHover={{ y: -4 }}
className="rounded-sm border border-primary/20 bg-primary/5 p-5 flex flex-col gap-3 relative overflow-hidden"
>
<div className="absolute -right-4 -bottom-4 opacity-5 rotate-12">
<Brain className="h-24 w-24 text-primary" />
</div>
<div className="flex items-center gap-2 mb-1"> <div className="flex items-center gap-2 mb-1">
<Brain className="h-4 w-4 text-primary" /> <Brain className="h-4 w-4 text-primary" />
<h3 className="text-xs font-semibold uppercase tracking-wider text-primary">AI Assistant</h3> <h3 className="text-xs font-semibold uppercase tracking-wider text-primary">AI Optimizer</h3>
</div> </div>
<p className="text-[11px] text-muted-foreground leading-relaxed"> <p className="text-[11px] text-muted-foreground leading-relaxed">
Based on your energy trends, I suggest moving the <strong>UI Review</strong> to Thursday afternoon. Detected focus peak at 10 AM on Thursdays. Suggest moving **UI Review** to maximize alignment.
</p> </p>
<button className="bg-primary/20 text-primary hover:bg-primary/30 border border-primary/30 px-3 py-1.5 rounded-sm text-xs font-semibold transition-colors mt-2 text-center flex justify-center w-full"> <button
Auto-Optimize Schedule onClick={handleOptimize}
className="bg-primary/10 text-primary hover:bg-primary/20 border border-primary/20 px-3 py-1.5 rounded-sm text-[10px] font-bold uppercase tracking-widest transition-all mt-2 text-center flex justify-center w-full"
>
Run AI Optimization
</button> </button>
</div> </motion.div>
</div> </div>
@@ -170,7 +206,7 @@ export default function CalendarPage() {
</div> </div>
</div> </div>
{/* Calendar Header (Days) */} {/* Calendar Header */}
<div className="grid grid-cols-7 border-b border-white/5 bg-[#0F0B15]/50"> <div className="grid grid-cols-7 border-b border-white/5 bg-[#0F0B15]/50">
{daysOfWeek.map((day) => ( {daysOfWeek.map((day) => (
<div key={day} className="py-3 text-center text-[11px] font-semibold uppercase tracking-wider text-muted-foreground"> <div key={day} className="py-3 text-center text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">
@@ -182,34 +218,122 @@ export default function CalendarPage() {
{/* Calendar Grid */} {/* Calendar Grid */}
<div className="flex-1 grid grid-cols-7 grid-rows-5 overflow-hidden bg-white/[0.02] gap-[1px]"> <div className="flex-1 grid grid-cols-7 grid-rows-5 overflow-hidden bg-white/[0.02] gap-[1px]">
{calendarDays.map((cell, idx) => ( {calendarDays.map((cell, idx) => (
<div <motion.div
key={cell.key || cell.day} key={cell.key || cell.day}
className={`bg-[#0A0710] p-2 flex flex-col gap-1 transition-colors hover:bg-[#0F0B15] relative group ${cell.empty ? 'opacity-30' : ''}`} whileHover={{ backgroundColor: "rgba(15, 11, 21, 0.8)" }}
onClick={() => !cell.empty && setSelectedDay(cell)}
className={`bg-[#0A0710] p-2 flex flex-col gap-1 transition-all cursor-pointer relative group ${cell.empty ? 'opacity-30 pointer-events-none' : ''}`}
> >
{!cell.empty && ( {!cell.empty && (
<div className={`text-xs font-medium mb-1 w-6 h-6 flex items-center justify-center rounded-sm ${cell.isToday ? 'bg-primary text-primary-foreground' : 'text-muted-foreground group-hover:text-foreground'}`}> <div className={`text-xs font-medium mb-1 w-6 h-6 flex items-center justify-center rounded-sm transition-colors ${cell.isToday ? 'bg-primary text-primary-foreground shadow-[0_0_12px_rgba(108,91,176,0.5)]' : 'text-muted-foreground group-hover:text-foreground'}`}>
{cell.day} {cell.day}
</div> </div>
)} )}
{/* Events */}
<div className="flex-1 overflow-y-auto tiny-scrollbar flex flex-col gap-1 pr-1"> <div className="flex-1 overflow-y-auto tiny-scrollbar flex flex-col gap-1 pr-1">
{cell.events?.map((event, eIdx) => ( {cell.events?.map((event, eIdx) => (
<div <motion.div
key={eIdx} key={eIdx}
className={`text-[10px] px-2 py-1 rounded-sm border truncate font-medium cursor-pointer transition-all hover:brightness-125 ${event.colorClass}`} initial={{ opacity: 0, x: -10 }}
title={`${event.time} - ${event.title}`} animate={{ opacity: 1, x: 0 }}
transition={{ delay: idx * 0.01 + eIdx * 0.05 }}
className={`text-[9px] px-1.5 py-1 rounded-sm border truncate font-bold tracking-tight transition-all hover:scale-[1.02] active:scale-95 ${event.colorClass}`}
> >
{event.time} {event.title} {event.title}
</div> </motion.div>
))} ))}
</div> </div>
</div> </motion.div>
))} ))}
</div> </div>
</div> </div>
</div> </div>
{/* Quick Entry Sheet */}
<AnimatePresence>
{selectedDay && (
<>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={() => setSelectedDay(null)}
className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[100]"
/>
<motion.div
initial={{ x: "100%" }}
animate={{ x: 0 }}
exit={{ x: "100%" }}
transition={{ type: "spring", damping: 25, stiffness: 200 }}
className="fixed top-0 right-0 h-full w-full max-w-md bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col"
>
<div className="p-6 border-b border-white/5 flex items-center justify-between bg-[#0F0B15]/50">
<div>
<h2 className="text-xl font-bold">May {selectedDay.day}, 2026</h2>
<p className="text-xs text-muted-foreground uppercase tracking-widest mt-1">Daily Schedule Overview</p>
</div>
<button onClick={() => setSelectedDay(null)} className="p-2 hover:bg-white/5 rounded-sm transition-colors text-muted-foreground hover:text-foreground">
<X className="h-5 w-5" />
</button>
</div>
<div className="flex-1 overflow-y-auto p-6 space-y-8">
<div>
<h3 className="text-[10px] font-bold uppercase tracking-widest text-primary mb-4 flex items-center gap-2">
<Clock className="h-3.5 w-3.5" /> Scheduled Events
</h3>
<div className="space-y-3">
{selectedDay.events?.length > 0 ? (
selectedDay.events.map((event: any, idx: number) => (
<div key={idx} className="p-4 rounded-sm border border-white/5 bg-[#150F1D] flex items-center justify-between group">
<div className="flex items-center gap-3">
<div className={`w-1 h-8 rounded-full ${event.colorClass.split(' ')[0]}`} />
<div>
<div className="text-sm font-bold">{event.title}</div>
<div className="text-[10px] text-muted-foreground">{event.time} {event.type}</div>
</div>
</div>
<button className="opacity-0 group-hover:opacity-100 p-1.5 hover:bg-white/5 rounded-sm transition-opacity">
<MoreHorizontal className="h-4 w-4 text-muted-foreground" />
</button>
</div>
))
) : (
<p className="text-sm text-muted-foreground italic px-2">No events scheduled for this day.</p>
)}
</div>
</div>
<div className="pt-4 border-t border-white/5">
<h3 className="text-[10px] font-bold uppercase tracking-widest text-primary mb-4">Quick Add Event</h3>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1">
<label className="text-[10px] font-bold text-muted-foreground">TIME</label>
<input type="time" className="w-full bg-[#150F1D] border border-white/10 rounded-sm px-3 py-2 text-xs outline-none focus:border-primary/50" />
</div>
<div className="space-y-1">
<label className="text-[10px] font-bold text-muted-foreground">CATEGORY</label>
<select className="w-full bg-[#150F1D] border border-white/10 rounded-sm px-3 py-2 text-xs outline-none focus:border-primary/50">
{categories.map(c => <option key={c.name}>{c.name}</option>)}
</select>
</div>
</div>
<div className="space-y-1">
<label className="text-[10px] font-bold text-muted-foreground">EVENT TITLE</label>
<input type="text" placeholder="e.g., Team Sync" className="w-full bg-[#150F1D] border border-white/10 rounded-sm px-3 py-2 text-xs outline-none focus:border-primary/50" />
</div>
<button className="w-full bg-primary hover:bg-primary/90 text-primary-foreground py-3 rounded-sm text-xs font-bold tracking-widest shadow-lg shadow-primary/20 transition-all active:scale-[0.98]">
ADD TO CALENDAR
</button>
</div>
</div>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div> </div>
); );
} }
+282
View File
@@ -0,0 +1,282 @@
"use client";
import { useState } from "react";
import {
Plus, Search, User, Mail, Phone, Globe,
MoreHorizontal, MessageSquare, Briefcase,
TrendingUp, Star, Clock, X, ChevronRight,
ArrowUpRight, DollarSign, Brain, Shield,
Activity, CheckCircle2, AlertCircle
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data
const clients = [
{
id: 1,
name: "Acme Corp",
contact: "John Doe",
email: "john@acme.com",
status: "Active",
value: "$12,400",
projects: 2,
health: "Stable",
lastContact: "2 days ago",
aiInsight: "Excellent relationship. High potential for upsell into the Q3 Marketing Package.",
history: [
{ type: "Meeting", date: "May 12", note: "Q3 Strategy Review" },
{ type: "Payment", date: "May 08", note: "$4,200 received" },
]
},
{
id: 2,
name: "Global Tech",
contact: "Jane Smith",
email: "jane@global.io",
status: "Onboarding",
value: "$8,500",
projects: 1,
health: "Critical",
lastContact: "1 week ago",
aiInsight: "Risk of churn detected. Last communication was 7 days ago. Immediate outreach suggested.",
history: [
{ type: "Proposal", date: "May 01", note: "Infrastructure Scale" },
]
},
{ id: 3, name: "Nexus Design", contact: "Mike Ross", email: "mike@nexus.com", status: "Active", value: "$42,000", projects: 4, health: "Growth", lastContact: "Today", aiInsight: "Client is expanding rapidly. Consider offering a dedicated project manager role.", history: [] },
{ id: 4, name: "Stark Ind.", contact: "Pepper P.", email: "pepper@stark.com", status: "Lead", value: "$0", projects: 0, health: "Neutral", lastContact: "May 14", aiInsight: "Warm lead from the Webflow conference. Interested in AI integration.", history: [] },
];
export default function ClientsPage() {
const [selectedClient, setSelectedClient] = useState<any>(null);
return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<div className="flex items-center gap-4">
<h1 className="text-lg font-medium text-muted-foreground">
<span className="text-foreground">Network</span> / Strategic Clients
</h1>
<div className="h-4 w-px bg-white/10" />
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-primary bg-primary/5 px-3 py-1 rounded-sm border border-primary/10">
<Users className="h-3 w-3" /> 12 ACTIVE PARTNERSHIPS
</div>
</div>
<div className="flex items-center gap-3">
<div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2">
<Search className="h-4 w-4 text-muted-foreground" />
<input
type="text"
placeholder="Search clients..."
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/>
</div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-5 py-2 rounded-sm text-xs font-black tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/30 active:scale-95">
<Plus className="h-4 w-4" />
ADD CLIENT
</button>
</div>
</div>
{/* CRM Stats */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 shrink-0">
<ClientStatCard label="Pipeline Value" value="$128.5k" subtext="+12% this month" icon={DollarSign} />
<ClientStatCard label="Avg. Health" value="Stable" subtext="92% Retention" icon={Activity} />
<ClientStatCard label="New Leads" value="15" subtext="8 Qualified" icon={TrendingUp} />
<div className="bg-primary/5 border border-primary/20 rounded-sm p-6 flex flex-col justify-center relative overflow-hidden group">
<div className="absolute -right-4 -top-4 opacity-5 rotate-12 transition-transform group-hover:scale-110"><Brain className="h-20 w-20 text-primary" /></div>
<div className="flex items-center gap-2 text-primary font-black uppercase tracking-widest text-[10px] mb-2">
<Brain className="h-3.5 w-3.5" /> AI Insight
</div>
<p className="text-[11px] font-bold text-foreground/80 leading-relaxed italic">
"High churn risk for Global Tech. Immediate outreach suggested."
</p>
</div>
</div>
{/* Main Clients List */}
<div className="flex-1 overflow-y-auto tiny-scrollbar pr-1">
<div className="bg-[#0A0710] border border-white/5 rounded-sm overflow-hidden shadow-2xl">
<div className="grid grid-cols-12 gap-4 p-5 border-b border-white/5 bg-[#0F0B15]/50 text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground">
<div className="col-span-4 px-2">Partner Entity</div>
<div className="col-span-2">Relationship</div>
<div className="col-span-2">Strategic Value</div>
<div className="col-span-2">Engagement</div>
<div className="col-span-2 text-right">Actions</div>
</div>
<div className="divide-y divide-white/5">
{clients.map((client) => (
<motion.div
key={client.id}
onClick={() => setSelectedClient(client)}
className="grid grid-cols-12 gap-4 p-6 items-center hover:bg-white/[0.02] transition-all group cursor-pointer border-l-2 border-transparent hover:border-primary"
>
<div className="col-span-4 flex items-center gap-4">
<div className="h-10 w-10 rounded-sm bg-[#150F1D] border border-white/5 flex items-center justify-center font-black text-primary text-xs uppercase tracking-tighter shadow-inner">
{client.name.split(' ').map(n => n[0]).join('')}
</div>
<div className="min-w-0">
<div className="text-sm font-black group-hover:text-primary transition-colors truncate">{client.name}</div>
<div className="text-[10px] text-muted-foreground font-bold tracking-widest mt-0.5">{client.contact}</div>
</div>
</div>
<div className="col-span-2">
<span className={`text-[9px] font-black uppercase tracking-[0.2em] px-2.5 py-1 rounded-sm border ${
client.health === 'Growth' ? 'text-emerald-400 border-emerald-500/20 bg-emerald-500/5' :
client.health === 'Stable' ? 'text-blue-400 border-blue-500/20 bg-blue-500/5' :
client.health === 'Critical' ? 'text-rose-400 border-rose-500/20 bg-rose-500/5' : 'text-muted-foreground border-white/10'
}`}>
{client.health}
</span>
</div>
<div className="col-span-2 flex flex-col">
<span className="text-sm font-black text-foreground">{client.value}</span>
<span className="text-[9px] text-muted-foreground font-bold uppercase tracking-widest">{client.projects} Active Projects</span>
</div>
<div className="col-span-2 flex flex-col">
<span className="text-xs font-bold text-foreground">{client.lastContact}</span>
<span className="text-[9px] text-muted-foreground font-bold uppercase tracking-widest mt-0.5">Last Touchpoint</span>
</div>
<div className="col-span-2 flex justify-end gap-1 opacity-0 group-hover:opacity-100 transition-all">
<button className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><MessageSquare className="h-4 w-4" /></button>
<button className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><MoreHorizontal className="h-4 w-4" /></button>
</div>
</motion.div>
))}
</div>
</div>
</div>
{/* Client Detail Sheet */}
<AnimatePresence>
{selectedClient && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedClient(null)} className="fixed inset-0 bg-black/80 backdrop-blur-md z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-2xl bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col">
<div className="p-10 border-b border-white/5 flex items-center justify-between bg-primary/5">
<div className="flex items-center gap-6">
<div className="h-16 w-16 rounded-sm bg-primary/10 border border-primary/20 flex items-center justify-center font-black text-primary text-xl uppercase shadow-xl">
{selectedClient.name.split(' ').map((n: string) => n[0]).join('')}
</div>
<div className="space-y-1">
<h2 className="text-3xl font-black tracking-tighter text-foreground">{selectedClient.name}</h2>
<div className="flex items-center gap-3">
<span className="text-[10px] font-black text-primary uppercase tracking-widest">{selectedClient.contact}</span>
<div className="w-1 h-1 rounded-full bg-white/20" />
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">{selectedClient.email}</span>
</div>
</div>
</div>
<button onClick={() => setSelectedClient(null)} className="p-3 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><X className="h-6 w-6" /></button>
</div>
<div className="flex-1 overflow-y-auto p-10 space-y-12 tiny-scrollbar">
{/* AI Client Pulse */}
<div className="rounded-sm border border-primary/20 bg-primary/5 p-8 space-y-4 relative overflow-hidden">
<div className="absolute -right-4 -top-4 opacity-5">
<Brain className="h-24 w-24 text-primary" />
</div>
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary flex items-center gap-2">
<Brain className="h-4 w-4" /> Client Health Pulse
</h3>
<p className="text-sm font-medium text-foreground/90 leading-relaxed italic">
"{selectedClient.aiInsight}"
</p>
</div>
{/* Key Financials */}
<div className="grid grid-cols-2 gap-8">
<div className="bg-[#150F1D] border border-white/5 rounded-sm p-6 space-y-2">
<div className="text-[10px] font-black text-muted-foreground uppercase tracking-widest">LIFETIME VALUE</div>
<div className="text-2xl font-black text-primary">{selectedClient.value}</div>
</div>
<div className="bg-[#150F1D] border border-white/5 rounded-sm p-6 space-y-2">
<div className="text-[10px] font-black text-muted-foreground uppercase tracking-widest">ACTIVE DELIVERABLES</div>
<div className="text-2xl font-black text-foreground">{selectedClient.projects}</div>
</div>
</div>
{/* Relationship History */}
<div className="space-y-6">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Relationship Log</h3>
<div className="relative space-y-6 pl-6 before:absolute before:left-[11px] before:top-2 before:bottom-2 before:w-px before:bg-white/10">
{selectedClient.history?.length > 0 ? selectedClient.history.map((log: any, i: number) => (
<div key={i} className="relative group">
<div className="absolute -left-[23px] top-1 h-3 w-3 rounded-full border-2 border-[#0A0710] bg-primary z-10" />
<div className="flex justify-between items-start">
<div>
<div className="text-sm font-bold group-hover:text-primary transition-colors">{log.note}</div>
<div className="text-[10px] text-muted-foreground mt-1 uppercase font-medium">{log.date} {log.type}</div>
</div>
</div>
</div>
)) : <p className="text-xs text-muted-foreground italic">No historical log entries found for this partner.</p>}
</div>
</div>
{/* Quick Actions */}
<div className="space-y-6 pt-6 border-t border-white/5">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Strategic Actions</h3>
<div className="grid grid-cols-2 gap-4">
<ActionButton icon={Briefcase} label="Launch New Project" />
<ActionButton icon={DollarSign} label="Generate Invoice" />
<ActionButton icon={MessageSquare} label="Relationship Review" />
<ActionButton icon={Shield} label="Update Contract" />
</div>
</div>
</div>
<div className="p-10 border-t border-white/5 bg-[#0F0B15]/50 flex gap-4">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-5 rounded-sm text-[11px] font-black uppercase tracking-widest shadow-2xl shadow-primary/30 transition-all active:scale-[0.98]">
OPEN PARTNER PORTAL
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}
function ActionButton({ icon: Icon, label }: { icon: any, label: string }) {
return (
<button className="p-4 rounded-sm bg-[#150F1D] border border-white/5 flex items-center gap-3 group hover:border-primary/20 transition-all text-left">
<div className="p-2 bg-white/5 rounded-sm group-hover:bg-primary/10 transition-colors">
<Icon className="h-4 w-4 text-muted-foreground group-hover:text-primary" />
</div>
<span className="text-[10px] font-black text-muted-foreground uppercase tracking-widest leading-tight group-hover:text-foreground">{label}</span>
</button>
);
}
function ClientStatCard({ label, value, subtext, icon: Icon }: any) {
return (
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex items-center gap-6 group relative overflow-hidden shadow-xl">
<div className="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity">
<Icon className="h-20 w-20 text-foreground" />
</div>
<div className="p-4 bg-white/5 rounded-sm group-hover:bg-primary/10 transition-colors relative z-10">
<Icon className="h-6 w-6 text-muted-foreground group-hover:text-primary transition-colors" />
</div>
<div className="relative z-10">
<div className="text-[10px] font-black uppercase tracking-[0.2em] text-muted-foreground mb-1">{label}</div>
<div className="flex items-baseline gap-2">
<span className="text-3xl font-black text-foreground tracking-tighter leading-none">{value}</span>
<span className="text-[10px] text-emerald-500 font-bold uppercase tracking-widest">{subtext}</span>
</div>
</div>
</div>
);
}
+340 -113
View File
@@ -1,154 +1,381 @@
"use client"; "use client";
import { Plus, Search, Filter, Brain, FileText, Download, MoreHorizontal, FileSpreadsheet, FileIcon, MessageSquare } from "lucide-react"; import { useState } from "react";
import {
Plus, Search, FileText, File, Image, Music, Video,
MoreHorizontal, Download, Share2, Trash2, Eye,
Layout, List, Brain, Clock, ChevronRight, X,
Folder, HardDrive, Shield, Cloud, Tag, Info,
Star, Filter, Zap, Globe, ExternalLink, Activity
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const documents = [ const documents = [
{ {
id: 1, id: 1,
name: "Q3 Strategy Planning.docx", name: "Marketing Strategy 2026.pdf",
type: "word", type: "PDF",
size: "2.4 MB", size: "2.4 MB",
updated: "2 hours ago", date: "May 10, 2026",
aiStatus: "Summarized", category: "Strategy",
aiSummary: "Focuses on user acquisition and shifting marketing budget to TikTok ads. AI extracted 4 key action items." starred: true,
summary: "Comprehensive roadmap for Q3 marketing funnels and ad spend allocation.",
owner: "Sarah J.",
tags: ["Marketing", "Strategy", "Q3"],
aiAnalysis: "This document outlines a 15% increase in digital spend. Key focus is on video-first content."
}, },
{ {
id: 2, id: 2,
name: "Financial_Report_May.xlsx", name: "Project Brand Identity.fig",
type: "excel", type: "FIG",
size: "5.1 MB", size: "15.8 MB",
updated: "Yesterday", date: "May 08, 2026",
aiStatus: "Analyzing", category: "Design",
aiSummary: "AI is currently detecting anomalies in the Q2 vs Q3 expense margins." starred: false,
summary: "Core design tokens, typography, and color palette for the Cognis rebrand.",
owner: "Alex R.",
tags: ["Design", "UI", "Branding"],
aiAnalysis: "Identifies 'Cyber-Lavender' as the primary action color. Typography is set to Geist Sans."
}, },
{ { id: 3, name: "Client Contracts Bundle.zip", type: "ZIP", size: "4.2 MB", date: "May 05, 2026", category: "Legal", starred: true, summary: "Collection of signed service agreements for the top 5 enterprise clients.", owner: "Emma W.", tags: ["Legal", "Enterprise"] },
id: 3, { id: 4, name: "Revenue Forecast Q3.xlsx", type: "XLSX", size: "1.1 MB", date: "May 01, 2026", category: "Finance", starred: false, summary: "Predicted revenue growth based on current subscription trends and churn rates.", owner: "Sarah J.", tags: ["Finance", "Data"] },
name: "Design_System_Guidelines.pdf", { id: 5, name: "User Research Session 01.mp4", type: "MP4", size: "142 MB", date: "Apr 28, 2026", category: "Research", starred: false, summary: "Interview with primary persona 'Executive Alex' regarding workflow pain points.", owner: "Mike C.", tags: ["Research", "User-Test"] },
type: "pdf", ];
size: "12 MB",
updated: "May 04, 2026", const storageStats = [
aiStatus: "Summarized", { label: "Documents", size: "1.2 GB", color: "bg-primary", percentage: 65 },
aiSummary: "Details the new dark mode color tokens (#0A0710). AI created a searchable index for developers." { label: "Media", size: "800 MB", color: "bg-blue-500", percentage: 25 },
}, { label: "Others", size: "400 MB", color: "bg-white/20", percentage: 10 },
{
id: 4,
name: "Client_Feedback_Transcript.txt",
type: "text",
size: "145 KB",
updated: "May 01, 2026",
aiStatus: "Action Required",
aiSummary: "Sentiment analysis is extremely negative regarding the login flow. AI flagged this for urgent review."
}
]; ];
export default function DocumentsPage() { export default function DocumentsPage() {
const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
const [selectedDoc, setSelectedDoc] = useState<any>(null);
const [activeFolder, setActiveFolder] = useState("All Files");
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<h1 className="text-lg font-medium text-muted-foreground"> <div className="flex items-center gap-4">
<span className="text-foreground">Management</span> / Documents <h1 className="text-lg font-medium text-muted-foreground">
</h1> <span className="text-foreground">Resources</span> / Documents & Drive
</h1>
<div className="h-4 w-px bg-white/10 hidden md:block" />
<div className="hidden md:flex items-center gap-3">
<div className="flex -space-x-2">
{[1, 2, 3].map(i => <div key={i} className="h-6 w-6 rounded-full border-2 border-[#0A0710] bg-[#1F172B] flex items-center justify-center text-[8px] font-bold">U{i}</div>)}
</div>
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">Shared with team</span>
</div>
</div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2"> <div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2">
<Search className="h-4 w-4 text-muted-foreground" /> <Search className="h-4 w-4 text-muted-foreground" />
<input <input
type="text" type="text"
placeholder="Search documents or ask AI..." placeholder="Search files..."
className="bg-transparent border-none outline-none text-xs w-64 placeholder:text-muted-foreground/50 text-foreground" className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground font-medium"
/> />
</div> </div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-5 py-2 rounded-sm text-xs font-black tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/30 active:scale-95">
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
UPLOAD UPLOAD FILE
</button> </button>
</div> </div>
</div> </div>
{/* AI Semantic Search Banner */} <div className="flex-1 flex gap-8 min-h-0">
<div className="rounded-sm border border-primary/20 bg-[linear-gradient(90deg,rgba(108,91,176,0.1)_0%,rgba(10,7,16,0)_100%)] p-6 flex flex-col gap-4">
<div className="flex items-center gap-2">
<Brain className="h-5 w-5 text-primary" />
<h2 className="text-sm font-semibold">Talk to your Workspace</h2>
</div>
<p className="text-xs text-muted-foreground w-1/2 leading-relaxed">
The AI has indexed 1,240 documents. Instead of searching by keywords, ask a direct question like <em>"What were the key takeaways from the Q3 Strategy?"</em>
</p>
<div className="flex gap-2">
<input
type="text"
placeholder="Ask anything about your files..."
className="flex-1 bg-[#0A0710] border border-white/10 rounded-sm px-4 py-2 text-sm outline-none focus:border-primary/50 transition-colors"
/>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground px-6 py-2 rounded-sm text-sm font-semibold transition-colors">
Ask AI
</button>
</div>
</div>
{/* Document List */} {/* Left Sidebar: Navigation & Storage */}
<div className="grid grid-cols-1 gap-4"> <div className="hidden xl:flex w-72 flex-col gap-8 shrink-0">
{documents.map((doc) => (
<div key={doc.id} className="rounded-sm border border-white/5 bg-[#0A0710] p-5 flex flex-col md:flex-row md:items-center gap-6 group hover:border-white/10 transition-colors">
{/* File Info */} <div className="space-y-1">
<div className="flex items-center gap-4 min-w-[300px]"> {["All Files", "Recent", "Starred", "Shared", "Trash"].map(folder => (
<div className={`p-3 rounded-sm flex items-center justify-center shrink-0 ${ <button
doc.type === 'word' ? 'bg-blue-500/10 text-blue-400' : key={folder}
doc.type === 'excel' ? 'bg-emerald-500/10 text-emerald-400' : onClick={() => setActiveFolder(folder)}
doc.type === 'pdf' ? 'bg-red-500/10 text-red-400' : className={`w-full flex items-center justify-between px-4 py-3 rounded-sm text-sm font-bold transition-all border ${activeFolder === folder ? 'bg-primary/5 text-primary border-primary/20 shadow-lg shadow-primary/5' : 'text-muted-foreground hover:bg-white/5 hover:text-foreground border-transparent'}`}
'bg-white/10 text-foreground' >
}`}> <div className="flex items-center gap-3">
{doc.type === 'word' ? <FileText className="h-6 w-6" /> : <Folder className={`h-4 w-4 ${activeFolder === folder ? 'text-primary' : 'text-muted-foreground'}`} />
doc.type === 'excel' ? <FileSpreadsheet className="h-6 w-6" /> : {folder}
<FileIcon className="h-6 w-6" />} </div>
{folder === "Starred" && <Star className="h-3 w-3 fill-primary text-primary" />}
</button>
))}
</div>
<div className="space-y-5">
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground px-4">Storage Usage</h3>
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-5 space-y-4 shadow-xl">
<div className="flex justify-between items-end mb-2">
<span className="text-[10px] font-black text-foreground uppercase tracking-widest">2.4 GB / 10 GB</span>
<span className="text-[10px] font-black text-primary uppercase tracking-widest">24%</span>
</div> </div>
<div className="min-w-0"> <div className="h-1.5 w-full bg-white/5 rounded-full overflow-hidden flex">
<h3 className="text-sm font-semibold truncate hover:text-primary cursor-pointer transition-colors mb-1">{doc.name}</h3> {storageStats.map(stat => (
<div className="flex items-center gap-3 text-xs text-muted-foreground"> <div key={stat.label} className={`h-full ${stat.color}`} style={{ width: `${stat.percentage}%` }} />
<span>{doc.size}</span> ))}
<span className="w-1 h-1 rounded-full bg-white/20"></span> </div>
<span>{doc.updated}</span> <div className="grid grid-cols-1 gap-3 pt-2">
{storageStats.map(stat => (
<div key={stat.label} className="flex justify-between items-center text-[9px] font-bold uppercase tracking-widest">
<div className="flex items-center gap-2">
<div className={`w-1.5 h-1.5 rounded-full ${stat.color}`} />
<span className="text-muted-foreground">{stat.label}</span>
</div>
<span>{stat.size}</span>
</div>
))}
</div>
<button className="w-full bg-white/5 hover:bg-white/10 text-[9px] font-black uppercase tracking-widest py-2 rounded-sm border border-white/5 transition-all mt-2">
UPGRADE STORAGE
</button>
</div>
</div>
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 space-y-4 relative overflow-hidden group shadow-2xl">
<div className="absolute -right-4 -top-4 opacity-5 rotate-12 transition-transform group-hover:scale-110">
<Brain className="h-20 w-20 text-primary" />
</div>
<div className="flex items-center gap-2">
<Brain className="h-4 w-4 text-primary" />
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">AI Librarian</h3>
</div>
<p className="text-[11px] font-bold text-foreground/80 leading-relaxed italic">
"Your 'Legal' folder is 80% redundant. Should I suggest an automated cleanup strategy?"
</p>
</div>
</div>
{/* Main Content Area */}
<div className="flex-1 flex flex-col gap-6 overflow-hidden">
<div className="flex items-center justify-between shrink-0">
<div className="flex items-center gap-6">
<div className="flex items-center gap-2 bg-[#150F1D] border border-white/5 rounded-sm p-0.5 shadow-inner">
<button onClick={() => setViewMode("grid")} className={`px-4 py-2 text-[10px] font-black uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'grid' ? 'bg-[#2B2538] text-foreground shadow-lg' : 'text-muted-foreground hover:text-foreground'}`}><Layout className="h-3.5 w-3.5" /> Grid</button>
<button onClick={() => setViewMode("list")} className={`px-4 py-2 text-[10px] font-black uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'list' ? 'bg-[#2B2538] text-foreground shadow-lg' : 'text-muted-foreground hover:text-foreground'}`}><List className="h-3.5 w-3.5" /> List</button>
</div>
<div className="h-6 w-px bg-white/5" />
<div className="flex items-center gap-4">
{["All", "PDF", "Design", "Media"].map(f => (
<button key={f} className="text-[10px] font-black uppercase tracking-widest text-muted-foreground hover:text-primary transition-colors">{f}</button>
))}
</div>
</div>
<button className="p-2.5 bg-[#150F1D] border border-white/5 rounded-sm text-muted-foreground hover:text-foreground transition-all">
<Filter className="h-4 w-4" />
</button>
</div>
<div className="flex-1 overflow-y-auto tiny-scrollbar pr-1">
{viewMode === "grid" ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8 pb-8">
{documents.map((doc) => (
<motion.div
key={doc.id}
whileHover={{ y: -6, scale: 1.02 }}
onClick={() => setSelectedDoc(doc)}
className="bg-[#0A0710] border border-white/5 rounded-sm p-6 flex flex-col group relative overflow-hidden shadow-2xl transition-all hover:border-primary/40 cursor-pointer"
>
<div className="absolute top-3 right-3 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-all">
<button className="p-1.5 hover:bg-white/10 rounded-sm transition-colors text-muted-foreground"><Star className={`h-3.5 w-3.5 ${doc.starred ? 'fill-primary text-primary' : ''}`} /></button>
<button className="p-1.5 hover:bg-white/10 rounded-sm transition-colors text-muted-foreground"><MoreHorizontal className="h-3.5 w-3.5" /></button>
</div>
<div className="aspect-[4/3] bg-[#150F1D] border border-white/5 rounded-sm mb-6 flex items-center justify-center relative overflow-hidden group/thumb shadow-inner">
<DocIcon type={doc.type} />
<div className="absolute inset-0 bg-primary/5 opacity-0 group-hover/thumb:opacity-100 transition-opacity" />
</div>
<div className="space-y-1.5">
<div className="text-[13px] font-black truncate group-hover:text-primary transition-colors tracking-tight">{doc.name}</div>
<div className="flex items-center justify-between text-[9px] text-muted-foreground font-black uppercase tracking-[0.2em]">
<span className="flex items-center gap-1.5">
<div className="w-1 h-1 rounded-full bg-white/20" />
{doc.type} {doc.size}
</span>
<span>{doc.date.split(',')[0]}</span>
</div>
</div>
</motion.div>
))}
</div>
) : (
<div className="bg-[#0A0710] border border-white/5 rounded-sm overflow-hidden shadow-2xl mb-8">
<div className="grid grid-cols-12 gap-4 p-5 border-b border-white/5 bg-[#0F0B15]/50 text-[9px] font-black uppercase tracking-[0.3em] text-muted-foreground">
<div className="col-span-6 px-2">Document Name</div>
<div className="col-span-2">File Weight</div>
<div className="col-span-2">Ownership</div>
<div className="col-span-2 text-right">Strategic Date</div>
</div>
<div className="divide-y divide-white/5">
{documents.map(doc => (
<div key={doc.id} onClick={() => setSelectedDoc(doc)} className="grid grid-cols-12 gap-4 p-6 items-center hover:bg-white/[0.02] transition-all group cursor-pointer border-l-2 border-transparent hover:border-primary">
<div className="col-span-6 flex items-center gap-5">
<DocIcon type={doc.type} small />
<div className="min-w-0">
<div className="text-[13px] font-black group-hover:text-primary transition-colors truncate tracking-tight">{doc.name}</div>
<div className="flex items-center gap-3 mt-1">
<span className="text-[9px] text-muted-foreground uppercase font-black tracking-[0.2em]">{doc.category}</span>
{doc.starred && <Star className="h-2.5 w-2.5 fill-primary text-primary" />}
</div>
</div>
</div>
<div className="col-span-2 text-[11px] text-muted-foreground font-black uppercase tracking-tighter">{doc.size}</div>
<div className="col-span-2 text-[11px] text-muted-foreground font-black uppercase tracking-widest">{doc.owner}</div>
<div className="col-span-2 text-right text-[11px] text-muted-foreground font-black uppercase tracking-tighter">{doc.date.split(',')[0]}</div>
</div>
))}
</div> </div>
</div> </div>
</div> )}
{/* AI Insight */}
<div className="flex-1 flex flex-col bg-[#150F1D]/50 border border-white/5 p-3 rounded-sm relative overflow-hidden">
<div className="absolute left-0 top-0 bottom-0 w-0.5 bg-primary/50"></div>
<div className="flex items-center gap-2 mb-1.5">
<Brain className="h-3 w-3 text-primary" />
<span className={`text-[10px] font-bold uppercase tracking-wider ${
doc.aiStatus === 'Action Required' ? 'text-red-400' :
doc.aiStatus === 'Analyzing' ? 'text-orange-400 animate-pulse' :
'text-primary'
}`}>{doc.aiStatus}</span>
</div>
<p className="text-[11px] text-muted-foreground leading-snug">
{doc.aiSummary}
</p>
</div>
{/* Actions */}
<div className="flex items-center gap-2">
<button className="bg-primary/10 hover:bg-primary/20 text-primary border border-primary/20 px-3 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors">
<MessageSquare className="h-3.5 w-3.5" />
Chat
</button>
<button className="p-2 hover:bg-white/5 rounded-sm text-muted-foreground transition-colors">
<Download className="h-4 w-4" />
</button>
<button className="p-2 hover:bg-white/5 rounded-sm text-muted-foreground transition-colors">
<MoreHorizontal className="h-4 w-4" />
</button>
</div>
</div> </div>
))} </div>
</div> </div>
{/* Document Detail Sheet */}
<AnimatePresence>
{selectedDoc && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedDoc(null)} className="fixed inset-0 bg-black/90 backdrop-blur-xl z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-xl bg-[#0A0710] border-l border-white/10 z-[101] shadow-2xl flex flex-col">
<div className="p-10 border-b border-white/5 flex items-center justify-between bg-primary/10 relative overflow-hidden">
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_30%_-20%,rgba(108,91,176,0.15),transparent)] pointer-events-none" />
<div className="flex items-center gap-6 relative z-10">
<div className="p-4 bg-[#150F1D] border border-white/10 rounded-sm shadow-xl">
<DocIcon type={selectedDoc.type} />
</div>
<div>
<h2 className="text-2xl font-black tracking-tighter text-foreground truncate max-w-sm uppercase">{selectedDoc.name}</h2>
<div className="flex items-center gap-4 mt-2">
<span className="text-[10px] font-black uppercase tracking-[0.2em] bg-primary/20 text-primary px-3 py-1 rounded-sm border border-primary/20 shadow-sm">{selectedDoc.type}</span>
<span className="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em]">{selectedDoc.size}</span>
{selectedDoc.starred && <Star className="h-3.5 w-3.5 fill-primary text-primary" />}
</div>
</div>
</div>
<button onClick={() => setSelectedDoc(null)} className="p-2.5 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors relative z-10"><X className="h-8 w-8" /></button>
</div>
<div className="flex-1 overflow-y-auto p-10 space-y-12 tiny-scrollbar relative">
{/* AI Summary Section */}
<div className="rounded-sm border border-primary/30 bg-primary/5 p-8 space-y-5 relative overflow-hidden shadow-2xl">
<div className="absolute -right-6 -top-6 opacity-10 rotate-12">
<Brain className="h-24 w-24 text-primary" />
</div>
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-primary flex items-center gap-2">
<Brain className="h-4 w-4" /> Strategic Content Intelligence
</h3>
<div className="space-y-4">
<p className="text-sm font-bold text-foreground/90 leading-[1.6] italic tracking-tight">
"{selectedDoc.summary}"
</p>
{selectedDoc.aiAnalysis && (
<div className="pt-5 border-t border-primary/20 mt-5">
<div className="text-[10px] font-black text-primary uppercase tracking-[0.3em] mb-3 flex items-center gap-2">
<Zap className="h-3.5 w-3.5" /> High-Level Insight
</div>
<p className="text-[11px] text-muted-foreground leading-relaxed font-medium uppercase tracking-wider">{selectedDoc.aiAnalysis}</p>
</div>
)}
</div>
</div>
{/* Metadata & Actions */}
<div className="grid grid-cols-2 gap-12">
<div className="space-y-5">
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-primary">File Properties</h3>
<div className="space-y-5">
<MetaItem label="AUTHOR" value={selectedDoc.owner} />
<MetaItem label="TIMELINE" value={selectedDoc.date} />
<MetaItem label="CLASSIF." value={selectedDoc.category} />
</div>
</div>
<div className="space-y-5">
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-primary">Strategic Tags</h3>
<div className="flex flex-wrap gap-2.5">
{selectedDoc.tags?.map((tag: string) => (
<span key={tag} className="text-[9px] font-black uppercase tracking-[0.2em] px-3 py-1.5 rounded-sm bg-white/5 border border-white/10 text-muted-foreground hover:border-primary hover:text-primary transition-all cursor-pointer">
{tag}
</span>
))}
<button className="text-[9px] font-black uppercase tracking-[0.2em] px-3 py-1.5 rounded-sm border border-dashed border-white/20 text-muted-foreground hover:border-white/40 transition-colors">
+ NEW TAG
</button>
</div>
</div>
</div>
{/* Connected Ecosystem */}
<div className="space-y-6">
<div className="flex justify-between items-center">
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-primary">Strategic Ecosystem</h3>
<span className="text-[9px] font-black text-muted-foreground uppercase tracking-widest">Linked by AI</span>
</div>
<div className="space-y-4">
<div className="p-5 rounded-sm bg-[#150F1D] border border-white/5 flex items-center justify-between group cursor-pointer hover:border-primary/40 transition-all shadow-xl">
<div className="flex items-center gap-4">
<div className="p-3 bg-primary/10 rounded-sm shadow-inner"><Globe className="h-5 w-5 text-primary" /></div>
<div>
<div className="text-[11px] font-black uppercase tracking-widest text-foreground">Project: Q3 Expansion</div>
<div className="text-[9px] text-muted-foreground uppercase mt-1 font-bold">Referenced in Section 4.2</div>
</div>
</div>
<ExternalLink className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" />
</div>
<div className="p-5 rounded-sm bg-[#150F1D] border border-white/5 flex items-center justify-between group cursor-pointer hover:border-primary/40 transition-all shadow-xl">
<div className="flex items-center gap-4">
<div className="p-3 bg-emerald-500/10 rounded-sm shadow-inner"><Activity className="h-5 w-5 text-emerald-500" /></div>
<div>
<div className="text-[11px] font-black uppercase tracking-widest text-foreground">Goal: Market Dominance</div>
<div className="text-[9px] text-muted-foreground uppercase mt-1 font-bold">Foundational Resource</div>
</div>
</div>
<ExternalLink className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" />
</div>
</div>
</div>
</div>
<div className="p-10 border-t border-white/10 bg-[#0F0B15]/60 flex gap-6">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-5 rounded-sm text-[11px] font-black uppercase tracking-[0.3em] shadow-2xl shadow-primary/40 transition-all active:scale-[0.98] flex items-center justify-center gap-3">
<Download className="h-5 w-5" /> DOWNLOAD FILE
</button>
<button className="p-5 border border-white/10 rounded-sm text-muted-foreground hover:bg-white/10 transition-all shadow-xl">
<Share2 className="h-6 w-6" />
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}
function DocIcon({ type, small = false }: { type: string, small?: boolean }) {
const sizeClass = small ? "h-6 w-6" : "h-14 w-14";
if (["PDF", "XLSX"].includes(type)) return <FileText className={`${sizeClass} text-rose-500`} />;
if (["FIG"].includes(type)) return <File className={`${sizeClass} text-purple-500`} />;
if (["MP4"].includes(type)) return <Video className={`${sizeClass} text-blue-500`} />;
if (["ZIP"].includes(type)) return <File className={`${sizeClass} text-orange-500`} />;
return <File className={`${sizeClass} text-muted-foreground`} />;
}
function MetaItem({ label, value }: { label: string, value: string }) {
return (
<div className="flex items-center justify-between border-b border-white/5 pb-3">
<span className="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em]">{label}</span>
<span className="text-[11px] font-black text-foreground uppercase tracking-tight">{value}</span>
</div> </div>
); );
} }
+341 -192
View File
@@ -1,255 +1,404 @@
"use client"; "use client";
import { Search, Filter, Brain, ArrowUpRight, ArrowDownRight, DollarSign, Activity, PieChart, Download, Wallet, Plus } from "lucide-react"; import { useState, useMemo } from "react";
import { import {
Bar, Plus, Search, TrendingUp, TrendingDown, DollarSign,
BarChart, CreditCard, ArrowUpRight, ArrowDownRight, MoreHorizontal,
CartesianGrid, Calendar, FileText, Download, PieChart as PieChartIcon,
ResponsiveContainer, Wallet, Brain, ArrowRight, X, Check, Activity,
Tooltip, Briefcase, Landmark, Receipt, Percent, Target
XAxis, } from "lucide-react";
YAxis, import {
Area, Area, AreaChart, Bar, BarChart, CartesianGrid,
AreaChart, ResponsiveContainer, Tooltip, XAxis, YAxis, Cell,
Pie, Pie, PieChart
PieChart as RechartsPieChart,
Cell
} from "recharts"; } from "recharts";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const cashFlowData = [ const cashflowData = [
{ month: "Jan", in: 45000, out: 28000 }, { month: "Jan", income: 12500, expense: 8400, predicted: 13000 },
{ month: "Feb", in: 52000, out: 31000 }, { month: "Feb", income: 14200, expense: 9100, predicted: 14500 },
{ month: "Mar", in: 48000, out: 29000 }, { month: "Mar", income: 13800, expense: 8800, predicted: 14000 },
{ month: "Apr", in: 61000, out: 34000 }, { month: "Apr", income: 15600, expense: 10200, predicted: 16000 },
{ month: "May", in: 59000, out: 42000 }, { month: "May", income: 18400, expense: 11500, predicted: 19500 },
{ month: "Jun", in: 75000, out: 38000 }, { month: "Jun", income: 21000, expense: 12000, predicted: 22000 },
]; ];
const expensesData = [ const expensesByCategory = [
{ name: "Payroll", value: 45000, color: "#6C5BB0" }, { name: "Software", value: 3400, color: "#6C5BB0" },
{ name: "Software/SaaS", value: 12000, color: "#54468B" }, { name: "Rent", value: 2500, color: "#a798e8" },
{ name: "Marketing", value: 18000, color: "#3B3161" }, { name: "Marketing", value: 1800, color: "#10b981" },
{ name: "Office/Rent", value: 8000, color: "#221C38" }, { name: "Taxes", value: 4200, color: "#3b82f6" },
{ name: "Travel", value: 1200, color: "#f59e0b" },
]; ];
const recentTransactions = [ const transactions = [
{ id: 1, desc: "Stripe Payout", category: "Revenue", amount: "+$12,450.00", date: "Today", status: "Completed" }, { id: 1, name: "Stripe Subscription", date: "May 15", amount: "+$4,200", status: "Success", type: "Income", category: "Direct Sales", project: "Cognis Mobile" },
{ id: 2, desc: "Amazon Web Services", category: "Software", amount: "-$3,240.50", date: "Yesterday", status: "Completed" }, { id: 2, name: "Amazon Web Services", date: "May 12", amount: "-$840", status: "Pending", type: "Expense", category: "Cloud Infra", project: "Infrastructure" },
{ id: 3, desc: "Google Ads", category: "Marketing", amount: "-$4,500.00", date: "May 15", status: "Pending" }, { id: 3, name: "Office Rent Q3", date: "May 10", amount: "-$2,500", status: "Success", type: "Expense", category: "Overhead", project: "General" },
{ id: 4, desc: "WeWork Remote", category: "Office", amount: "-$1,200.00", date: "May 12", status: "Completed" }, { id: 4, name: "Client: Marketing Site", date: "May 08", amount: "+$2,800", status: "Success", type: "Income", category: "Freelance", project: "Marketing Site" },
{ id: 5, name: "GitHub Enterprise", date: "May 05", amount: "-$120", status: "Success", type: "Expense", category: "Software", project: "Infrastructure" },
]; ];
export default function FinancePage() { export default function FinancePage() {
const [showInvoiceModal, setShowInvoiceModal] = useState(false);
const [selectedTransaction, setSelectedTransaction] = useState<any>(null);
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<h1 className="text-lg font-medium text-muted-foreground"> <div className="flex items-center gap-4">
<span className="text-foreground">Management</span> / Finance <h1 className="text-lg font-medium text-muted-foreground">
</h1> <span className="text-foreground">Business</span> / Financials
</h1>
<div className="h-4 w-px bg-white/10" />
<div className="flex items-center gap-2 text-[10px] font-bold uppercase tracking-widest text-emerald-500 bg-emerald-500/5 px-3 py-1 rounded-sm border border-emerald-500/10">
<Check className="h-3 w-3" /> ALL SYSTEMS HEALTHY
</div>
</div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<button className="bg-white/5 hover:bg-white/10 text-foreground border border-white/10 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <button
<Download className="h-4 w-4" /> onClick={() => setShowInvoiceModal(true)}
STATEMENT className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-5 py-2 rounded-sm text-xs font-black tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/30 active:scale-95"
</button> >
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <Receipt className="h-4 w-4" />
<Plus className="h-4 w-4" /> CREATE INVOICE
NEW INVOICE
</button> </button>
</div> </div>
</div> </div>
{/* AI Financial Analyst */}
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 flex flex-col md:flex-row items-start md:items-center justify-between gap-6">
<div className="flex items-start gap-4">
<div className="p-3 bg-primary/10 rounded-sm shrink-0">
<Brain className="h-6 w-6 text-primary" />
</div>
<div>
<h3 className="text-sm font-semibold text-primary mb-1 flex items-center gap-2">
AI Financial Analyst
</h3>
<p className="text-xs text-foreground/80 leading-relaxed max-w-3xl">
I detected an anomaly: <strong>Software/SaaS expenses</strong> increased by 22% compared to last month. Specifically, AWS costs spiked. AI recommends auditing idle EC2 instances to save approximately $850/mo.
</p>
</div>
</div>
<button className="bg-primary/20 text-primary hover:bg-primary/30 border border-primary/30 px-4 py-2 rounded-sm text-xs font-semibold transition-colors shrink-0">
Run Cloud Audit
</button>
</div>
{/* KPI Row */} {/* KPI Row */}
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 shrink-0">
<FinanceKpiCard label="Total Revenue" value="$42,850" change="+18%" trend="up" icon={DollarSign} />
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6"> <FinanceKpiCard label="Tax Provision" value="$8,400" change="+12%" trend="up" icon={Landmark} />
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4 flex items-center gap-2"> <FinanceKpiCard label="Operating Costs" value="$12,400" change="-5%" trend="down" icon={TrendingDown} />
<DollarSign className="h-3.5 w-3.5" /> Total Revenue (MTD) <FinanceKpiCard label="Projected Net" value="$30,450" change="+24%" trend="up" icon={Wallet} color="primary" />
</h3>
<div className="flex items-end gap-3 mb-1">
<span className="text-3xl font-bold text-foreground">$124,500</span>
<span className="text-xs text-emerald-500 flex items-center font-medium mb-1">
<ArrowUpRight className="h-3 w-3 mr-0.5" /> 8.4%
</span>
</div>
</div>
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6">
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4 flex items-center gap-2">
<Activity className="h-3.5 w-3.5" /> Monthly Burn Rate
</h3>
<div className="flex items-end gap-3 mb-1">
<span className="text-3xl font-bold text-foreground">$42,300</span>
<span className="text-xs text-red-500 flex items-center font-medium mb-1">
<ArrowUpRight className="h-3 w-3 mr-0.5" /> 2.1%
</span>
</div>
</div>
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6">
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4 flex items-center gap-2">
<Wallet className="h-3.5 w-3.5" /> Cash Runway
</h3>
<div className="flex items-end gap-3 mb-1">
<span className="text-3xl font-bold text-foreground">14.2</span>
<span className="text-xs text-muted-foreground flex items-center font-medium mb-1">
Months
</span>
</div>
</div>
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6">
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-4 flex items-center gap-2">
<Brain className="h-3.5 w-3.5 text-primary" /> AI Profitability Score
</h3>
<div className="flex items-end gap-3 mb-1">
<span className="text-3xl font-bold text-primary">94/100</span>
<span className="text-xs text-emerald-500 flex items-center font-medium mb-1">
Optimal
</span>
</div>
</div>
</div> </div>
{/* Charts & Tables */} {/* Main Analysis Area */}
<div className="grid grid-cols-1 xl:grid-cols-3 gap-6 flex-1 min-h-[400px]"> <div className="grid grid-cols-1 xl:grid-cols-3 gap-6 flex-1 min-h-[400px]">
{/* Cash Flow Chart */} {/* Cashflow Chart */}
<div className="xl:col-span-2 rounded-sm border border-white/5 bg-[#0A0710] p-6 flex flex-col"> <div className="xl:col-span-2 bg-[#0A0710] border border-white/5 rounded-sm p-8 flex flex-col relative overflow-hidden group shadow-2xl">
<div className="flex justify-between items-start mb-6"> <div className="absolute top-0 right-0 p-8 opacity-5 group-hover:opacity-10 transition-opacity">
<TrendingUp className="h-48 w-48 text-primary" />
</div>
<div className="flex justify-between items-start mb-10 relative z-10">
<div> <div>
<h3 className="text-sm font-semibold mb-1">Cash Flow Overview</h3> <h3 className="text-xl font-black mb-1 flex items-center gap-3">
<p className="text-xs text-muted-foreground">Revenue vs Expenses over the last 6 months.</p> Intelligent Cashflow
<span className="text-[10px] font-black bg-primary/20 text-primary px-3 py-1 rounded-sm uppercase tracking-[0.2em] animate-pulse">AI Forecasting</span>
</h3>
<p className="text-sm text-muted-foreground max-w-md">Real-time revenue monitoring compared with deep-learning projections for the next quarter.</p>
</div> </div>
<div className="flex gap-4 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground"> <div className="flex gap-6 text-[10px] font-black uppercase tracking-widest text-muted-foreground">
<div className="flex items-center gap-2"><div className="w-2 h-2 rounded-sm bg-emerald-500"></div> Inflow</div> <div className="flex items-center gap-2"><div className="w-2 h-2 rounded-full bg-primary" /> Income</div>
<div className="flex items-center gap-2"><div className="w-2 h-2 rounded-sm bg-red-500"></div> Outflow</div> <div className="flex items-center gap-2"><div className="w-2 h-2 rounded-full bg-rose-500" /> Expense</div>
<div className="flex items-center gap-2"><div className="w-2 h-2 rounded-full border-2 border-dashed border-primary" /> Forecast</div>
</div> </div>
</div> </div>
<div className="flex-1 w-full min-h-[250px]"> <div className="flex-1 w-full min-h-[300px]">
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
<BarChart data={cashFlowData}> <AreaChart data={cashflowData}>
<defs>
<linearGradient id="colorIncome" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#6C5BB0" stopOpacity={0.4}/>
<stop offset="95%" stopColor="#6C5BB0" stopOpacity={0}/>
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#ffffff05" /> <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#ffffff05" />
<XAxis dataKey="month" axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5' }} dy={10} /> <XAxis dataKey="month" axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5', fontWeight: 600 }} dy={10} />
<YAxis axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5' }} dx={-10} tickFormatter={(val) => `$${val/1000}k`} /> <YAxis axisLine={false} tickLine={false} tick={{ fontSize: 11, fill: '#8F89A5', fontWeight: 600 }} dx={-10} />
<Tooltip <Tooltip
cursor={{ fill: '#ffffff05' }} cursor={{ stroke: '#6C5BB0', strokeWidth: 1 }}
contentStyle={{ backgroundColor: "#1F172B", border: "none", fontSize: "12px", color: "#FBF9FE", borderRadius: "4px" }} contentStyle={{ backgroundColor: "#150F1D", border: "1px solid rgba(255,255,255,0.05)", borderRadius: "4px", fontSize: "12px" }}
itemStyle={{ color: "#FBF9FE" }}
/> />
<Bar dataKey="in" fill="#10b981" radius={[2, 2, 0, 0]} barSize={16} /> <Area type="monotone" dataKey="income" stroke="#6C5BB0" strokeWidth={4} fillOpacity={1} fill="url(#colorIncome)" />
<Bar dataKey="out" fill="#ef4444" radius={[2, 2, 0, 0]} barSize={16} /> <Area type="monotone" dataKey="expense" stroke="#f43f5e" strokeWidth={2} fill="transparent" strokeDasharray="4 4" />
</BarChart> <Area type="monotone" dataKey="predicted" stroke="#6C5BB0" strokeWidth={1} fill="transparent" strokeDasharray="10 10" opacity={0.5} />
</AreaChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>
</div> </div>
{/* Expenses Pie & Recent Transactions */} {/* Expense Breakdown & AI Insights */}
<div className="flex flex-col gap-6"> <div className="flex flex-col gap-6">
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex flex-col shadow-2xl">
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-6 flex-1 flex flex-col"> <h3 className="text-[11px] font-black uppercase tracking-[0.2em] text-muted-foreground mb-8">Category Allocation</h3>
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2">Expenses Breakdown</h3> <div className="flex-1 w-full min-h-[180px] flex items-center justify-center">
<div className="flex-1 w-full flex items-center justify-center relative min-h-[160px]">
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
<RechartsPieChart> <PieChart>
<Pie <Pie
data={expensesData} data={expensesByCategory}
cx="50%" cx="50%"
cy="50%" cy="50%"
innerRadius={50} innerRadius={55}
outerRadius={70} outerRadius={80}
paddingAngle={2} paddingAngle={4}
dataKey="value" dataKey="value"
stroke="none" stroke="none"
> >
{expensesData.map((entry, index) => ( {expensesByCategory.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} /> <Cell key={index} fill={entry.color} />
))} ))}
</Pie> </Pie>
<Tooltip contentStyle={{ backgroundColor: "#1F172B", border: "none", fontSize: "12px" }} /> <Tooltip contentStyle={{ backgroundColor: "#150F1D", border: "none" }} />
</RechartsPieChart> </PieChart>
</ResponsiveContainer> </ResponsiveContainer>
<div className="absolute inset-0 flex items-center justify-center pointer-events-none flex-col">
<span className="text-[10px] text-muted-foreground uppercase font-bold tracking-widest">Total</span>
<span className="text-sm font-bold">$83k</span>
</div>
</div> </div>
<div className="space-y-2 mt-4"> <div className="mt-8 space-y-3">
{expensesData.map((item, idx) => ( {expensesByCategory.slice(0, 3).map(ex => (
<div key={idx} className="flex justify-between items-center text-xs"> <div key={ex.name} className="flex justify-between items-center text-[10px] font-black uppercase tracking-widest">
<div className="flex items-center gap-2"> <div className="flex items-center gap-3">
<div className="w-2 h-2 rounded-sm" style={{ backgroundColor: item.color }}></div> <div className="w-2 h-2 rounded-full" style={{ backgroundColor: ex.color }} />
<span className="text-muted-foreground">{item.name}</span> <span className="text-muted-foreground">{ex.name}</span>
</div> </div>
<span className="font-semibold">${(item.value / 1000).toFixed(1)}k</span> <span>${ex.value.toLocaleString()}</span>
</div> </div>
))} ))}
</div> </div>
</div> </div>
</div> <div className="bg-primary/5 border border-primary/20 rounded-sm p-8 flex-1 flex flex-col justify-between relative overflow-hidden group">
<div className="absolute -right-4 -top-4 opacity-5 rotate-12 transition-transform group-hover:scale-110">
</div> <Brain className="h-24 w-24 text-primary" />
{/* AI Categorized Transactions */}
<div className="bg-[#0A0710] rounded-sm border border-white/5 overflow-hidden">
<div className="p-4 border-b border-white/5 flex justify-between items-center">
<h3 className="text-sm font-semibold">Recent Transactions</h3>
<span className="text-[10px] font-bold uppercase tracking-wider text-primary flex items-center gap-1"><Brain className="h-3 w-3" /> Auto-Categorized by AI</span>
</div>
<div className="grid grid-cols-12 gap-4 p-4 border-b border-white/5 bg-[#0F0B15]/50 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
<div className="col-span-5">Description</div>
<div className="col-span-2">Category</div>
<div className="col-span-2">Date</div>
<div className="col-span-2">Amount</div>
<div className="col-span-1 text-right">Status</div>
</div>
<div className="divide-y divide-white/5">
{recentTransactions.map((tx) => (
<div key={tx.id} className="grid grid-cols-12 gap-4 p-4 items-center hover:bg-white/[0.02] transition-colors">
<div className="col-span-5 text-sm font-medium">{tx.desc}</div>
<div className="col-span-2 text-xs text-muted-foreground">{tx.category}</div>
<div className="col-span-2 text-xs text-muted-foreground">{tx.date}</div>
<div className={`col-span-2 text-sm font-bold ${tx.amount.startsWith('+') ? 'text-emerald-400' : 'text-foreground'}`}>
{tx.amount}
</div>
<div className="col-span-1 text-right">
<span className={`text-[10px] uppercase font-bold px-2 py-1 rounded-sm border inline-block ${
tx.status === 'Completed' ? 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20' :
'bg-orange-500/10 text-orange-400 border-orange-500/20'
}`}>
{tx.status}
</span>
</div>
</div> </div>
))} <div className="space-y-4">
<div className="flex items-center gap-3">
<div className="p-2 bg-primary/20 rounded-sm">
<Percent className="h-4 w-4 text-primary" />
</div>
<h3 className="text-[11px] font-black uppercase tracking-[0.2em] text-primary">Strategic Advantage</h3>
</div>
<p className="text-sm font-bold leading-relaxed text-foreground/90 italic">
"Your project-specific ROI is 18% higher when tasks are completed in the morning focus block. Strategic reinvestment of $5k suggested for Q4."
</p>
</div>
<button className="text-[10px] font-black text-primary uppercase tracking-[0.2em] flex items-center gap-2 group/btn border-b border-primary/20 pb-1 self-start hover:border-primary transition-all">
OPTIMIZE SPENDING <ArrowRight className="h-3 w-3 group-hover/btn:translate-x-1 transition-transform" />
</button>
</div>
</div> </div>
</div> </div>
{/* Transactions Ledger */}
<div className="bg-[#0A0710] border border-white/5 rounded-sm overflow-hidden flex flex-col h-[450px] shadow-2xl">
<div className="flex justify-between items-center p-8 border-b border-white/5 bg-[#0F0B15]/40 backdrop-blur-sm">
<div>
<h3 className="text-xs font-black uppercase tracking-[0.3em] text-muted-foreground">Strategic Ledger</h3>
<p className="text-[10px] text-muted-foreground mt-1 uppercase font-bold tracking-widest">Showing last 24 transactions across 5 projects</p>
</div>
<div className="flex items-center gap-4">
<div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2">
<Filter className="h-3 w-3 text-muted-foreground" />
<span className="text-[10px] font-bold text-muted-foreground">FILTER</span>
</div>
<button className="text-[10px] font-black text-primary uppercase tracking-[0.2em] bg-primary/10 px-4 py-2 rounded-sm hover:bg-primary/20 transition-all">Full Report</button>
</div>
</div>
<div className="flex-1 overflow-y-auto tiny-scrollbar">
<div className="divide-y divide-white/5">
{transactions.map(t => (
<div key={t.id} onClick={() => setSelectedTransaction(t)} className="grid grid-cols-12 gap-4 p-6 items-center hover:bg-white/[0.02] transition-all group cursor-pointer border-l-2 border-transparent hover:border-primary">
<div className="col-span-1 flex justify-center">
<div className={`p-3 rounded-sm ${t.type === 'Income' ? 'bg-emerald-500/10 text-emerald-500 shadow-[0_0_10px_rgba(16,185,129,0.1)]' : 'bg-rose-500/10 text-rose-500 shadow-[0_0_10px_rgba(244,63,94,0.1)]'}`}>
{t.type === 'Income' ? <ArrowUpRight className="h-5 w-5" /> : <ArrowDownRight className="h-5 w-5" />}
</div>
</div>
<div className="col-span-5">
<div className="text-sm font-black group-hover:text-primary transition-colors">{t.name}</div>
<div className="flex items-center gap-3 mt-1">
<span className="text-[10px] text-muted-foreground uppercase font-black tracking-widest">{t.category}</span>
<span className="text-[10px] text-primary font-bold bg-primary/5 px-2 py-0.5 rounded-sm">{t.project}</span>
</div>
</div>
<div className="col-span-2 text-xs text-muted-foreground font-black uppercase tracking-tighter">{t.date}</div>
<div className="col-span-2">
<span className={`text-sm font-black tracking-tighter ${t.type === 'Income' ? 'text-emerald-400' : 'text-rose-400'}`}>
{t.amount}
</span>
</div>
<div className="col-span-2 flex justify-end gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><MoreHorizontal className="h-4 w-4" /></button>
</div>
</div>
))}
</div>
</div>
</div>
{/* Invoice Editor Modal */}
<AnimatePresence>
{showInvoiceModal && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setShowInvoiceModal(false)} className="fixed inset-0 bg-black/90 backdrop-blur-xl z-[100]" />
<motion.div initial={{ scale: 0.9, opacity: 0, y: 20 }} animate={{ scale: 1, opacity: 1, y: 0 }} exit={{ scale: 0.9, opacity: 0, y: 20 }} className="fixed inset-0 m-auto w-full max-w-3xl h-fit max-h-[90vh] bg-[#0A0710] border border-white/10 z-[101] shadow-2xl flex flex-col rounded-sm overflow-hidden">
<div className="p-10 border-b border-white/5 flex items-center justify-between bg-primary/10 relative overflow-hidden">
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_30%_-20%,rgba(108,91,176,0.15),transparent)] pointer-events-none" />
<div className="flex items-center gap-4 relative z-10">
<div className="p-3 bg-primary rounded-sm shadow-xl shadow-primary/20"><Receipt className="h-6 w-6 text-primary-foreground" /></div>
<div>
<h2 className="text-2xl font-black uppercase tracking-tighter">Strategic Invoice</h2>
<p className="text-[10px] font-black text-primary tracking-[0.3em] uppercase">AI-Optimized Billing Engine</p>
</div>
</div>
<button onClick={() => setShowInvoiceModal(false)} className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors relative z-10"><X className="h-7 w-7" /></button>
</div>
<div className="p-10 space-y-8 overflow-y-auto tiny-scrollbar">
<div className="grid grid-cols-2 gap-8">
<div className="space-y-2">
<label className="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em]">Select Client</label>
<div className="relative">
<input type="text" placeholder="Start typing client name..." className="w-full bg-[#150F1D] border border-white/10 rounded-sm px-5 py-4 text-sm font-bold outline-none focus:border-primary/50 transition-all" />
<Search className="absolute right-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
</div>
</div>
<div className="space-y-2">
<label className="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em]">Project Association</label>
<select className="w-full bg-[#150F1D] border border-white/10 rounded-sm px-5 py-4 text-sm font-bold outline-none focus:border-primary/50 transition-all appearance-none">
<option className="bg-[#0A0710]">Marketing Site Redesign</option>
<option className="bg-[#0A0710]">Infrastructure Scale</option>
<option className="bg-[#0A0710]">Cognis Mobile Dev</option>
</select>
</div>
</div>
<div className="space-y-6 pt-4">
<div className="flex justify-between items-center">
<h3 className="text-[11px] font-black uppercase tracking-[0.3em] text-primary">Billable Items</h3>
<button className="text-[10px] font-black text-muted-foreground hover:text-primary transition-colors flex items-center gap-2">
<Plus className="h-3 w-3" /> ADD CUSTOM LINE
</button>
</div>
<div className="space-y-3">
<InvoiceLineItem title="Phase 1: Design Strategy" rate="$120/hr" hours="24h" total="$2,880" />
<InvoiceLineItem title="Phase 2: Core Development" rate="$150/hr" hours="12h" total="$1,800" />
<div className="p-4 rounded-sm border border-dashed border-white/10 flex items-center justify-center text-[10px] font-bold text-muted-foreground hover:bg-white/5 transition-all cursor-pointer">
AI SUGGESTION: ADD "QA & TESTING" (8H)
</div>
</div>
</div>
<div className="pt-8 border-t border-white/10 flex flex-col items-end gap-3">
<div className="flex gap-16 text-sm">
<span className="text-muted-foreground font-black uppercase tracking-widest text-[10px] mt-1">Subtotal</span>
<span className="font-black text-lg">$4,680.00</span>
</div>
<div className="flex gap-16 text-sm">
<span className="text-muted-foreground font-black uppercase tracking-widest text-[10px] mt-1">Tax (18%)</span>
<span className="font-black text-lg">$842.40</span>
</div>
<div className="flex gap-16 text-2xl font-black mt-4 pt-4 border-t border-primary/20 w-full justify-end">
<span className="text-primary uppercase tracking-[0.4em] text-[10px] mt-3">Grand Total</span>
<span className="text-primary text-4xl tracking-tighter">$5,522.40</span>
</div>
</div>
</div>
<div className="p-10 border-t border-white/5 flex gap-6 bg-[#0F0B15]/60">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-5 rounded-sm text-[11px] font-black uppercase tracking-[0.3em] shadow-2xl shadow-primary/40 transition-all active:scale-[0.98] flex items-center justify-center gap-3">
<Download className="h-5 w-5" /> GENERATE & SEND
</button>
<button className="px-10 border border-white/10 rounded-sm text-[11px] font-black uppercase tracking-[0.2em] text-muted-foreground hover:bg-white/5 transition-all">
SAVE AS DRAFT
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
{/* Transaction Detail Sheet */}
<AnimatePresence>
{selectedTransaction && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedTransaction(null)} className="fixed inset-0 bg-black/80 backdrop-blur-md z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-lg bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col p-10 space-y-12">
<div className="flex justify-between items-start">
<div className={`p-4 rounded-sm ${selectedTransaction.type === 'Income' ? 'bg-emerald-500/10 text-emerald-500' : 'bg-rose-500/10 text-rose-500'}`}>
{selectedTransaction.type === 'Income' ? <ArrowUpRight className="h-8 w-8" /> : <ArrowDownRight className="h-8 w-8" />}
</div>
<button onClick={() => setSelectedTransaction(null)} className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><X className="h-7 w-7" /></button>
</div>
<div className="space-y-2">
<h2 className="text-3xl font-black tracking-tighter">{selectedTransaction.name}</h2>
<div className="flex items-center gap-4">
<span className={`text-xl font-black ${selectedTransaction.type === 'Income' ? 'text-emerald-400' : 'text-rose-400'}`}>{selectedTransaction.amount}</span>
<span className="text-[10px] font-black uppercase tracking-widest bg-white/5 px-2 py-1 rounded-sm text-muted-foreground border border-white/5">{selectedTransaction.status}</span>
</div>
</div>
<div className="space-y-6 pt-6 border-t border-white/5">
<DetailMeta label="TRANSACTION DATE" value={selectedTransaction.date} />
<DetailMeta label="STRATEGIC CATEGORY" value={selectedTransaction.category} />
<DetailMeta label="PROJECT LINK" value={selectedTransaction.project} isPrimary />
</div>
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 space-y-4">
<h3 className="text-[10px] font-black uppercase tracking-widest text-primary flex items-center gap-2">
<Brain className="h-3.5 w-3.5" /> Financial Insight
</h3>
<p className="text-xs text-muted-foreground leading-relaxed italic">
This {selectedTransaction.type.toLowerCase()} was processed via Stripe and linked to your **{selectedTransaction.project}** deliverables. Tax obligations have been pre-calculated.
</p>
</div>
<button className="w-full bg-white/5 hover:bg-white/10 border border-white/10 py-4 rounded-sm text-[10px] font-black uppercase tracking-[0.2em] transition-all flex items-center justify-center gap-3 mt-auto">
<Download className="h-4 w-4" /> DOWNLOAD RECEIPT
</button>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}
function InvoiceLineItem({ title, rate, hours, total }: any) {
return (
<div className="grid grid-cols-12 gap-4 p-5 rounded-sm bg-[#150F1D] border border-white/5 items-center group hover:border-primary/30 transition-all">
<div className="col-span-7 flex flex-col">
<span className="text-xs font-black group-hover:text-primary transition-colors uppercase tracking-widest">{title}</span>
<span className="text-[9px] text-muted-foreground font-bold uppercase tracking-widest mt-1">Strategic Development Block</span>
</div>
<div className="col-span-2 text-center text-xs font-black text-muted-foreground">{rate}</div>
<div className="col-span-1 text-center text-xs font-black text-muted-foreground">{hours}</div>
<div className="col-span-2 text-right text-sm font-black text-primary">{total}</div>
</div>
);
}
function DetailMeta({ label, value, isPrimary = false }: any) {
return (
<div className="flex justify-between items-center">
<span className="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em]">{label}</span>
<span className={`text-sm font-black ${isPrimary ? 'text-primary' : 'text-foreground'}`}>{value}</span>
</div>
);
}
function FinanceKpiCard({ label, value, change, trend, icon: Icon, color = "default" }: any) {
const isUp = trend === "up";
const trendColor = isUp ? "text-emerald-500" : "text-rose-500";
return (
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 group relative overflow-hidden shadow-2xl transition-all hover:border-white/10">
<div className={`absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity ${color === 'primary' ? 'text-primary' : 'text-foreground'}`}>
<Icon className="h-20 w-20" />
</div>
<div className="text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground mb-4">{label}</div>
<div className="flex items-baseline gap-3 relative z-10">
<span className="text-3xl font-black text-foreground tracking-tighter leading-none">{value}</span>
<div className={`flex items-center text-[10px] font-black px-2 py-0.5 rounded-sm bg-white/5 ${trendColor}`}>
{isUp ? <ArrowUpRight className="h-3.5 w-3.5 mr-0.5" /> : <ArrowDownRight className="h-3.5 w-3.5 mr-0.5" />} {change}
</div>
</div>
</div> </div>
); );
} }
+255 -126
View File
@@ -1,165 +1,294 @@
"use client"; "use client";
import { Plus, Brain, Target, Compass, Award, MoreHorizontal, CircleDashed, CheckCircle2 } from "lucide-react"; import { useState } from "react";
import {
Plus, Search, Target, Flag, TrendingUp, Zap,
CheckCircle2, Clock, Brain, MoreHorizontal, X,
ChevronRight, ArrowRight, BarChart3, Star,
Shield, Globe, Briefcase, Award
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const goals = [ const goals = [
{ {
id: 1, id: 1,
title: "Launch SaaS Product MVP", title: "100k Monthly Recurring Revenue",
category: "Career & Business", category: "Financial",
progress: 75, progress: 42,
dueDate: "Q3 2026", deadline: "Dec 2026",
status: "On Track", status: "Active",
color: "#6C5BB0", // Primary priority: "Critical",
milestones: [ milestones: [
{ name: "Finalize Designs", done: true }, { name: "Reach 50k MRR", status: "Done", date: "Aug 2026" },
{ name: "Backend Architecture", done: true }, { name: "Scale Sales Team", status: "In Progress", date: "Sep 2026" },
{ name: "Frontend Development", done: true }, { name: "Launch Enterprise Tier", status: "Upcoming", date: "Nov 2026" },
{ name: "Beta Testing", done: false }, ],
{ name: "Public Launch", done: false }, aiInsight: "Currently 12% ahead of target. Strategic focus should remain on enterprise lead generation."
]
}, },
{ {
id: 2, id: 2,
title: "Run a Half-Marathon", title: "Launch Cognis AI Mobile App",
category: "Health & Fitness", category: "Product",
progress: 40, progress: 85,
dueDate: "Oct 12, 2026", deadline: "May 25, 2026",
status: "Behind", status: "Active",
color: "#10b981", // Emerald priority: "High",
milestones: [ milestones: [
{ name: "Run 5K Without Stopping", done: true }, { name: "Beta Testing", status: "Done", date: "Apr 15" },
{ name: "Run 10K", done: true }, { name: "App Store Review", status: "In Progress", date: "May 10" },
{ name: "Maintain 15K weekly volume", done: false }, { name: "Global Launch", status: "Upcoming", date: "May 25" },
{ name: "Complete 18K long run", done: false }, ],
] aiInsight: "85% complete. Recommendation: Finalize push notification logic to ensure day-1 retention."
}, },
{ { id: 3, title: "Achieve Peak Physical Fitness", category: "Personal", progress: 60, deadline: "Ongoing", status: "Active", priority: "Medium", milestones: [], aiInsight: "" },
id: 3, { id: 4, title: "Acquire 500 Enterprise Leads", category: "Marketing", progress: 25, deadline: "Jun 2026", status: "Delayed", priority: "High", milestones: [], aiInsight: "" },
title: "Read 24 Books",
category: "Personal Growth",
progress: 50,
dueDate: "Dec 31, 2026",
status: "Ahead",
color: "#f97316", // Orange
milestones: [
{ name: "Read 6 Books (Q1)", done: true },
{ name: "Read 12 Books (Q2)", done: true },
{ name: "Read 18 Books (Q3)", done: false },
]
}
]; ];
export default function GoalsPage() { export default function GoalsPage() {
const [selectedGoal, setSelectedGoal] = useState<any>(null);
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<h1 className="text-lg font-medium text-muted-foreground"> <div className="flex items-center gap-4">
<span className="text-foreground">Personal</span> / Strategic Goals <h1 className="text-lg font-medium text-muted-foreground">
</h1> <span className="text-foreground">Vision</span> / Strategic Goals
</h1>
<div className="h-4 w-px bg-white/10" />
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-primary bg-primary/5 px-3 py-1 rounded-sm border border-primary/10">
<Target className="h-3 w-3" /> 4 ACTIVE OBJECTIVES
</div>
</div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2">
<Search className="h-4 w-4 text-muted-foreground" />
<input
type="text"
placeholder="Search goals..."
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/>
</div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-5 py-2 rounded-sm text-xs font-black tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/30 active:scale-95">
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
NEW GOAL NEW GOAL
</button> </button>
</div> </div>
</div> </div>
{/* AI Goal Strategist */} {/* Goal Matrix Categories */}
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 flex flex-col md:flex-row items-center justify-between gap-6"> <div className="grid grid-cols-1 md:grid-cols-4 gap-6 shrink-0">
<div className="flex items-start gap-4"> <GoalCategoryCard label="Critical" count={1} color="text-rose-500" icon={Zap} />
<div className="p-3 bg-primary/10 rounded-sm shrink-0"> <GoalCategoryCard label="High Priority" count={2} color="text-orange-500" icon={Star} />
<Brain className="h-6 w-6 text-primary" /> <GoalCategoryCard label="Medium" count={1} color="text-blue-500" icon={TrendingUp} />
</div> <GoalCategoryCard label="Completed" count={12} color="text-emerald-500" icon={CheckCircle2} />
<div>
<h3 className="text-sm font-semibold text-primary mb-1 flex items-center gap-2">
AI Goal Strategist
</h3>
<p className="text-xs text-foreground/80 leading-relaxed max-w-3xl">
You are falling behind on your <strong>Half-Marathon</strong> goal. Your running habit completion has dropped to 30% this month. AI suggests breaking the next milestone ("Maintain 15K weekly volume") into smaller, manageable 3K chunks to rebuild momentum.
</p>
</div>
</div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground px-4 py-2 rounded-sm text-xs font-semibold transition-colors shrink-0 shadow-lg shadow-primary/20">
Refactor Milestones
</button>
</div> </div>
{/* Goals List */} {/* Main Goals Grid */}
<div className="space-y-6 pb-6"> <div className="flex-1 overflow-y-auto tiny-scrollbar pr-1">
{goals.map((goal) => ( <div className="grid grid-cols-1 md:grid-cols-2 gap-8 pb-6">
<div key={goal.id} className="rounded-sm border border-white/5 bg-[#0A0710] p-6 flex flex-col lg:flex-row gap-8 relative overflow-hidden group"> {goals.map((goal) => (
<motion.div
key={goal.id}
whileHover={{ y: -4 }}
onClick={() => setSelectedGoal(goal)}
className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex flex-col gap-8 relative group overflow-hidden shadow-2xl cursor-pointer hover:border-primary/30 transition-all"
>
<div className={`absolute top-0 right-0 w-32 h-32 translate-x-16 -translate-y-16 opacity-10 blur-3xl rounded-full ${goal.priority === 'Critical' ? 'bg-rose-500' : 'bg-primary'}`} />
{/* Left Side: Overview & Progress */} <div className="flex justify-between items-start relative z-10">
<div className="flex-1 flex flex-col justify-between"> <div className="space-y-2">
<div> <div className="flex items-center gap-3">
<div className="flex items-center gap-3 mb-2"> <span className={`text-[10px] font-black uppercase tracking-widest px-2 py-0.5 rounded-sm border ${
<h2 className="text-xl font-bold text-foreground">{goal.title}</h2> goal.priority === 'Critical' ? 'text-rose-400 border-rose-500/20 bg-rose-500/5' :
<span className={`text-[10px] uppercase font-bold px-2 py-0.5 rounded-sm border ${ goal.priority === 'High' ? 'text-orange-400 border-orange-500/20 bg-orange-500/5' : 'text-blue-400 border-blue-500/20 bg-blue-500/5'
goal.status === 'Ahead' ? 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20' : }`}>
goal.status === 'Behind' ? 'bg-orange-500/10 text-orange-400 border-orange-500/20' : {goal.priority}
'bg-blue-500/10 text-blue-400 border-blue-500/20'
}`}>
{goal.status}
</span>
</div>
<div className="flex items-center gap-4 text-xs text-muted-foreground mb-6">
<span className="flex items-center gap-1.5"><Compass className="h-3.5 w-3.5" /> {goal.category}</span>
<span className="flex items-center gap-1.5"><Target className="h-3.5 w-3.5" /> Due: {goal.dueDate}</span>
</div>
</div>
{/* Big Progress Bar */}
<div>
<div className="flex justify-between items-end mb-2">
<span className="text-sm font-semibold">Overall Progress</span>
<span className="text-2xl font-bold" style={{ color: goal.color }}>{goal.progress}%</span>
</div>
<div className="h-3 w-full bg-white/5 rounded-full overflow-hidden">
<div
className="h-full rounded-full transition-all duration-1000 relative"
style={{ width: `${goal.progress}%`, backgroundColor: goal.color }}
>
{/* Inner highlight for 3D effect */}
<div className="absolute top-0 left-0 right-0 h-1/2 bg-white/20"></div>
</div>
</div>
</div>
</div>
{/* Right Side: Milestones */}
<div className="w-full lg:w-96 rounded-sm bg-[#150F1D] border border-white/5 p-4 flex flex-col">
<div className="flex justify-between items-center mb-4">
<h3 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Milestones</h3>
<button className="text-muted-foreground hover:text-foreground transition-colors"><MoreHorizontal className="h-4 w-4" /></button>
</div>
<div className="space-y-3 flex-1 overflow-y-auto tiny-scrollbar">
{goal.milestones.map((ms, idx) => (
<div key={idx} className="flex items-start gap-3">
{ms.done ? (
<CheckCircle2 className="h-4 w-4 shrink-0 mt-0.5" style={{ color: goal.color }} />
) : (
<CircleDashed className="h-4 w-4 text-muted-foreground shrink-0 mt-0.5" />
)}
<span className={`text-sm ${ms.done ? 'text-muted-foreground line-through' : 'text-foreground font-medium'}`}>
{ms.name}
</span> </span>
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">{goal.category}</span>
</div> </div>
))} <h3 className="text-2xl font-black tracking-tighter group-hover:text-primary transition-colors">{goal.title}</h3>
</div>
<button className="p-2 hover:bg-white/5 rounded-sm transition-colors text-muted-foreground"><MoreHorizontal className="h-5 w-5" /></button>
</div> </div>
<button className="mt-4 w-full border border-dashed border-white/10 hover:border-white/30 text-muted-foreground hover:text-foreground py-2 rounded-sm text-xs font-semibold transition-colors flex items-center justify-center gap-2"> <div className="space-y-4 relative z-10">
<Plus className="h-3 w-3" /> Add Milestone <div className="flex justify-between items-end">
</button> <div className="space-y-1">
</div> <div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground">Strategic Progress</div>
<div className="text-3xl font-black text-foreground">{goal.progress}%</div>
</div>
<div className="text-right">
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground mb-1">Target Date</div>
<div className="text-xs font-bold text-foreground">{goal.deadline}</div>
</div>
</div>
<div className="h-1.5 w-full bg-white/5 rounded-full overflow-hidden">
<motion.div
initial={{ width: 0 }}
animate={{ width: `${goal.progress}%` }}
transition={{ duration: 1, ease: "easeOut" }}
className={`h-full rounded-full ${goal.progress === 100 ? 'bg-emerald-500' : goal.status === 'Delayed' ? 'bg-rose-500' : 'bg-primary shadow-[0_0_15px_rgba(108,91,176,0.5)]'}`}
/>
</div>
</div>
</div> <div className="pt-6 border-t border-white/5 flex items-center justify-between relative z-10">
))} <div className="flex items-center gap-4">
<div className="flex -space-x-2">
{[1, 2, 3].map(i => <div key={i} className="h-6 w-6 rounded-full border border-[#0A0710] bg-[#1F172B] flex items-center justify-center text-[8px] font-bold">U{i}</div>)}
</div>
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">{goal.milestones?.length || 0} Milestones</span>
</div>
<button className="text-[10px] font-black uppercase tracking-widest text-primary flex items-center gap-2 group/btn">
VIEW STRATEGY <ArrowRight className="h-3 w-3 group-hover/btn:translate-x-1 transition-transform" />
</button>
</div>
</motion.div>
))}
</div>
</div> </div>
{/* Goal Detail Sheet */}
<AnimatePresence>
{selectedGoal && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedGoal(null)} className="fixed inset-0 bg-black/80 backdrop-blur-md z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-2xl bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col">
<div className="p-10 border-b border-white/5 flex items-center justify-between bg-primary/5">
<div className="space-y-2">
<div className="flex items-center gap-3">
<span className={`text-[10px] font-black uppercase tracking-widest px-2 py-1 rounded-sm border ${
selectedGoal.priority === 'Critical' ? 'text-rose-400 border-rose-500/20' : 'text-primary border-primary/20'
}`}>
{selectedGoal.priority} Priority
</span>
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">Category: {selectedGoal.category}</span>
</div>
<h2 className="text-3xl font-black tracking-tighter text-foreground">{selectedGoal.title}</h2>
</div>
<button onClick={() => setSelectedGoal(null)} className="p-3 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><X className="h-6 w-6" /></button>
</div>
<div className="flex-1 overflow-y-auto p-10 space-y-12 tiny-scrollbar">
{/* Progress Visual */}
<div className="grid grid-cols-3 gap-8">
<div className="col-span-2 bg-[#150F1D] border border-white/5 rounded-sm p-8 flex flex-col justify-center">
<div className="flex justify-between items-end mb-4">
<div className="text-[10px] font-black uppercase tracking-widest text-primary">Strategic Completion</div>
<div className="text-4xl font-black">{selectedGoal.progress}%</div>
</div>
<div className="h-2 w-full bg-white/5 rounded-full overflow-hidden">
<div className="h-full bg-primary" style={{ width: `${selectedGoal.progress}%` }} />
</div>
</div>
<div className="bg-white/5 border border-white/5 rounded-sm p-6 flex flex-col items-center justify-center text-center">
<Clock className="h-6 w-6 text-muted-foreground mb-2" />
<div className="text-lg font-black">{selectedGoal.deadline}</div>
<div className="text-[9px] font-bold text-muted-foreground uppercase tracking-widest">Target Date</div>
</div>
</div>
{/* AI Goal Intelligence */}
{selectedGoal.aiInsight && (
<div className="rounded-sm border border-primary/20 bg-primary/5 p-8 space-y-4 relative overflow-hidden">
<div className="absolute -right-4 -top-4 opacity-5">
<Brain className="h-24 w-24 text-primary" />
</div>
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary flex items-center gap-2">
<Brain className="h-4 w-4" /> Goal Intelligence Report
</h3>
<p className="text-sm font-medium text-foreground/90 leading-relaxed italic">
"{selectedGoal.aiInsight}"
</p>
</div>
)}
{/* Milestone Roadmap */}
<div className="space-y-6">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Milestone Roadmap</h3>
<div className="relative space-y-8 pl-6 before:absolute before:left-[11px] before:top-2 before:bottom-2 before:w-px before:bg-white/10">
{selectedGoal.milestones?.map((ms: any, i: number) => (
<div key={i} className="relative group">
<div className={`absolute -left-[23px] top-1 h-3 w-3 rounded-full border-2 border-[#0A0710] z-10 ${
ms.status === 'Done' ? 'bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]' :
ms.status === 'In Progress' ? 'bg-primary shadow-[0_0_8px_rgba(108,91,176,0.5)]' : 'bg-white/10'
}`} />
<div className="flex justify-between items-start">
<div>
<div className="text-sm font-bold group-hover:text-primary transition-colors">{ms.name}</div>
<div className="text-[10px] text-muted-foreground mt-1 uppercase font-medium">{ms.date} {ms.status}</div>
</div>
{ms.status === 'Done' && <CheckCircle2 className="h-4 w-4 text-emerald-500" />}
</div>
</div>
))}
</div>
</div>
{/* Connect Resources */}
<div className="space-y-6 pt-6 border-t border-white/5">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Linked Deliverables</h3>
<div className="grid grid-cols-2 gap-4">
<div className="p-4 rounded-sm bg-[#150F1D] border border-white/5 flex items-center justify-between group cursor-pointer hover:border-primary/20 transition-all">
<div className="flex items-center gap-3">
<div className="p-2 bg-blue-500/10 rounded-sm"><Briefcase className="h-4 w-4 text-blue-400" /></div>
<div>
<div className="text-xs font-bold">Project: Cognis App</div>
<div className="text-[9px] text-muted-foreground uppercase mt-1">Core Requirement</div>
</div>
</div>
<ChevronRight className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" />
</div>
<div className="p-4 rounded-sm bg-[#150F1D] border border-white/5 flex items-center justify-between group cursor-pointer hover:border-primary/20 transition-all">
<div className="flex items-center gap-3">
<div className="p-2 bg-emerald-500/10 rounded-sm"><Award className="h-4 w-4 text-emerald-500" /></div>
<div>
<div className="text-xs font-bold">Achievement: Series A</div>
<div className="text-[9px] text-muted-foreground uppercase mt-1">Strategic Outcome</div>
</div>
</div>
<ChevronRight className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" />
</div>
</div>
</div>
</div>
<div className="p-10 border-t border-white/5 bg-[#0F0B15]/50 flex gap-4">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-5 rounded-sm text-[11px] font-black uppercase tracking-widest shadow-2xl shadow-primary/30 transition-all active:scale-[0.98]">
UPDATE STRATEGIC PROGRESS
</button>
<button className="p-5 border border-white/10 rounded-sm text-muted-foreground hover:bg-white/5 transition-colors">
<BarChart3 className="h-6 w-6" />
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}
function GoalCategoryCard({ label, count, color, icon: Icon }: any) {
return (
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-6 flex items-center justify-between group hover:border-white/10 transition-all shadow-xl">
<div className="flex items-center gap-4">
<div className={`p-3 bg-white/5 rounded-sm ${color} transition-colors group-hover:bg-white/10`}>
<Icon className="h-5 w-5" />
</div>
<div>
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground mb-0.5">{label}</div>
<div className="text-xl font-black">{count}</div>
</div>
</div>
<ChevronRight className="h-4 w-4 text-muted-foreground/30" />
</div> </div>
); );
} }
+234 -146
View File
@@ -1,188 +1,276 @@
"use client"; "use client";
import { Plus, Filter, Brain, Check, X, Flame, Target, Trophy, TrendingUp } from "lucide-react"; import { useState } from "react";
import { Area, AreaChart, ResponsiveContainer, XAxis, Tooltip } from "recharts"; import {
Plus, Search, Zap, Flame, Calendar, CheckCircle2,
Trophy, TrendingUp, Brain, Info, X, MoreHorizontal,
ChevronRight, Activity, Clock, BarChart3, Target
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const habits = [ const habits = [
{ { id: 1, name: "Deep Work Block", frequency: "Daily", streak: 12, bestStreak: 24, progress: 85, color: "bg-[#6C5BB0]", icon: Brain, completedDays: [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15] },
id: 1, { id: 2, name: "7AM Gym Session", frequency: "Mon, Wed, Fri", streak: 4, bestStreak: 8, progress: 60, color: "bg-emerald-500", icon: Activity, completedDays: [1, 3, 5, 8, 10, 12, 15] },
name: "Morning Meditation", { id: 3, name: "Strategic Reading", frequency: "Daily", streak: 0, bestStreak: 15, progress: 30, color: "bg-blue-500", icon: Zap, completedDays: [1, 2, 3, 4, 10, 11] },
category: "Mindfulness", { id: 4, name: "Journaling", frequency: "Daily", streak: 18, bestStreak: 18, progress: 100, color: "bg-orange-500", icon: Target, completedDays: Array.from({length: 15}, (_, i) => i + 1) },
streak: 12,
goal: "Daily",
color: "#6C5BB0", // Primary
status: [true, true, true, false, true, true, false],
trend: [40, 45, 30, 60, 50, 70, 85]
},
{
id: 2,
name: "Read 20 Pages",
category: "Learning",
streak: 4,
goal: "Daily",
color: "#10b981", // Emerald
status: [false, true, true, true, true, false, false],
trend: [20, 40, 50, 40, 60, 80, 75]
},
{
id: 3,
name: "Gym Workout",
category: "Health",
streak: 2,
goal: "4x Week",
color: "#f97316", // Orange
status: [true, false, true, false, true, false, false],
trend: [50, 55, 45, 65, 60, 75, 90]
},
{
id: 4,
name: "No Sugar",
category: "Diet",
streak: 0,
goal: "Daily",
color: "#ef4444", // Red
status: [true, true, false, false, false, false, false],
trend: [80, 70, 60, 40, 30, 20, 10]
}
]; ];
const days = ["M", "T", "W", "T", "F", "S", "S"];
export default function HabitsPage() { export default function HabitsPage() {
const [selectedHabit, setSelectedHabit] = useState<any>(null);
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<h1 className="text-lg font-medium text-muted-foreground"> <div className="flex items-center gap-4">
<span className="text-foreground">Personal</span> / Habits Tracker <h1 className="text-lg font-medium text-muted-foreground">
</h1> <span className="text-foreground">Mindset</span> / Habits & Performance
</h1>
<div className="h-4 w-px bg-white/10" />
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-orange-500 bg-orange-500/5 px-3 py-1 rounded-sm border border-orange-500/10">
<Flame className="h-3 w-3" /> 18 DAY OVERALL STREAK
</div>
</div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<button className="bg-[#150F1D] hover:bg-white/5 text-foreground border border-white/10 px-3 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2">
<Filter className="h-4 w-4" /> <Search className="h-4 w-4 text-muted-foreground" />
</button> <input
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> type="text"
placeholder="Search habits..."
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/>
</div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-5 py-2 rounded-sm text-xs font-black tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/30 active:scale-95">
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
NEW HABIT NEW HABIT
</button> </button>
</div> </div>
</div> </div>
{/* AI Habit Optimizer */} {/* Top Stats Overview */}
<div className="rounded-sm border border-primary/20 bg-[linear-gradient(90deg,rgba(108,91,176,0.1)_0%,rgba(10,7,16,0)_100%)] p-6 flex flex-col md:flex-row items-center justify-between gap-6"> <div className="grid grid-cols-1 md:grid-cols-3 gap-6 shrink-0">
<div className="flex items-start gap-4"> <div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex items-center gap-6 group relative overflow-hidden shadow-2xl">
<div className="p-3 bg-primary/10 rounded-sm shrink-0"> <div className="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity"><Flame className="h-20 w-20 text-orange-500" /></div>
<Brain className="h-6 w-6 text-primary" /> <div className="p-4 bg-orange-500/10 rounded-sm"><Flame className="h-6 w-6 text-orange-500" /></div>
</div>
<div> <div>
<h3 className="text-sm font-semibold text-primary mb-1 flex items-center gap-2"> <div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground mb-1">Consistency Score</div>
AI Habit Optimizer <div className="flex items-baseline gap-2">
</h3> <span className="text-3xl font-black text-foreground tracking-tighter">92%</span>
<p className="text-xs text-foreground/80 leading-relaxed max-w-3xl"> <span className="text-[10px] text-emerald-500 font-bold">+4% vs last week</span>
I noticed a pattern: You often break your <strong>"No Sugar"</strong> streak on Thursdays. This correlates with high-stress days marked in your Journal. AI suggests scheduling a stress-relief activity (like a walk) around 3 PM on Thursdays to curb cravings. </div>
</p>
</div> </div>
</div> </div>
<button className="bg-primary/20 text-primary hover:bg-primary/30 border border-primary/30 px-4 py-2 rounded-sm text-xs font-semibold transition-colors shrink-0"> <div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex items-center gap-6 group relative overflow-hidden shadow-2xl">
Add Routine Intervention <div className="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity"><Trophy className="h-20 w-20 text-primary" /></div>
</button> <div className="p-4 bg-primary/10 rounded-sm"><Trophy className="h-6 w-6 text-primary" /></div>
</div>
{/* KPI Row */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-5 flex items-center justify-between">
<div> <div>
<h4 className="text-[10px] uppercase tracking-wider text-muted-foreground font-bold mb-1">Perfect Days This Month</h4> <div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground mb-1">Weekly Goals Hit</div>
<div className="text-3xl font-bold text-foreground">8</div> <div className="flex items-baseline gap-2">
<span className="text-3xl font-black text-foreground tracking-tighter">14/18</span>
<span className="text-[10px] text-muted-foreground font-bold tracking-widest uppercase">Target: 16</span>
</div>
</div> </div>
<Trophy className="h-10 w-10 text-emerald-500 opacity-20" />
</div> </div>
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-5 flex items-center justify-between"> <div className="bg-primary/5 border border-primary/20 rounded-sm p-8 flex flex-col justify-center relative overflow-hidden group">
<div> <div className="absolute -right-4 -top-4 opacity-5 rotate-12"><Brain className="h-24 w-24 text-primary" /></div>
<h4 className="text-[10px] uppercase tracking-wider text-muted-foreground font-bold mb-1">Longest Active Streak</h4> <div className="flex items-center gap-3 mb-2">
<div className="text-3xl font-bold text-foreground">12 <span className="text-sm text-muted-foreground font-normal">days</span></div> <Brain className="h-4 w-4 text-primary" />
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">AI Coach</h3>
</div> </div>
<Flame className="h-10 w-10 text-orange-500 opacity-20" /> <p className="text-xs font-bold leading-relaxed text-foreground/80 italic">
</div> "Your 'Strategic Reading' is slipping. Consider linking it to your 'Morning Coffee' habit to increase completion by ~40%."
<div className="rounded-sm border border-white/5 bg-[#0A0710] p-5 flex items-center justify-between"> </p>
<div>
<h4 className="text-[10px] uppercase tracking-wider text-muted-foreground font-bold mb-1">Overall Completion Rate</h4>
<div className="text-3xl font-bold text-foreground">68%</div>
</div>
<Target className="h-10 w-10 text-blue-500 opacity-20" />
</div> </div>
</div> </div>
{/* Habit Grid */} {/* Main Habits Container */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 pb-6"> <div className="flex-1 overflow-y-auto tiny-scrollbar">
{habits.map((habit) => ( <div className="grid grid-cols-1 xl:grid-cols-2 gap-8 pb-6">
<div key={habit.id} className="rounded-sm border border-white/5 bg-[#0A0710] p-6 flex flex-col group hover:border-white/10 transition-colors relative overflow-hidden">
{/* Top Info */} {/* Habits Cards */}
<div className="flex justify-between items-start mb-6 z-10"> <div className="space-y-6">
<div> <div className="flex items-center justify-between px-2">
<h3 className="text-lg font-bold text-foreground mb-1">{habit.name}</h3> <h3 className="text-[11px] font-black uppercase tracking-[0.3em] text-muted-foreground">Active Disciplines</h3>
<div className="flex gap-2 items-center"> <button className="text-[10px] font-bold text-muted-foreground hover:text-foreground flex items-center gap-2 uppercase tracking-widest"><Calendar className="h-3.5 w-3.5" /> Monthly View</button>
<span className="text-[10px] uppercase tracking-wider font-bold px-2 py-0.5 rounded-sm bg-white/5 text-muted-foreground border border-white/5">{habit.category}</span>
<span className="text-xs text-muted-foreground flex items-center gap-1">
<Target className="h-3 w-3" /> {habit.goal}
</span>
</div>
</div>
<div className="flex flex-col items-end">
<span className="text-xs text-muted-foreground mb-0.5">Current Streak</span>
<div className="flex items-center gap-1.5 font-bold" style={{ color: habit.streak > 0 ? habit.color : '#8F89A5' }}>
<Flame className="h-4 w-4" /> {habit.streak}
</div>
</div>
</div> </div>
{/* Weekly Checkboxes */} <div className="space-y-4">
<div className="flex justify-between items-center mb-6 z-10"> {habits.map(habit => (
{days.map((day, idx) => ( <motion.div
<div key={idx} className="flex flex-col items-center gap-2"> key={habit.id}
<span className="text-[10px] font-bold text-muted-foreground">{day}</span> whileHover={{ x: 4 }}
<button onClick={() => setSelectedHabit(habit)}
className="w-8 h-8 rounded-sm flex items-center justify-center transition-all border" className="bg-[#0A0710] border border-white/5 rounded-sm p-6 flex flex-col gap-6 relative group overflow-hidden shadow-xl cursor-pointer hover:border-primary/30 transition-all"
style={{ >
backgroundColor: habit.status[idx] ? `${habit.color}20` : '#150F1D', <div className="flex justify-between items-start relative z-10">
borderColor: habit.status[idx] ? `${habit.color}50` : '#ffffff10', <div className="flex items-center gap-4">
color: habit.status[idx] ? habit.color : '#ffffff20' <div className={`p-3 rounded-sm ${habit.color}/10 text-foreground`}>
}} <habit.icon className="h-6 w-6 text-foreground" />
> </div>
{habit.status[idx] ? <Check className="h-4 w-4" /> : <X className="h-3 w-3" />} <div>
</button> <h3 className="text-lg font-black group-hover:text-primary transition-colors">{habit.name}</h3>
</div> <div className="flex items-center gap-3 mt-1">
<span className="text-[10px] font-black uppercase tracking-widest text-muted-foreground">{habit.frequency}</span>
<div className="w-1 h-1 rounded-full bg-white/20" />
<div className="flex items-center gap-1 text-[10px] font-black text-orange-500 uppercase tracking-widest">
<Flame className="h-3 w-3" /> {habit.streak} DAY STREAK
</div>
</div>
</div>
</div>
<div className="flex gap-4 items-center">
<div className="text-right">
<div className="text-[10px] font-black text-muted-foreground uppercase tracking-widest mb-1">Completion</div>
<div className="text-xl font-black">{habit.progress}%</div>
</div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground p-3 rounded-sm shadow-xl shadow-primary/20 transition-all active:scale-90">
<CheckCircle2 className="h-6 w-6" />
</button>
</div>
</div>
{/* Mini Heatmap Visualization */}
<div className="grid grid-cols-15 gap-1.5 h-3">
{Array.from({length: 15}).map((_, i) => {
const isCompleted = habit.completedDays.includes(i + 1);
return (
<div
key={i}
className={`rounded-[2px] transition-all ${isCompleted ? habit.color + ' opacity-100 shadow-[0_0_8px_rgba(108,91,176,0.3)]' : 'bg-white/5 opacity-30 hover:opacity-50'}`}
/>
);
})}
</div>
</motion.div>
))} ))}
</div> </div>
</div>
{/* Micro Chart (Background styling) */} {/* Detailed Performance Analytics */}
<div className="h-16 w-full mt-auto relative z-0 opacity-50 group-hover:opacity-100 transition-opacity"> <div className="space-y-6">
<div className="absolute top-0 left-0 text-[10px] text-muted-foreground uppercase tracking-widest font-bold flex items-center gap-1"> <div className="flex items-center justify-between px-2">
<TrendingUp className="h-3 w-3" /> 30-Day Trend <h3 className="text-[11px] font-black uppercase tracking-[0.3em] text-muted-foreground">Strategic Insight</h3>
</div> <button className="text-[10px] font-bold text-muted-foreground hover:text-foreground uppercase tracking-widest">Full Reports</button>
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={habit.trend.map((val, i) => ({ name: i, value: val }))}>
<defs>
<linearGradient id={`grad-${habit.id}`} x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={habit.color} stopOpacity={0.3}/>
<stop offset="95%" stopColor={habit.color} stopOpacity={0}/>
</linearGradient>
</defs>
<Tooltip
cursor={false}
contentStyle={{ display: 'none' }}
/>
<Area type="monotone" dataKey="value" stroke={habit.color} strokeWidth={2} fillOpacity={1} fill={`url(#grad-${habit.id})`} />
</AreaChart>
</ResponsiveContainer>
</div> </div>
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex flex-col gap-8 h-fit shadow-2xl">
<div>
<h4 className="text-xs font-black uppercase tracking-widest text-primary mb-4">Weekly Success Rate</h4>
<div className="flex items-end justify-between h-40 gap-4">
{[45, 65, 30, 85, 95, 70, 80].map((h, i) => (
<div key={i} className="flex-1 flex flex-col items-center gap-3 group/bar">
<div className="w-full relative">
<motion.div
initial={{ height: 0 }}
animate={{ height: `${h}%` }}
transition={{ duration: 1, delay: i * 0.1 }}
className={`w-full rounded-sm bg-primary/20 border-t-2 border-primary group-hover/bar:bg-primary/40 transition-all cursor-pointer`}
/>
</div>
<span className="text-[8px] font-black text-muted-foreground uppercase tracking-widest">{["M", "T", "W", "T", "F", "S", "S"][i]}</span>
</div>
))}
</div>
</div>
<div className="pt-8 border-t border-white/5 space-y-6">
<div className="flex items-center gap-3">
<TrendingUp className="h-5 w-5 text-emerald-500" />
<div>
<div className="text-xs font-black uppercase tracking-widest">Momentum Building</div>
<p className="text-[10px] text-muted-foreground leading-relaxed mt-1">You've maintained a 90%+ completion rate for 4 consecutive days. This is a 12% improvement over last week's performance.</p>
</div>
</div>
<div className="flex items-center gap-3">
<Activity className="h-5 w-5 text-primary" />
<div>
<div className="text-xs font-black uppercase tracking-widest">Peak Performance Hub</div>
<p className="text-[10px] text-muted-foreground leading-relaxed mt-1">Deep Work completion correlates 85% with 7AM Gym sessions. Physical discipline is driving your strategic output.</p>
</div>
</div>
</div>
</div>
</div> </div>
))}
</div>
</div> </div>
{/* Habit Detail Sheet */}
<AnimatePresence>
{selectedHabit && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedHabit(null)} className="fixed inset-0 bg-black/80 backdrop-blur-md z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-xl bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col p-10 space-y-12">
<div className="flex justify-between items-start">
<div className={`p-5 rounded-sm ${selectedHabit.color}/20 text-foreground`}>
<selectedHabit.icon className="h-10 w-10" />
</div>
<button onClick={() => setSelectedHabit(null)} className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><X className="h-7 w-7" /></button>
</div>
<div className="space-y-2">
<h2 className="text-4xl font-black tracking-tighter">{selectedHabit.name}</h2>
<div className="flex items-center gap-5">
<div className="flex items-center gap-2">
<Flame className="h-4 w-4 text-orange-500" />
<span className="text-lg font-black text-orange-500">{selectedHabit.streak} DAY STREAK</span>
</div>
<div className="text-xs font-black text-muted-foreground uppercase tracking-widest border-l border-white/10 pl-5">BEST STREAK: {selectedHabit.bestStreak} DAYS</div>
</div>
</div>
<div className="space-y-8 pt-8 border-t border-white/5">
<div>
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary mb-6">30-Day Activity Heatmap</h3>
<div className="grid grid-cols-10 gap-2">
{Array.from({length: 30}).map((_, i) => {
const isCompleted = selectedHabit.completedDays.includes(i + 1);
return (
<div
key={i}
className={`aspect-square rounded-sm border ${isCompleted ? selectedHabit.color + ' border-transparent shadow-[0_0_12px_rgba(108,91,176,0.2)]' : 'bg-white/5 border-white/5 opacity-20'}`}
/>
);
})}
</div>
</div>
<div className="grid grid-cols-2 gap-6">
<div className="p-6 rounded-sm bg-[#150F1D] border border-white/5 space-y-2">
<div className="text-[10px] font-black text-muted-foreground uppercase tracking-widest">FREQUENCY</div>
<div className="text-sm font-black text-foreground">{selectedHabit.frequency}</div>
</div>
<div className="p-6 rounded-sm bg-[#150F1D] border border-white/5 space-y-2">
<div className="text-[10px] font-black text-muted-foreground uppercase tracking-widest">MONTHLY SUCCESS</div>
<div className="text-sm font-black text-emerald-400">{selectedHabit.progress}%</div>
</div>
</div>
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 space-y-4">
<h3 className="text-[10px] font-black uppercase tracking-widest text-primary flex items-center gap-2">
<Zap className="h-3.5 w-3.5" /> Performance Context
</h3>
<p className="text-xs text-muted-foreground leading-relaxed italic">
You've hit this habit {selectedHabit.completedDays.length} times this month. Strategic data suggests that completing this before 10 AM increases your daily task throughput by 12%.
</p>
</div>
</div>
<div className="mt-auto flex gap-4">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-4 rounded-sm text-[11px] font-black uppercase tracking-widest shadow-2xl shadow-primary/30 transition-all active:scale-[0.98]">
MARK AS COMPLETED TODAY
</button>
<button className="p-4 border border-white/10 rounded-sm text-muted-foreground hover:bg-white/5 transition-colors">
<BarChart3 className="h-6 w-6" />
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div> </div>
); );
} }
+248 -106
View File
@@ -1,152 +1,294 @@
"use client"; "use client";
import { Plus, Search, Filter, Brain, PenTool, Calendar, AlignLeft, Tag, Lock, Sparkles, Image as ImageIcon } from "lucide-react"; import { useState } from "react";
import {
Plus, Search, Calendar, Clock, Brain, MessageSquare,
Smile, Frown, Meh, Star, MoreHorizontal, X,
Zap, Save, Trash2, Edit3, Image as ImageIcon, Link as LinkIcon,
ChevronLeft, ChevronRight, Activity, Filter, AlignLeft, Hash
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const journalEntries = [ const journalEntries = [
{ {
id: 1, id: 1,
title: "Breakthrough in System Design", date: "May 15, 2026",
preview: "Today we finally cracked the database architecture. By moving to a distributed model...", title: "Deep Work Breakthrough",
date: "Today, 10:45 AM", excerpt: "Today I finally cracked the multi-tenant architecture logic for the Cognis core. Energy was high after the morning focus block.",
tags: ["Work", "Idea", "Win"], sentiment: "Great",
sentiment: "Positive" moodScore: 92,
tags: ["Productivity", "Coding"],
content: "The morning started with a 4-hour deep work block. I avoided all notifications and focused purely on the database schema. The multi-tenant logic is now solid. I feel a huge weight off my shoulders. Physical energy was 9/10 thanks to the 7am gym session."
}, },
{ {
id: 2, id: 2,
title: "Feeling a bit overwhelmed", date: "May 14, 2026",
preview: "The Q3 deadlines are approaching fast. I need to make sure I'm prioritizing...", title: "Project Risk Discussion",
date: "Yesterday", excerpt: "Met with Alex regarding the Infrastructure delays. Felt a bit anxious about the timeline but the AI risk report helped us focus.",
tags: ["Mental Health", "Vent"], sentiment: "Neutral",
sentiment: "Anxious" moodScore: 65,
tags: ["Meeting", "Stress"],
content: "Alex and I went through the infrastructure roadmap. We are indeed behind on the database migration. The stress is real, but we have a plan now. AI suggests prioritizing the migration scripts. Note for tomorrow: focus on script optimization."
}, },
{ { id: 3, date: "May 12, 2026", title: "Creative Flow", excerpt: "Spent the afternoon in Figma. The new 'Cyber-Lavender' palette is looking stunning in the dark mode previews.", sentiment: "Great", moodScore: 88, tags: ["Design", "Creative"] },
id: 3,
title: "Morning Routine Reflection",
preview: "Woke up at 6 AM. Did 20 minutes of meditation. It really sets the tone for...",
date: "May 06, 2026",
tags: ["Habits", "Morning"],
sentiment: "Calm"
}
]; ];
export default function JournalPage() { export default function JournalPage() {
const [selectedEntry, setSelectedEntry] = useState<any>(null);
const [isCreating, setIsCreating] = useState(false);
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<h1 className="text-lg font-medium text-muted-foreground"> <div className="flex items-center gap-4">
<span className="text-foreground">Personal</span> / Daily Journal <h1 className="text-lg font-medium text-muted-foreground">
</h1> <span className="text-foreground">Mindset</span> / Strategic Journal
</h1>
<div className="h-4 w-px bg-white/10" />
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-primary">
<Edit3 className="h-3 w-3" /> 128 ENTRIES RECORDED
</div>
</div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2"> <div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2">
<Search className="h-4 w-4 text-muted-foreground" /> <Search className="h-4 w-4 text-muted-foreground" />
<input <input
type="text" type="text"
placeholder="Search memories..." placeholder="Search thoughts..."
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground" className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/> />
</div> </div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <button
onClick={() => setIsCreating(true)}
className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-5 py-2 rounded-sm text-xs font-black tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/30 active:scale-95"
>
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
NEW ENTRY NEW ENTRY
</button> </button>
</div> </div>
</div> </div>
{/* Main Layout */} <div className="flex-1 flex gap-8 min-h-0">
<div className="flex flex-col lg:flex-row gap-6 flex-1 min-h-0">
{/* Left Panel: Entry List & AI */} {/* Left Sidebar: Entries List */}
<div className="w-full lg:w-80 flex flex-col gap-6 shrink-0"> <div className="w-full max-w-sm flex flex-col gap-4 overflow-y-auto tiny-scrollbar pr-2">
<div className="flex items-center justify-between px-2 mb-2">
{/* AI Sentiment Analysis */} <h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground">Recent Reflections</h3>
<div className="rounded-sm border border-primary/20 bg-[linear-gradient(135deg,rgba(108,91,176,0.1)_0%,rgba(10,7,16,0)_100%)] p-5"> <button className="text-[10px] font-bold text-muted-foreground hover:text-foreground flex items-center gap-1">
<h3 className="text-sm font-semibold text-primary mb-2 flex items-center gap-2"> <Filter className="h-3 w-3" /> FILTER
<Brain className="h-4 w-4" /> AI Reflection Insight
</h3>
<p className="text-[11px] text-foreground/80 leading-relaxed mb-3">
Over the last 14 days, your entries tagged with <strong>"Work"</strong> show a 30% increase in stress vocabulary. However, entries after <strong>Morning Meditation</strong> are consistently highly positive.
</p>
<button className="bg-primary/20 text-primary hover:bg-primary/30 border border-primary/30 px-3 py-1.5 rounded-sm text-[10px] font-bold uppercase tracking-wider transition-colors w-full">
Generate Weekly Summary
</button> </button>
</div> </div>
{/* Entries List */} <div className="space-y-4">
<div className="flex-1 rounded-sm border border-white/5 bg-[#0A0710] flex flex-col overflow-hidden"> {journalEntries.map(entry => (
<div className="p-4 border-b border-white/5 flex justify-between items-center"> <motion.div
<span className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Recent Entries</span> key={entry.id}
<Filter className="h-4 w-4 text-muted-foreground hover:text-foreground cursor-pointer" /> whileHover={{ x: 4 }}
</div> onClick={() => setSelectedEntry(entry)}
<div className="flex-1 overflow-y-auto tiny-scrollbar p-2 space-y-1"> className={`p-5 rounded-sm border cursor-pointer transition-all ${selectedEntry?.id === entry.id ? 'bg-[#1F172B] border-primary/40 shadow-xl' : 'bg-[#0A0710] border-white/5 hover:border-white/10'}`}
{journalEntries.map((entry, idx) => ( >
<div key={entry.id} className={`p-3 rounded-sm cursor-pointer transition-colors ${idx === 0 ? 'bg-[#1F172B] border border-primary/30' : 'hover:bg-white/5 border border-transparent'}`}> <div className="flex justify-between items-start mb-3">
<h4 className="text-sm font-semibold text-foreground mb-1 truncate">{entry.title}</h4> <span className="text-[10px] font-black uppercase tracking-widest text-muted-foreground">{entry.date}</span>
<p className="text-[11px] text-muted-foreground line-clamp-2 leading-relaxed mb-2"> <SentimentIcon sentiment={entry.sentiment} />
{entry.preview} </div>
</p> <h3 className={`text-sm font-black mb-2 transition-colors ${selectedEntry?.id === entry.id ? 'text-primary' : 'text-foreground'}`}>{entry.title}</h3>
<div className="flex justify-between items-center text-[10px]"> <p className="text-[11px] text-muted-foreground leading-relaxed line-clamp-2 italic">"{entry.excerpt}"</p>
<span className="text-primary font-medium">{entry.date}</span> <div className="flex gap-2 mt-4">
<span className="flex gap-1"> {entry.tags.map(tag => (
{entry.tags.map(tag => ( <span key={tag} className="text-[8px] font-black uppercase tracking-widest px-2 py-0.5 rounded-sm bg-white/5 text-muted-foreground">#{tag}</span>
<span key={tag} className="bg-white/10 px-1.5 py-0.5 rounded-sm">{tag}</span> ))}
))} </div>
</span> </motion.div>
))}
</div>
</div>
{/* Main Content: Entry Viewer/Editor */}
<div className="flex-1 bg-[#0A0710] border border-white/5 rounded-sm flex flex-col relative overflow-hidden shadow-2xl">
<AnimatePresence mode="wait">
{selectedEntry ? (
<motion.div
key={selectedEntry.id}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
className="flex-1 flex flex-col"
>
<div className="p-10 border-b border-white/5 flex items-center justify-between bg-primary/5">
<div className="space-y-1">
<div className="flex items-center gap-3">
<span className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">{selectedEntry.date}</span>
<div className="w-1.5 h-1.5 rounded-full bg-white/20" />
<div className="flex items-center gap-1.5 text-[10px] font-black text-emerald-400">
<Activity className="h-3 w-3" /> MOOD SCORE: {selectedEntry.moodScore}%
</div>
</div>
<h2 className="text-3xl font-black tracking-tighter text-foreground">{selectedEntry.title}</h2>
</div>
<div className="flex gap-2">
<button className="p-2.5 hover:bg-white/5 rounded-sm text-muted-foreground transition-colors"><Edit3 className="h-5 w-5" /></button>
<button className="p-2.5 hover:bg-white/5 rounded-sm text-rose-500 transition-colors"><Trash2 className="h-5 w-5" /></button>
</div> </div>
</div> </div>
))}
</div>
</div>
</div>
{/* Right Panel: Editor Mock */} <div className="flex-1 p-10 overflow-y-auto tiny-scrollbar space-y-12">
<div className="flex-1 rounded-sm border border-white/5 bg-[#0A0710] flex flex-col relative overflow-hidden group">
{/* Editor Header */} {/* AI Psychological Insight */}
<div className="p-4 border-b border-white/5 flex justify-between items-center bg-[#0F0B15]/50"> <div className="rounded-sm border border-primary/20 bg-primary/5 p-8 space-y-4 relative overflow-hidden">
<div className="flex items-center gap-4 text-xs text-muted-foreground"> <div className="absolute -right-4 -top-4 opacity-5">
<span className="flex items-center gap-1.5"><Calendar className="h-4 w-4" /> Today, 10:45 AM</span> <Brain className="h-24 w-24 text-primary" />
<span className="flex items-center gap-1.5"><Tag className="h-4 w-4" /> 3 Tags</span> </div>
<span className="flex items-center gap-1.5"><Lock className="h-4 w-4" /> Private</span> <h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary flex items-center gap-2">
</div> <Brain className="h-4 w-4" /> Cognitive Analysis
<div className="flex items-center gap-2"> </h3>
<button className="p-1.5 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><AlignLeft className="h-4 w-4" /></button> <p className="text-sm font-medium text-foreground/90 leading-relaxed italic">
<button className="p-1.5 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><ImageIcon className="h-4 w-4" /></button> "I've noticed that your mood scores peak when you mention 'Deep Work' blocks in the morning. However, meeting-heavy days seem to correlate with anxious sentiment. Consider restructuring 'Infrastructure' discussions for early PM."
<button className="p-1.5 hover:bg-primary/20 bg-primary/10 rounded-sm text-primary transition-colors flex items-center gap-1"> </p>
<Sparkles className="h-4 w-4" /> <span className="text-[10px] font-bold">Ask AI</span> </div>
</button>
</div>
</div>
{/* Editor Body */} {/* Body Content */}
<div className="flex-1 p-8 md:px-12 md:py-10 overflow-y-auto tiny-scrollbar"> <div className="space-y-6">
<input <p className="text-lg text-foreground/90 leading-[1.8] font-medium tracking-tight">
type="text" {selectedEntry.content || "No detailed content available for this entry."}
value="Breakthrough in System Design" </p>
readOnly </div>
className="w-full bg-transparent border-none outline-none text-3xl font-bold text-foreground mb-6"
/> {/* Strategic Connections */}
<div className="text-foreground/80 leading-loose space-y-6 text-sm"> <div className="pt-10 border-t border-white/5 space-y-6">
<p> <h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Connected Strategics</h3>
Today we finally cracked the database architecture. By moving to a distributed model, we've essentially solved the latency issues we were seeing during peak load. It feels incredibly satisfying to see weeks of research finally click into place. <div className="grid grid-cols-2 gap-4">
</p> <div className="p-4 rounded-sm bg-[#150F1D] border border-white/5 flex items-center justify-between group cursor-pointer hover:border-primary/30 transition-all">
<p> <div className="flex items-center gap-3">
I was discussing this with Alex earlier, and he pointed out that this structure directly mirrors the microservices split we planned for Q4. This means we are actually ahead of schedule! <div className="p-2 bg-primary/10 rounded-sm"><Zap className="h-4 w-4 text-primary" /></div>
</p> <div>
<div className="pl-4 border-l-2 border-primary text-primary italic"> <div className="text-xs font-bold text-foreground">Goal: Scaling Backend</div>
AI Note: You've mentioned "latency issues" in 3 previous entries. Consider documenting this final solution in the Engineering Wiki for future reference. <div className="text-[9px] text-muted-foreground uppercase mt-1">Directly Referenced</div>
</div>
</div>
<ArrowRight className="h-3 w-3 text-muted-foreground group-hover:text-primary transition-all" />
</div>
<div className="p-4 rounded-sm bg-[#150F1D] border border-white/5 flex items-center justify-between group cursor-pointer hover:border-primary/30 transition-all">
<div className="flex items-center gap-3">
<div className="p-2 bg-emerald-500/10 rounded-sm"><Clock className="h-4 w-4 text-emerald-500" /></div>
<div>
<div className="text-xs font-bold text-foreground">Habit: 7AM Gym</div>
<div className="text-[9px] text-muted-foreground uppercase mt-1">Impact Observed</div>
</div>
</div>
<ArrowRight className="h-3 w-3 text-muted-foreground group-hover:text-primary transition-all" />
</div>
</div>
</div>
</div>
<div className="p-8 border-t border-white/5 bg-[#0F0B15]/40 flex justify-between items-center">
<div className="flex -space-x-2">
{[1, 2, 3].map(i => <div key={i} className="h-8 w-8 rounded-full border-2 border-[#0A0710] bg-[#1F172B] flex items-center justify-center text-[10px] font-bold">A{i}</div>)}
<div className="h-8 w-8 rounded-full border-2 border-[#0A0710] bg-primary/20 flex items-center justify-center text-[10px] font-bold text-primary">+2</div>
</div>
<button className="text-[10px] font-black text-primary uppercase tracking-widest flex items-center gap-2 hover:bg-primary/10 px-4 py-2 rounded-sm transition-all">
<MessageSquare className="h-4 w-4" /> 12 COMMENTS
</button>
</div>
</motion.div>
) : (
<div className="flex-1 flex flex-col items-center justify-center p-20 text-center space-y-6">
<div className="p-6 bg-white/5 rounded-full">
<AlignLeft className="h-12 w-12 text-muted-foreground/30" />
</div>
<div>
<h2 className="text-xl font-black uppercase tracking-widest text-muted-foreground">No Entry Selected</h2>
<p className="text-sm text-muted-foreground mt-2 max-w-xs mx-auto italic">Select a reflection from the sidebar or create a new strategic entry to begin.</p>
</div>
<button
onClick={() => setIsCreating(true)}
className="bg-primary/10 text-primary border border-primary/20 px-6 py-2.5 rounded-sm text-xs font-black tracking-widest uppercase hover:bg-primary/20 transition-all"
>
Create Your First Entry
</button>
</div> </div>
<p> )}
Gonna take the rest of the evening off to recharge. Need to keep this momentum going without burning out. </AnimatePresence>
</p>
</div>
</div>
</div> </div>
</div> </div>
{/* New Entry Modal */}
<AnimatePresence>
{isCreating && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setIsCreating(false)} className="fixed inset-0 bg-black/90 backdrop-blur-xl z-[100]" />
<motion.div initial={{ scale: 0.95, opacity: 0, y: 20 }} animate={{ scale: 1, opacity: 1, y: 0 }} exit={{ scale: 0.95, opacity: 0, y: 20 }} className="fixed inset-0 m-auto w-full max-w-4xl h-[85vh] bg-[#0A0710] border border-white/10 z-[101] shadow-2xl flex flex-col rounded-sm overflow-hidden">
<div className="p-8 border-b border-white/5 flex items-center justify-between bg-primary/10">
<div className="flex items-center gap-4">
<div className="p-2.5 bg-primary rounded-sm shadow-xl shadow-primary/20"><Edit3 className="h-5 w-5 text-primary-foreground" /></div>
<div>
<h2 className="text-xl font-black uppercase tracking-tight">New Reflection</h2>
<p className="text-[10px] font-black text-primary tracking-[0.3em] uppercase">Documenting Strategic Growth</p>
</div>
</div>
<button onClick={() => setIsCreating(false)} className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><X className="h-7 w-7" /></button>
</div>
<div className="flex-1 flex flex-col p-10 space-y-8 overflow-y-auto tiny-scrollbar">
<div className="space-y-2">
<label className="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em]">Title of Reflection</label>
<input type="text" placeholder="e.g., Q3 Breakthrough or Team Alignment thoughts..." className="w-full bg-transparent border-none text-3xl font-black placeholder:text-muted-foreground/20 outline-none" />
</div>
<div className="flex gap-6 pb-6 border-b border-white/5">
<div className="flex items-center gap-3 bg-white/5 px-4 py-2 rounded-sm border border-white/5">
<Calendar className="h-4 w-4 text-primary" />
<span className="text-xs font-bold">May 15, 2026</span>
</div>
<div className="flex items-center gap-4">
<span className="text-[10px] font-black text-muted-foreground uppercase tracking-widest">Sentiment:</span>
<div className="flex gap-2">
<button className="p-2 rounded-sm bg-white/5 hover:bg-emerald-500/20 hover:text-emerald-500 transition-all"><Smile className="h-5 w-5" /></button>
<button className="p-2 rounded-sm bg-white/5 hover:bg-primary/20 hover:text-primary transition-all"><Meh className="h-5 w-5" /></button>
<button className="p-2 rounded-sm bg-white/5 hover:bg-rose-500/20 hover:text-rose-500 transition-all"><Frown className="h-5 w-5" /></button>
</div>
</div>
</div>
<div className="flex-1 min-h-[300px]">
<textarea
placeholder="Write your strategic reflections here... Use # to link goals or tasks."
className="w-full h-full bg-transparent border-none outline-none text-lg leading-relaxed text-foreground/80 resize-none placeholder:text-muted-foreground/10 font-medium"
/>
</div>
<div className="flex items-center gap-4 pt-6 border-t border-white/5">
<button className="p-2 text-muted-foreground hover:text-primary transition-colors"><ImageIcon className="h-5 w-5" /></button>
<button className="p-2 text-muted-foreground hover:text-primary transition-colors"><LinkIcon className="h-5 w-5" /></button>
<button className="p-2 text-muted-foreground hover:text-primary transition-colors"><Hash className="h-5 w-5" /></button>
<div className="ml-auto flex items-center gap-2 text-[10px] font-black text-muted-foreground/50 uppercase tracking-widest">
<Clock className="h-3 w-3" /> Auto-saving to Cloud...
</div>
</div>
</div>
<div className="p-10 border-t border-white/5 flex gap-6 bg-[#0F0B15]/60">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-5 rounded-sm text-[11px] font-black uppercase tracking-[0.3em] shadow-2xl shadow-primary/40 transition-all active:scale-[0.98] flex items-center justify-center gap-3">
<Save className="h-5 w-5" /> PUBLISH REFLECTION
</button>
<button onClick={() => setIsCreating(false)} className="px-10 border border-white/10 rounded-sm text-[11px] font-black uppercase tracking-[0.2em] text-muted-foreground hover:bg-white/5 transition-all">
DISCARD
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div> </div>
); );
} }
function SentimentIcon({ sentiment }: { sentiment: string }) {
if (sentiment === "Great") return <Smile className="h-4 w-4 text-emerald-500" />;
if (sentiment === "Neutral") return <Meh className="h-4 w-4 text-primary" />;
return <Frown className="h-4 w-4 text-rose-500" />;
}
+287 -116
View File
@@ -1,57 +1,64 @@
"use client"; "use client";
import { Plus, Search, Filter, Brain, AlertCircle, Clock, CheckCircle2, MoreHorizontal, Users, BarChart } from "lucide-react"; import { useState } from "react";
import {
Plus, Search, MoreHorizontal, MessageSquare, Clock,
CheckCircle2, AlertCircle, Layout, List, ArrowRight,
TrendingUp, Users, Calendar, Activity, X, ChevronRight,
Zap, Shield, Globe, Briefcase, Brain
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data // Mock Data
const projects = [ const projects = [
{ {
id: 1, id: 1,
name: "Cognis Mobile App", name: "Marketing Site",
status: "In Progress", description: "Main landing page and marketing funnel optimizations for the Q3 campaign.",
progress: 65, progress: 75,
dueDate: "May 28, 2026", members: 4,
team: ["JD", "AK", "LM"], tasks: 24,
aiRisk: "Low", deadline: "May 25",
aiSuggestion: "On track. Consistent velocity detected." status: "Active",
health: "Good",
phases: [
{ name: "Design", status: "Done", date: "Apr 15" },
{ name: "Development", status: "In Progress", date: "May 10" },
{ name: "QA", status: "Upcoming", date: "May 20" },
],
aiRisk: "Low risk. Team velocity is 12% higher than average. Content approval is the only potential bottleneck."
}, },
{ {
id: 2, id: 2,
name: "Q3 Marketing Site", name: "Infrastructure",
status: "At Risk", description: "Database and cloud server optimizations to support scaling to 100k users.",
progress: 32, progress: 45,
dueDate: "Jun 15, 2026", members: 2,
team: ["RK", "ST"], tasks: 12,
aiRisk: "High", deadline: "Jun 10",
aiSuggestion: "Bottleneck detected in Design phase. Suggest assigning 1 more designer." status: "Delayed",
health: "At Risk",
phases: [
{ name: "Migration", status: "In Progress", date: "May 12" },
{ name: "Load Testing", status: "Upcoming", date: "May 25" },
{ name: "Live Deploy", status: "Upcoming", date: "Jun 05" },
],
aiRisk: "High risk. Lead developer is over-allocated. Database migration scripts need optimization for the large dataset."
}, },
{ { id: 3, name: "Cognis Mobile", description: "React Native application for iOS/Android including push notifications.", progress: 92, members: 6, tasks: 48, deadline: "May 18", status: "Active", health: "Excell.", phases: [], aiRisk: "" },
id: 3, { id: 4, name: "Research", description: "User interview synthesis and competitor analysis for market expansion.", progress: 100, members: 3, tasks: 8, deadline: "May 05", status: "Completed", health: "Stable", phases: [], aiRisk: "" },
name: "Database Migration", { id: 5, name: "API v2", description: "Restructuring the core API for scale and performance improvements.", progress: 30, members: 5, tasks: 32, deadline: "Jul 15", status: "Active", health: "Good", phases: [], aiRisk: "" },
status: "Review",
progress: 90,
dueDate: "May 20, 2026",
team: ["JS", "AL", "BQ", "MK"],
aiRisk: "Medium",
aiSuggestion: "QA testing is taking 20% longer than historical average."
},
{
id: 4,
name: "User Authentication V2",
status: "To Do",
progress: 0,
dueDate: "Jul 01, 2026",
team: ["AK", "LM"],
aiRisk: "Low",
aiSuggestion: "Dependencies cleared. Ready to start."
}
]; ];
export default function ProjectsPage() { export default function ProjectsPage() {
const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
const [selectedProject, setSelectedProject] = useState<any>(null);
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<h1 className="text-lg font-medium text-muted-foreground"> <h1 className="text-lg font-medium text-muted-foreground">
<span className="text-foreground">Management</span> / Projects <span className="text-foreground">Management</span> / Projects
</h1> </h1>
@@ -64,103 +71,267 @@ export default function ProjectsPage() {
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground" className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/> />
</div> </div>
<button className="bg-[#150F1D] hover:bg-white/5 text-foreground border border-white/10 px-3 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-bold tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/20">
<Filter className="h-4 w-4" />
</button>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors">
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
NEW PROJECT NEW PROJECT
</button> </button>
</div> </div>
</div> </div>
{/* AI Project Manager Insight */} {/* Analytics Overview Cards */}
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 flex items-start gap-4"> <div className="grid grid-cols-1 md:grid-cols-3 gap-6 shrink-0">
<div className="p-3 bg-primary/10 rounded-sm"> <ProjectStatCard label="Active Projects" value="4" subtext="+1 from last month" icon={Activity} />
<Brain className="h-6 w-6 text-primary" /> <ProjectStatCard label="Average Progress" value="68%" subtext="12% ahead of schedule" icon={TrendingUp} />
</div> <ProjectStatCard label="Total Members" value="15" subtext="Across 5 project teams" icon={Users} />
<div className="flex-1"> </div>
<h3 className="text-sm font-semibold text-primary mb-1 flex items-center gap-2">
AI Project Assistant {/* View Toggle */}
<span className="bg-primary/20 text-primary text-[9px] uppercase px-1.5 py-0.5 rounded-sm">Active</span> <div className="flex items-center justify-between">
</h3> <div className="flex items-center gap-2 bg-[#150F1D] border border-white/5 rounded-sm p-0.5">
<p className="text-xs text-foreground/80 leading-relaxed mb-3"> <button onClick={() => setViewMode("grid")} className={`px-3 py-1.5 text-[10px] font-bold uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'grid' ? 'bg-[#2B2538] text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}`}><Layout className="h-3 w-3" /> Grid</button>
I have analyzed your active projects. <strong>Q3 Marketing Site</strong> is showing a high risk of delay based on current commit velocity. <button onClick={() => setViewMode("list")} className={`px-3 py-1.5 text-[10px] font-bold uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'list' ? 'bg-[#2B2538] text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}`}><List className="h-3 w-3" /> List</button>
I recommend redistributing tasks or extending the deadline by 4 days.
</p>
<div className="flex gap-3">
<button className="bg-primary hover:bg-primary/90 text-primary-foreground px-4 py-1.5 rounded-sm text-xs font-semibold transition-colors">
Apply AI Reallocation
</button>
<button className="bg-transparent hover:bg-white/5 text-foreground border border-white/10 px-4 py-1.5 rounded-sm text-xs font-semibold transition-colors">
View Detailed Analysis
</button>
</div>
</div> </div>
</div> </div>
{/* Project Cards Grid */} {/* Projects Container */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6"> <div className="flex-1 overflow-y-auto tiny-scrollbar">
{projects.map((project) => ( {viewMode === "grid" ? (
<div key={project.id} className="rounded-sm border border-white/5 bg-[#0A0710] flex flex-col group"> <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
{/* Card Header */} {projects.map((project) => (
<div className="p-6 border-b border-white/5 flex justify-between items-start"> <motion.div
<div> key={project.id}
<div className="flex items-center gap-3 mb-2"> whileHover={{ y: -4 }}
<h2 className="text-base font-semibold">{project.name}</h2> onClick={() => setSelectedProject(project)}
<span className={`text-[10px] uppercase font-bold px-2 py-0.5 rounded-sm border ${ className="bg-[#0A0710] border border-white/5 rounded-sm p-6 flex flex-col gap-6 relative group overflow-hidden shadow-2xl cursor-pointer hover:border-primary/30 transition-all"
project.status === 'In Progress' ? 'bg-blue-500/10 text-blue-400 border-blue-500/20' : >
project.status === 'At Risk' ? 'bg-red-500/10 text-red-400 border-red-500/20' : <div className={`absolute top-0 right-0 w-32 h-32 translate-x-16 -translate-y-16 opacity-10 blur-3xl rounded-full ${project.status === 'Delayed' ? 'bg-rose-500' : 'bg-primary'}`} />
project.status === 'Review' ? 'bg-orange-500/10 text-orange-400 border-orange-500/20' :
'bg-white/5 text-muted-foreground border-white/10' <div className="flex justify-between items-start relative z-10">
<div className="flex-1 min-w-0">
<h3 className="text-lg font-black truncate group-hover:text-primary transition-colors">{project.name}</h3>
<p className="text-xs text-muted-foreground mt-1 line-clamp-1">{project.description}</p>
</div>
<button className="p-1.5 hover:bg-white/5 rounded-sm transition-colors text-muted-foreground"><MoreHorizontal className="h-4 w-4" /></button>
</div>
<div className="space-y-3">
<div className="flex justify-between text-[10px] font-bold">
<span className="text-muted-foreground uppercase tracking-widest">Global Progress</span>
<span>{project.progress}%</span>
</div>
<div className="h-1 w-full bg-white/5 rounded-full overflow-hidden">
<motion.div
initial={{ width: 0 }}
animate={{ width: `${project.progress}%` }}
transition={{ duration: 1, ease: "easeOut" }}
className={`h-full rounded-full ${project.progress === 100 ? 'bg-emerald-500' : project.status === 'Delayed' ? 'bg-rose-500' : 'bg-primary shadow-[0_0_12px_rgba(108,91,176,0.6)]'}`}
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="flex items-center gap-2">
<div className="p-1.5 bg-white/5 rounded-sm">
<Calendar className="h-3 w-3 text-muted-foreground" />
</div>
<span className="text-[10px] font-bold text-muted-foreground">{project.deadline}</span>
</div>
<div className="flex items-center gap-2 justify-end">
<div className="flex -space-x-2">
{[1, 2, 3].map(i => (
<div key={i} className="h-5 w-5 rounded-full border border-[#0A0710] bg-[#1F172B] flex items-center justify-center text-[8px] font-bold">U{i}</div>
))}
</div>
<span className="text-[10px] font-bold text-muted-foreground ml-1">{project.members} Team</span>
</div>
</div>
<div className="pt-4 border-t border-white/5 flex items-center justify-between">
<span className={`text-[9px] font-black uppercase tracking-[0.2em] px-2 py-1 rounded-sm border ${
project.health === 'Good' ? 'text-blue-400 border-blue-500/20 bg-blue-500/5' :
project.health === 'Excell.' ? 'text-emerald-400 border-emerald-500/20 bg-emerald-500/5' :
project.health === 'At Risk' ? 'text-rose-400 border-rose-500/20 bg-rose-500/5' : 'text-muted-foreground border-white/10'
}`}> }`}>
{project.status} {project.health}
</span> </span>
<button className="text-[9px] font-black uppercase tracking-widest flex items-center gap-1 text-primary group/btn">
VIEW DETAILS <ArrowRight className="h-3 w-3 group-hover/btn:translate-x-1 transition-transform" />
</button>
</div> </div>
<div className="flex items-center gap-4 text-xs text-muted-foreground"> </motion.div>
<div className="flex items-center gap-1.5"><Clock className="h-3.5 w-3.5" /> Due {project.dueDate}</div> ))}
<div className="flex items-center gap-1.5"><Users className="h-3.5 w-3.5" /> {project.team.length} Members</div> </div>
</div> ) : (
</div> <div className="bg-[#0A0710] border border-white/5 rounded-sm overflow-hidden">
<button className="text-muted-foreground hover:text-foreground opacity-0 group-hover:opacity-100 transition-opacity"> <div className="grid grid-cols-12 gap-4 p-4 border-b border-white/5 bg-[#0F0B15]/50 text-[10px] font-bold uppercase tracking-widest text-muted-foreground">
<MoreHorizontal className="h-5 w-5" /> <div className="col-span-4">Project Name</div>
</button> <div className="col-span-2">Health Status</div>
<div className="col-span-3">Progress Metrics</div>
<div className="col-span-2">Final Deadline</div>
<div className="col-span-1"></div>
</div> </div>
<div className="divide-y divide-white/5">
{/* AI Risk & Suggestion */} {projects.map(project => (
<div className="p-4 bg-[#150F1D]/50 border-b border-white/5 flex gap-3 items-start"> <div key={project.id} onClick={() => setSelectedProject(project)} className="grid grid-cols-12 gap-4 p-5 items-center hover:bg-white/[0.02] transition-colors group cursor-pointer">
{project.aiRisk === "High" ? <AlertCircle className="h-4 w-4 text-red-400 mt-0.5 shrink-0" /> : <div className="col-span-4">
project.aiRisk === "Medium" ? <BarChart className="h-4 w-4 text-orange-400 mt-0.5 shrink-0" /> : <div className="text-sm font-black group-hover:text-primary transition-colors">{project.name}</div>
<CheckCircle2 className="h-4 w-4 text-emerald-400 mt-0.5 shrink-0" />} <div className="text-[10px] text-muted-foreground mt-0.5 tracking-wider">{project.tasks} Active Deliverables</div>
<div> </div>
<div className="text-[10px] font-bold uppercase tracking-wider mb-0.5 flex items-center gap-1.5"> <div className="col-span-2">
<Brain className="h-3 w-3" /> <span className={`text-[9px] font-black uppercase tracking-widest px-2 py-1 rounded-sm border ${
AI Risk: <span className={ project.health === 'Good' ? 'text-blue-400 border-blue-500/20 bg-blue-500/5' :
project.aiRisk === 'High' ? 'text-red-400' : project.health === 'Excell.' ? 'text-emerald-400 border-emerald-500/20 bg-emerald-500/5' : 'text-rose-400 border-rose-500/20 bg-rose-500/5'
project.aiRisk === 'Medium' ? 'text-orange-400' : 'text-emerald-400' }`}>
}>{project.aiRisk}</span> {project.health}
</span>
</div>
<div className="col-span-3 pr-12">
<div className="flex justify-between text-[10px] font-bold mb-2">
<span className="text-muted-foreground">{project.progress}% Complete</span>
</div>
<div className="h-1.5 w-full bg-white/5 rounded-full overflow-hidden">
<div className={`h-full rounded-full ${project.progress === 100 ? 'bg-emerald-500' : 'bg-primary'}`} style={{ width: `${project.progress}%` }} />
</div>
</div>
<div className="col-span-2 text-xs font-bold text-muted-foreground uppercase">{project.deadline}</div>
<div className="col-span-1 flex justify-end">
<button className="p-1.5 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><MoreHorizontal className="h-4 w-4" /></button>
</div>
</div> </div>
<p className="text-xs text-muted-foreground">{project.aiSuggestion}</p> ))}
</div>
</div>
{/* Progress & Actions */}
<div className="p-6 mt-auto">
<div className="flex justify-between items-center mb-2">
<span className="text-xs font-medium">Progress</span>
<span className="text-xs font-bold text-primary">{project.progress}%</span>
</div>
<div className="h-1.5 w-full bg-white/5 rounded-full overflow-hidden">
<div
className="h-full bg-primary rounded-full transition-all duration-1000"
style={{ width: `${project.progress}%` }}
></div>
</div>
</div> </div>
</div> </div>
))} )}
</div> </div>
{/* Project Detail Sheet */}
<AnimatePresence>
{selectedProject && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedProject(null)} className="fixed inset-0 bg-black/80 backdrop-blur-md z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-2xl bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col">
<div className="p-10 border-b border-white/5 flex items-center justify-between bg-primary/5">
<div className="space-y-2">
<div className="flex items-center gap-3">
<span className={`text-[10px] font-black uppercase tracking-widest px-2 py-1 rounded-sm border ${
selectedProject.health === 'Good' ? 'text-blue-400 border-blue-500/20' :
selectedProject.health === 'Excell.' ? 'text-emerald-400 border-emerald-500/20' : 'text-rose-400 border-rose-500/20'
}`}>
{selectedProject.health} Health
</span>
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">Due: {selectedProject.deadline}</span>
</div>
<h2 className="text-3xl font-black tracking-tighter text-foreground">{selectedProject.name}</h2>
</div>
<button onClick={() => setSelectedProject(null)} className="p-3 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><X className="h-6 w-6" /></button>
</div>
<div className="flex-1 overflow-y-auto p-10 space-y-12 tiny-scrollbar">
{/* Description & KPI */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
<div className="md:col-span-2 space-y-4">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Overview</h3>
<p className="text-sm text-muted-foreground leading-relaxed">{selectedProject.description}</p>
</div>
<div className="bg-[#150F1D] border border-white/5 rounded-sm p-6 flex flex-col items-center justify-center text-center">
<div className="text-4xl font-black text-primary mb-1">{selectedProject.progress}%</div>
<div className="text-[9px] font-bold text-muted-foreground uppercase tracking-widest">Global Progress</div>
</div>
</div>
{/* AI Risk Intelligence */}
{selectedProject.aiRisk && (
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 space-y-3 relative overflow-hidden">
<div className="absolute -right-4 -top-4 opacity-5">
<Brain className="h-20 w-20 text-primary" />
</div>
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary flex items-center gap-2">
<Brain className="h-3.5 w-3.5" /> AI Risk Assessment
</h3>
<p className="text-xs font-medium text-foreground/90 leading-relaxed italic">
"{selectedProject.aiRisk}"
</p>
</div>
)}
{/* Timeline / Phases */}
<div className="space-y-6">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Project Roadmap</h3>
<div className="relative space-y-8 pl-6 before:absolute before:left-[11px] before:top-2 before:bottom-2 before:w-px before:bg-white/10">
{selectedProject.phases?.map((phase: any, i: number) => (
<div key={i} className="relative group">
<div className={`absolute -left-[23px] top-1 h-3 w-3 rounded-full border-2 border-[#0A0710] z-10 ${
phase.status === 'Done' ? 'bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]' :
phase.status === 'In Progress' ? 'bg-primary shadow-[0_0_8px_rgba(108,91,176,0.5)]' : 'bg-white/10'
}`} />
<div className="flex justify-between items-start">
<div>
<div className="text-sm font-bold group-hover:text-primary transition-colors">{phase.name}</div>
<div className="text-[10px] text-muted-foreground mt-1 uppercase font-medium">{phase.date} {phase.status}</div>
</div>
{phase.status === 'Done' && <CheckCircle2 className="h-4 w-4 text-emerald-500" />}
</div>
</div>
))}
</div>
</div>
{/* Team & Resources */}
<div className="space-y-6">
<div className="flex justify-between items-center">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Team Allocation</h3>
<button className="text-[10px] font-bold text-muted-foreground hover:text-foreground">MANAGE TEAM</button>
</div>
<div className="grid grid-cols-2 gap-4">
{[1, 2, 3, 4].slice(0, selectedProject.members).map(i => (
<div key={i} className="p-4 rounded-sm bg-[#150F1D] border border-white/5 flex items-center gap-3">
<div className="h-10 w-10 rounded-sm bg-primary/10 border border-primary/20 flex items-center justify-center font-black text-primary text-xs">U{i}</div>
<div>
<div className="text-xs font-bold text-foreground">Project Member {i}</div>
<div className="text-[10px] text-muted-foreground uppercase tracking-widest mt-1">Strategic Lead</div>
</div>
</div>
))}
</div>
</div>
</div>
<div className="p-10 border-t border-white/5 bg-[#0F0B15]/50 flex gap-4">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-4 rounded-sm text-[11px] font-black uppercase tracking-widest shadow-xl shadow-primary/30 transition-all active:scale-[0.98]">
LAUNCH PROJECT CONSOLE
</button>
<button className="p-4 border border-white/10 rounded-sm text-muted-foreground hover:bg-white/5 transition-colors">
<Activity className="h-6 w-6" />
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}
function ProjectStatCard({ label, value, subtext, icon: Icon }: any) {
return (
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex items-center gap-6 group relative overflow-hidden shadow-xl">
<div className="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity">
<Icon className="h-20 w-20 text-foreground" />
</div>
<div className="p-4 bg-white/5 rounded-sm group-hover:bg-primary/10 transition-colors relative z-10">
<Icon className="h-6 w-6 text-muted-foreground group-hover:text-primary transition-colors" />
</div>
<div className="relative z-10">
<div className="text-[10px] font-black uppercase tracking-[0.2em] text-muted-foreground mb-1">{label}</div>
<div className="flex items-baseline gap-2">
<span className="text-3xl font-black text-foreground tracking-tighter">{value}</span>
<span className="text-[10px] text-emerald-500 font-bold uppercase tracking-widest">{subtext}</span>
</div>
</div>
</div> </div>
); );
} }
+302
View File
@@ -0,0 +1,302 @@
"use client";
import { useState } from "react";
import {
Plus, Search, FileText, FileCheck, Clock, Shield,
MoreHorizontal, Download, Share2, Eye, Brain,
ChevronRight, ArrowRight, X, CheckCircle2,
AlertCircle, DollarSign, PenTool, Send, Layout, List
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
// Mock Data
const proposals = [
{
id: 1,
title: "Enterprise AI Integration",
client: "Acme Corp",
value: "$42,000",
status: "Sent",
date: "May 15",
health: "Warm",
aiInsight: "92% probability of closing based on recent meeting sentiment analysis.",
details: "Full stack AI integration including LLM deployment and custom data pipelines."
},
{
id: 2,
title: "Cloud Infrastructure Audit",
client: "Global Tech",
value: "$12,500",
status: "Negotiation",
date: "May 12",
health: "Critical",
aiInsight: "Client is questioning the pricing on Clause 4.2. Suggesting a 5% bundle discount.",
details: "Security audit and scalability roadmap for the AWS infrastructure."
},
{ id: 3, title: "Design System Revamp", client: "Nexus Design", value: "$8,200", status: "Signed", date: "May 08", health: "Secure", aiInsight: "", details: "" },
{ id: 4, title: "Mobile App Retainer", client: "Stark Ind.", value: "$5,000/mo", status: "Draft", date: "May 20", health: "Lead", aiInsight: "", details: "" },
];
export default function ProposalsPage() {
const [selectedProposal, setSelectedProposal] = useState<any>(null);
const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<div className="flex items-center gap-4">
<h1 className="text-lg font-medium text-muted-foreground">
<span className="text-foreground">Business</span> / Proposals & Contracts
</h1>
<div className="h-4 w-px bg-white/10" />
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-primary bg-primary/5 px-3 py-1 rounded-sm border border-primary/10">
<FileCheck className="h-3 w-3" /> 8 SIGNED CONTRACTS
</div>
</div>
<div className="flex items-center gap-3">
<div className="bg-[#150F1D] border border-white/5 rounded-sm px-3 py-1.5 flex items-center gap-2">
<Search className="h-4 w-4 text-muted-foreground" />
<input
type="text"
placeholder="Search proposals..."
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/>
</div>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-5 py-2 rounded-sm text-xs font-black tracking-widest flex items-center gap-2 transition-all shadow-lg shadow-primary/30 active:scale-95">
<Plus className="h-4 w-4" />
NEW PROPOSAL
</button>
</div>
</div>
{/* Lifecycle Status Cards */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 shrink-0">
<StatusCard label="Drafts" count={2} color="text-muted-foreground" icon={PenTool} />
<StatusCard label="Out for Review" count={3} color="text-blue-500" icon={Send} />
<StatusCard label="Negotiation" count={1} color="text-orange-500" icon={Clock} />
<StatusCard label="Active Contracts" count={8} color="text-emerald-500" icon={Shield} />
</div>
{/* Main Container */}
<div className="flex-1 flex flex-col gap-6 overflow-hidden">
<div className="flex items-center justify-between shrink-0">
<div className="flex items-center gap-2 bg-[#150F1D] border border-white/5 rounded-sm p-0.5">
<button onClick={() => setViewMode("grid")} className={`px-3 py-1.5 text-[10px] font-bold uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'grid' ? 'bg-[#2B2538] text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}`}><Layout className="h-3 w-3" /> Grid</button>
<button onClick={() => setViewMode("list")} className={`px-3 py-1.5 text-[10px] font-bold uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'list' ? 'bg-[#2B2538] text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}`}><List className="h-3 w-3" /> List</button>
</div>
<div className="flex items-center gap-4 text-[10px] font-black uppercase tracking-widest text-muted-foreground">
<span>Sort by: Latest</span>
<MoreHorizontal className="h-4 w-4" />
</div>
</div>
<div className="flex-1 overflow-y-auto tiny-scrollbar pr-1">
{viewMode === "grid" ? (
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-8 pb-6">
{proposals.map((prop) => (
<motion.div
key={prop.id}
whileHover={{ y: -4 }}
onClick={() => setSelectedProposal(prop)}
className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex flex-col gap-8 relative group overflow-hidden shadow-2xl cursor-pointer hover:border-primary/30 transition-all"
>
<div className={`absolute top-0 right-0 w-32 h-32 translate-x-16 -translate-y-16 opacity-5 blur-3xl rounded-full ${prop.status === 'Signed' ? 'bg-emerald-500' : 'bg-primary'}`} />
<div className="flex justify-between items-start relative z-10">
<div className="space-y-2">
<div className="flex items-center gap-3">
<span className={`text-[9px] font-black uppercase tracking-widest px-2 py-0.5 rounded-sm border ${
prop.status === 'Signed' ? 'text-emerald-400 border-emerald-500/20 bg-emerald-500/5' :
prop.status === 'Negotiation' ? 'text-orange-400 border-orange-500/20 bg-orange-500/5' : 'text-blue-400 border-blue-500/20 bg-blue-500/5'
}`}>
{prop.status}
</span>
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">{prop.client}</span>
</div>
<h3 className="text-xl font-black tracking-tighter group-hover:text-primary transition-colors">{prop.title}</h3>
</div>
<FileText className="h-6 w-6 text-muted-foreground/30 group-hover:text-primary/50 transition-colors" />
</div>
<div className="space-y-2 relative z-10">
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground">Contract Value</div>
<div className="text-2xl font-black text-foreground">{prop.value}</div>
</div>
<div className="pt-6 border-t border-white/5 flex items-center justify-between relative z-10">
<div className="flex items-center gap-2">
<Clock className="h-3.5 w-3.5 text-muted-foreground" />
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">Updated {prop.date}</span>
</div>
<div className={`text-[9px] font-black uppercase tracking-widest flex items-center gap-1 ${
prop.health === 'Secure' ? 'text-emerald-400' : prop.health === 'Critical' ? 'text-rose-400' : 'text-primary'
}`}>
{prop.health} PULSE
</div>
</div>
</motion.div>
))}
</div>
) : (
<div className="bg-[#0A0710] border border-white/5 rounded-sm overflow-hidden shadow-2xl">
<div className="grid grid-cols-12 gap-4 p-5 border-b border-white/5 bg-[#0F0B15]/50 text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground">
<div className="col-span-4 px-2">Document Title</div>
<div className="col-span-2">Client</div>
<div className="col-span-2">Lifecycle</div>
<div className="col-span-2">Value</div>
<div className="col-span-2 text-right">Actions</div>
</div>
<div className="divide-y divide-white/5">
{proposals.map(prop => (
<div key={prop.id} onClick={() => setSelectedProposal(prop)} className="grid grid-cols-12 gap-4 p-6 items-center hover:bg-white/[0.02] transition-all group cursor-pointer">
<div className="col-span-4 flex items-center gap-4">
<div className="h-8 w-8 rounded-sm bg-white/5 flex items-center justify-center"><FileText className="h-4 w-4 text-muted-foreground" /></div>
<span className="text-sm font-black group-hover:text-primary transition-colors">{prop.title}</span>
</div>
<div className="col-span-2 text-xs font-bold text-muted-foreground uppercase">{prop.client}</div>
<div className="col-span-2">
<span className={`text-[9px] font-black uppercase tracking-widest px-2 py-0.5 rounded-sm border ${prop.status === 'Signed' ? 'text-emerald-400 border-emerald-500/20' : 'text-primary border-primary/20'}`}>
{prop.status}
</span>
</div>
<div className="col-span-2 text-sm font-black text-foreground">{prop.value}</div>
<div className="col-span-2 flex justify-end opacity-0 group-hover:opacity-100 transition-all">
<button className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground"><MoreHorizontal className="h-4 w-4" /></button>
</div>
</div>
))}
</div>
</div>
)}
</div>
</div>
{/* Proposal Detail Sheet */}
<AnimatePresence>
{selectedProposal && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedProposal(null)} className="fixed inset-0 bg-black/80 backdrop-blur-md z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-2xl bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col">
<div className="p-10 border-b border-white/5 flex items-center justify-between bg-primary/5">
<div className="space-y-2">
<div className="flex items-center gap-3">
<span className="text-[10px] font-black uppercase tracking-widest text-primary border border-primary/20 px-2 py-0.5 rounded-sm">{selectedProposal.status}</span>
<span className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest">{selectedProposal.client}</span>
</div>
<h2 className="text-3xl font-black tracking-tighter text-foreground">{selectedProposal.title}</h2>
</div>
<button onClick={() => setSelectedProposal(null)} className="p-3 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><X className="h-6 w-6" /></button>
</div>
<div className="flex-1 overflow-y-auto p-10 space-y-12 tiny-scrollbar">
{/* AI Closing Probability */}
{selectedProposal.aiInsight && (
<div className="rounded-sm border border-primary/20 bg-primary/5 p-8 space-y-4 relative overflow-hidden">
<div className="absolute -right-4 -top-4 opacity-5">
<Brain className="h-24 w-24 text-primary" />
</div>
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary flex items-center gap-2">
<Brain className="h-4 w-4" /> AI Strategic Analysis
</h3>
<p className="text-sm font-medium text-foreground/90 leading-relaxed italic">
"{selectedProposal.aiInsight}"
</p>
</div>
)}
{/* Key Details */}
<div className="grid grid-cols-2 gap-8">
<div className="bg-[#150F1D] border border-white/5 rounded-sm p-6 space-y-2">
<div className="text-[10px] font-black text-muted-foreground uppercase tracking-widest">CONTRACT VALUE</div>
<div className="text-2xl font-black text-primary">{selectedProposal.value}</div>
</div>
<div className="bg-[#150F1D] border border-white/5 rounded-sm p-6 space-y-2">
<div className="text-[10px] font-black text-muted-foreground uppercase tracking-widest">RELATIONSHIP HEALTH</div>
<div className="text-2xl font-black text-foreground">{selectedProposal.health}</div>
</div>
</div>
{/* Lifecycle Roadmap */}
<div className="space-y-6">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Engagement History</h3>
<div className="relative space-y-8 pl-6 before:absolute before:left-[11px] before:top-2 before:bottom-2 before:w-px before:bg-white/10">
<HistoryItem title="Proposal Draft Created" date="May 10" status="Done" />
<HistoryItem title="Initial Review with Client" date="May 12" status="Done" />
<HistoryItem title="Current State: Negotiation" date="Now" status="Active" />
<HistoryItem title="Pending: Final Approval" date="TBD" status="Upcoming" />
</div>
</div>
{/* Quick Actions */}
<div className="space-y-6 pt-6 border-t border-white/5">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Contractual Controls</h3>
<div className="grid grid-cols-2 gap-4">
<ControlBtn icon={Download} label="Export PDF" />
<ControlBtn icon={Share2} label="Secure Share" />
<ControlBtn icon={Eye} label="Client Preview" />
<ControlBtn icon={Shield} label="Verify Sig." />
</div>
</div>
</div>
<div className="p-10 border-t border-white/5 bg-[#0F0B15]/50 flex gap-4">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-5 rounded-sm text-[11px] font-black uppercase tracking-widest shadow-2xl shadow-primary/30 transition-all active:scale-[0.98] flex items-center justify-center gap-3">
<Send className="h-5 w-5" /> SEND REVISED PROPOSAL
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}
function HistoryItem({ title, date, status }: any) {
return (
<div className="relative group">
<div className={`absolute -left-[23px] top-1 h-3 w-3 rounded-full border-2 border-[#0A0710] z-10 ${
status === 'Done' ? 'bg-emerald-500' : status === 'Active' ? 'bg-primary' : 'bg-white/10'
}`} />
<div className="flex justify-between items-start">
<div>
<div className="text-sm font-bold group-hover:text-primary transition-colors">{title}</div>
<div className="text-[10px] text-muted-foreground mt-1 uppercase font-medium">{date}</div>
</div>
</div>
</div>
);
}
function ControlBtn({ icon: Icon, label }: any) {
return (
<button className="p-4 rounded-sm bg-[#150F1D] border border-white/5 flex items-center gap-3 group hover:border-primary/20 transition-all">
<Icon className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" />
<span className="text-[10px] font-black text-muted-foreground uppercase tracking-widest group-hover:text-foreground">{label}</span>
</button>
);
}
function StatusCard({ label, count, color, icon: Icon }: any) {
return (
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-6 flex items-center justify-between group hover:border-white/10 transition-all shadow-xl">
<div className="flex items-center gap-4">
<div className={`p-3 bg-white/5 rounded-sm ${color} transition-colors group-hover:bg-white/10`}>
<Icon className="h-5 w-5" />
</div>
<div>
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground mb-0.5">{label}</div>
<div className="text-xl font-black">{count}</div>
</div>
</div>
<ChevronRight className="h-4 w-4 text-muted-foreground/30" />
</div>
);
}
+229 -150
View File
@@ -1,67 +1,47 @@
"use client"; "use client";
import { Plus, Search, Filter, Brain, CheckSquare2, Clock, AlertCircle, MoreHorizontal, MessageSquare, ArrowUpRight, CheckCircle2 } from "lucide-react"; import { useState } from "react";
import {
Plus, Search, Filter, Brain, CheckSquare2, Clock, AlertCircle,
MoreHorizontal, MessageSquare, ArrowUpRight, CheckCircle2,
GripVertical, List, Layout, X, Calendar, User, Tag
} from "lucide-react";
import { motion, AnimatePresence, Reorder } from "framer-motion";
// Mock Data // Mock Data
const tasks = [ const initialTasks = [
{ { id: "1", title: "Finalize Q3 Marketing Assets", project: "Marketing Site", priority: "High", status: "In Progress", assignee: "Sarah J.", aiPredict: "2 days", dueDate: "May 15" },
id: 1, { id: "2", title: "Database Migration Script", project: "Infrastructure", priority: "Critical", status: "Review", assignee: "Alex R.", aiPredict: "4 hours", dueDate: "May 12" },
title: "Finalize Q3 Marketing Assets", { id: "3", title: "Design System Tokens", project: "Cognis Mobile", priority: "Medium", status: "To Do", assignee: "Mike C.", aiPredict: "3 days", dueDate: "May 20" },
project: "Marketing Site", { id: "4", title: "Client Interview Synthesis", project: "Research", priority: "Low", status: "Done", assignee: "Emma W.", aiPredict: "Completed", dueDate: "May 08" },
priority: "High", { id: "5", title: "Optimize Webpack Config", project: "Infrastructure", priority: "Medium", status: "To Do", assignee: "Alex R.", aiPredict: "1 day", dueDate: "May 18" }
status: "In Progress",
assignee: "Sarah J.",
aiPredict: "2 days",
dueDate: "May 15"
},
{
id: 2,
title: "Database Migration Script",
project: "Infrastructure",
priority: "Critical",
status: "Review",
assignee: "Alex R.",
aiPredict: "4 hours",
dueDate: "May 12"
},
{
id: 3,
title: "Design System Tokens",
project: "Cognis Mobile",
priority: "Medium",
status: "To Do",
assignee: "Mike C.",
aiPredict: "3 days",
dueDate: "May 20"
},
{
id: 4,
title: "Client Interview Synthesis",
project: "Research",
priority: "Low",
status: "Done",
assignee: "Emma W.",
aiPredict: "Completed",
dueDate: "May 08"
},
{
id: 5,
title: "Optimize Webpack Config",
project: "Infrastructure",
priority: "Medium",
status: "To Do",
assignee: "Alex R.",
aiPredict: "1 day",
dueDate: "May 18"
}
]; ];
const columns = ["To Do", "In Progress", "Review", "Done"];
export default function TasksPage() { export default function TasksPage() {
const [viewMode, setViewMode] = useState<"list" | "kanban">("list");
const [tasks, setTasks] = useState(initialTasks);
const [isSorting, setIsSorting] = useState(false);
const [selectedTask, setSelectedTask] = useState<any>(null);
const handleAutoSort = () => {
setIsSorting(true);
setTimeout(() => {
const sorted = [...tasks].sort((a, b) => {
const priorityOrder: any = { Critical: 0, High: 1, Medium: 2, Low: 3 };
return priorityOrder[a.priority] - priorityOrder[b.priority];
});
setTasks(sorted);
setIsSorting(false);
}, 1500);
};
return ( return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6"> <div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */} {/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4"> <div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<h1 className="text-lg font-medium text-muted-foreground"> <h1 className="text-lg font-medium text-muted-foreground">
<span className="text-foreground">Management</span> / Tasks <span className="text-foreground">Management</span> / Tasks
</h1> </h1>
@@ -74,128 +54,227 @@ export default function TasksPage() {
className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground" className="bg-transparent border-none outline-none text-xs w-48 placeholder:text-muted-foreground/50 text-foreground"
/> />
</div> </div>
<button className="bg-[#150F1D] hover:bg-white/5 text-foreground border border-white/10 px-3 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors"> <button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-all active:scale-95 shadow-lg shadow-primary/20">
<Filter className="h-4 w-4" />
FILTER
</button>
<button className="bg-primary hover:bg-primary/90 text-primary-foreground border border-primary/20 px-4 py-1.5 rounded-sm text-xs font-semibold flex items-center gap-2 transition-colors">
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
NEW TASK NEW TASK
</button> </button>
</div> </div>
</div> </div>
{/* AI Task Prioritization */} {/* AI Task Prioritization Card */}
<div className="rounded-sm border border-primary/20 bg-primary/5 p-6 flex flex-col md:flex-row items-start md:items-center justify-between gap-6"> <div className="rounded-sm border border-primary/20 bg-primary/5 p-6 flex flex-col md:flex-row items-start md:items-center justify-between gap-6 relative overflow-hidden group">
<div className="absolute -right-4 -bottom-4 opacity-5 rotate-12 transition-transform group-hover:scale-110">
<Brain className="h-24 w-24 text-primary" />
</div>
<div className="flex items-start gap-4"> <div className="flex items-start gap-4">
<div className="p-3 bg-primary/10 rounded-sm shrink-0"> <div className="p-3 bg-primary/10 rounded-sm shrink-0">
<Brain className="h-6 w-6 text-primary" /> <Brain className="h-6 w-6 text-primary" />
</div> </div>
<div> <div>
<h3 className="text-sm font-semibold text-primary mb-1 flex items-center gap-2"> <h3 className="text-sm font-semibold text-primary mb-1 flex items-center gap-2">
AI Task Prioritization AI Priority Engine
</h3> </h3>
<p className="text-xs text-foreground/80 leading-relaxed max-w-2xl"> <p className="text-xs text-foreground/80 leading-relaxed max-w-2xl">
Based on the upcoming <strong>Infrastructure</strong> deadlines and <strong>Alex R.</strong>'s historical velocity, AI strongly suggests starting the <em>Database Migration Script</em> immediately. It has a high risk of cascading delays. Based on deadlines and team velocity, I've identified 3 tasks that need immediate focus. Auto-sort will reorder your backlog for maximum strategic impact.
</p> </p>
</div> </div>
</div> </div>
<button className="bg-primary/20 text-primary hover:bg-primary/30 border border-primary/30 px-4 py-2 rounded-sm text-xs font-semibold transition-colors shrink-0"> <button
Auto-Sort Backlog onClick={handleAutoSort}
disabled={isSorting}
className={`min-w-[140px] px-4 py-2 rounded-sm text-xs font-bold uppercase tracking-widest transition-all shadow-lg ${isSorting ? 'bg-emerald-500/20 text-emerald-400 border border-emerald-500/30' : 'bg-primary/10 text-primary border border-primary/30 hover:bg-primary/20'}`}
>
{isSorting ? "SORTING..." : "AUTO-SORT BACKLOG"}
</button> </button>
</div> </div>
{/* Task List Header */} {/* View Toggle */}
<div className="flex items-center justify-between mt-2"> <div className="flex items-center justify-between shrink-0">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2 bg-[#150F1D] border border-white/5 rounded-sm p-0.5">
<button className="px-3 py-1.5 text-xs font-medium rounded-sm bg-[#2B2538] text-foreground shadow-sm">List View</button> <button
<button className="px-3 py-1.5 text-xs font-medium rounded-sm text-muted-foreground hover:text-foreground transition-colors">Kanban Board</button> onClick={() => setViewMode("list")}
className={`px-3 py-1.5 text-[10px] font-bold uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'list' ? 'bg-[#2B2538] text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}`}
>
<List className="h-3 w-3" /> List View
</button>
<button
onClick={() => setViewMode("kanban")}
className={`px-3 py-1.5 text-[10px] font-bold uppercase tracking-widest rounded-sm transition-all flex items-center gap-2 ${viewMode === 'kanban' ? 'bg-[#2B2538] text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}`}
>
<Layout className="h-3 w-3" /> Kanban Board
</button>
</div>
<div className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground">
{tasks.length} Active Tasks
</div> </div>
<div className="text-xs text-muted-foreground font-medium">12 Active Tasks</div>
</div> </div>
{/* Tasks Table */} <div className="flex-1 min-h-0 overflow-hidden">
<div className="bg-[#0A0710] rounded-sm border border-white/5 overflow-hidden flex-1"> {viewMode === "list" ? (
<div className="grid grid-cols-12 gap-4 p-4 border-b border-white/5 bg-[#0F0B15]/50 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground"> <div className="bg-[#0A0710] rounded-sm border border-white/5 overflow-hidden flex flex-col h-full">
<div className="col-span-5">Task Details</div> <div className="grid grid-cols-12 gap-4 p-4 border-b border-white/5 bg-[#0F0B15]/50 text-[10px] font-bold uppercase tracking-widest text-muted-foreground shrink-0">
<div className="col-span-2">Status</div> <div className="col-span-5">Task Details</div>
<div className="col-span-2">Assignee</div> <div className="col-span-2">Status</div>
<div className="col-span-2">AI Time Estimate</div> <div className="col-span-2">Assignee</div>
<div className="col-span-1 text-right">Actions</div> <div className="col-span-2">AI Time Est.</div>
</div> <div className="col-span-1 text-right">Actions</div>
<div className="divide-y divide-white/5">
{tasks.map((task) => (
<div key={task.id} className="grid grid-cols-12 gap-4 p-4 items-center hover:bg-white/[0.02] transition-colors group">
{/* Task Details */}
<div className="col-span-5 flex items-start gap-3">
<button className="mt-0.5 text-muted-foreground hover:text-primary transition-colors">
{task.status === "Done" ? <CheckCircle2 className="h-4 w-4 text-emerald-400" /> : <CheckSquare2 className="h-4 w-4" />}
</button>
<div>
<div className={`text-sm font-medium mb-1 ${task.status === 'Done' ? 'text-muted-foreground line-through' : 'text-foreground'}`}>
{task.title}
</div>
<div className="flex items-center gap-2">
<span className="text-[10px] text-muted-foreground font-medium bg-[#150F1D] px-2 py-0.5 rounded-sm border border-white/5">
{task.project}
</span>
<span className={`text-[10px] uppercase font-bold tracking-wider flex items-center gap-1 ${
task.priority === 'Critical' ? 'text-red-400' :
task.priority === 'High' ? 'text-orange-400' :
task.priority === 'Medium' ? 'text-blue-400' : 'text-muted-foreground'
}`}>
{task.priority === 'Critical' && <AlertCircle className="h-3 w-3" />}
{task.priority}
</span>
</div>
</div>
</div>
{/* Status */}
<div className="col-span-2">
<span className={`text-[10px] uppercase font-bold px-2 py-1 rounded-sm border inline-block ${
task.status === 'In Progress' ? 'bg-blue-500/10 text-blue-400 border-blue-500/20' :
task.status === 'Review' ? 'bg-orange-500/10 text-orange-400 border-orange-500/20' :
task.status === 'Done' ? 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20' :
'bg-white/5 text-muted-foreground border-white/10'
}`}>
{task.status}
</span>
</div>
{/* Assignee */}
<div className="col-span-2 flex items-center gap-2">
<div className="h-6 w-6 rounded-sm bg-[#1F172B] border border-white/10 flex items-center justify-center text-[10px] font-bold text-primary">
{task.assignee.split(' ')[0][0]}{task.assignee.split(' ')[1][0]}
</div>
<span className="text-xs text-muted-foreground">{task.assignee}</span>
</div>
{/* AI Estimate */}
<div className="col-span-2 flex items-center gap-2">
{task.status !== 'Done' && <Clock className="h-3.5 w-3.5 text-primary" />}
<span className={`text-xs ${task.status === 'Done' ? 'text-emerald-400 font-medium' : 'text-muted-foreground'}`}>
{task.aiPredict}
</span>
</div>
{/* Actions */}
<div className="col-span-1 flex justify-end gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="p-1.5 hover:bg-white/10 rounded-sm text-muted-foreground hover:text-foreground transition-colors">
<MessageSquare className="h-4 w-4" />
</button>
<button className="p-1.5 hover:bg-white/10 rounded-sm text-muted-foreground hover:text-foreground transition-colors">
<MoreHorizontal className="h-4 w-4" />
</button>
</div>
</div> </div>
))}
</div> <div className="flex-1 overflow-y-auto tiny-scrollbar">
<Reorder.Group axis="y" values={tasks} onReorder={setTasks} className="divide-y divide-white/5">
{tasks.map((task) => (
<Reorder.Item
key={task.id}
value={task}
onClick={() => setSelectedTask(task)}
className="grid grid-cols-12 gap-4 p-4 items-center hover:bg-white/[0.02] transition-colors group cursor-pointer"
>
<div className="col-span-5 flex items-start gap-3">
<GripVertical className="h-4 w-4 text-muted-foreground/30 mt-1 opacity-0 group-hover:opacity-100 transition-opacity" />
<div className="flex-1 min-w-0">
<div className={`text-sm font-medium mb-1 truncate ${task.status === 'Done' ? 'text-muted-foreground line-through' : 'text-foreground'}`}>
{task.title}
</div>
<div className="flex items-center gap-2">
<span className="text-[10px] text-muted-foreground font-bold bg-[#150F1D] px-2 py-0.5 rounded-sm border border-white/5">{task.project}</span>
<span className={`text-[10px] uppercase font-black tracking-widest flex items-center gap-1 ${task.priority === 'Critical' ? 'text-red-400' : task.priority === 'High' ? 'text-orange-400' : 'text-blue-400'}`}>
{task.priority}
</span>
</div>
</div>
</div>
<div className="col-span-2">
<span className={`text-[9px] uppercase font-black px-2 py-1 rounded-sm border inline-block tracking-widest ${task.status === 'In Progress' ? 'bg-blue-500/10 text-blue-400 border-blue-500/20' : task.status === 'Review' ? 'bg-orange-500/10 text-orange-400 border-orange-500/20' : task.status === 'Done' ? 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20' : 'bg-white/5 text-muted-foreground border-white/10'}`}>
{task.status}
</span>
</div>
<div className="col-span-2 flex items-center gap-2">
<div className="h-6 w-6 rounded-sm bg-[#1F172B] border border-primary/20 flex items-center justify-center text-[10px] font-black text-primary uppercase">
{task.assignee.split(' ').map(n => n[0]).join('')}
</div>
<span className="text-xs text-muted-foreground truncate">{task.assignee}</span>
</div>
<div className="col-span-2 flex items-center gap-2">
<Clock className="h-3.5 w-3.5 text-primary opacity-50" />
<span className="text-xs text-muted-foreground">{task.aiPredict}</span>
</div>
<div className="col-span-1 flex justify-end gap-1">
<button className="p-1.5 hover:bg-white/10 rounded-sm text-muted-foreground transition-colors"><MoreHorizontal className="h-4 w-4" /></button>
</div>
</Reorder.Item>
))}
</Reorder.Group>
</div>
</div>
) : (
<div className="grid grid-cols-4 gap-6 h-full overflow-x-auto pb-4 tiny-scrollbar">
{columns.map((col) => (
<div key={col} className="flex flex-col gap-4 min-w-[280px]">
<div className="flex items-center justify-between px-2">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-muted-foreground">{col}</h3>
<span className="text-[10px] font-bold bg-white/5 px-2 py-0.5 rounded-sm">{tasks.filter(t => t.status === col).length}</span>
</div>
<div className="flex-1 bg-white/[0.02] border border-white/5 rounded-sm p-3 space-y-3 overflow-y-auto tiny-scrollbar">
{tasks.filter(t => t.status === col).map(task => (
<motion.div
key={task.id}
layoutId={task.id}
onClick={() => setSelectedTask(task)}
className="bg-[#0A0710] border border-white/5 rounded-sm p-4 hover:border-primary/30 transition-all cursor-pointer group shadow-xl"
>
<div className="text-xs font-bold mb-3 group-hover:text-primary transition-colors leading-relaxed">{task.title}</div>
<div className="flex items-center justify-between">
<span className={`text-[8px] font-black uppercase tracking-widest px-1.5 py-0.5 rounded-sm border ${task.priority === 'Critical' ? 'bg-red-500/10 text-red-400 border-red-500/20' : 'bg-white/5 text-muted-foreground border-white/10'}`}>
{task.priority}
</span>
<div className="h-5 w-5 rounded-sm bg-[#1F172B] border border-white/10 flex items-center justify-center text-[8px] font-black text-primary">
{task.assignee.split(' ').map(n => n[0]).join('')}
</div>
</div>
</motion.div>
))}
<button className="w-full py-2 border border-dashed border-white/10 rounded-sm text-[10px] font-bold text-muted-foreground hover:bg-white/5 hover:border-white/20 transition-all">
+ ADD TASK
</button>
</div>
</div>
))}
</div>
)}
</div> </div>
{/* Task Detail Sheet */}
<AnimatePresence>
{selectedTask && (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedTask(null)} className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[100]" />
<motion.div initial={{ x: "100%" }} animate={{ x: 0 }} exit={{ x: "100%" }} transition={{ type: "spring", damping: 25, stiffness: 200 }} className="fixed top-0 right-0 h-full w-full max-w-lg bg-[#0A0710] border-l border-white/5 z-[101] shadow-2xl flex flex-col">
<div className="p-8 border-b border-white/5 flex items-center justify-between bg-[#0F0B15]/50">
<div className="space-y-1">
<div className="flex items-center gap-2">
<span className="text-[10px] font-black uppercase tracking-widest bg-primary/20 text-primary px-2 py-0.5 rounded-sm">{selectedTask.project}</span>
<span className="text-[10px] font-bold text-muted-foreground">ID: #TSK-{selectedTask.id}</span>
</div>
<h2 className="text-xl font-black tracking-tight">{selectedTask.title}</h2>
</div>
<button onClick={() => setSelectedTask(null)} className="p-2 hover:bg-white/5 rounded-sm text-muted-foreground transition-colors"><X className="h-5 w-5" /></button>
</div>
<div className="flex-1 overflow-y-auto p-8 space-y-10 tiny-scrollbar">
<div className="grid grid-cols-2 gap-8">
<DetailItem label="ASSIGNEE" icon={User} value={selectedTask.assignee} />
<DetailItem label="DUE DATE" icon={Calendar} value={selectedTask.dueDate} />
<DetailItem label="PRIORITY" icon={AlertCircle} value={selectedTask.priority} />
<DetailItem label="AI ESTIMATE" icon={Brain} value={selectedTask.aiPredict} color="text-primary" />
</div>
<div className="space-y-4">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Description</h3>
<p className="text-sm text-muted-foreground leading-relaxed">
This task is part of the strategic {selectedTask.project} roadmap. Please ensure all design tokens are verified against the core Cognis design system before final review.
</p>
</div>
<div className="space-y-4 pt-8 border-t border-white/5">
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Subtasks</h3>
<div className="space-y-2">
{[1, 2, 3].map(i => (
<div key={i} className="flex items-center gap-3 p-3 rounded-sm bg-[#150F1D] border border-white/5 hover:border-white/10 transition-colors">
<div className="w-4 h-4 rounded-sm border border-white/20 flex items-center justify-center cursor-pointer hover:border-primary transition-colors">
<CheckSquare2 className="h-3 w-3 text-transparent hover:text-muted-foreground transition-colors" />
</div>
<span className="text-xs text-muted-foreground">Verification step {i} for the migration script.</span>
</div>
))}
</div>
</div>
</div>
<div className="p-8 border-t border-white/5 bg-[#0F0B15]/50 flex gap-4">
<button className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground py-3 rounded-sm text-[10px] font-black uppercase tracking-widest shadow-lg shadow-primary/20 transition-all active:scale-[0.98]">
MARK AS DONE
</button>
<button className="p-3 border border-white/10 rounded-sm text-muted-foreground hover:bg-white/5 transition-colors">
<MessageSquare className="h-5 w-5" />
</button>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}
function DetailItem({ label, icon: Icon, value, color = "text-muted-foreground" }: any) {
return (
<div className="space-y-2">
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground/50">{label}</div>
<div className="flex items-center gap-2">
<Icon className={`h-4 w-4 ${color}`} />
<span className={`text-sm font-bold ${color === 'text-primary' ? 'text-primary' : 'text-foreground'}`}>{value}</span>
</div>
</div> </div>
); );
} }
+251
View File
@@ -0,0 +1,251 @@
"use client";
import { useState, useEffect } from "react";
import {
Play, Pause, Square, Plus, Search, Clock,
BarChart3, Calendar, MoreHorizontal, X,
CheckCircle2, AlertCircle, Brain, Zap,
TrendingUp, Activity, Briefcase, User
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
import {
ResponsiveContainer, PieChart, Pie, Cell, Tooltip,
BarChart, Bar, XAxis, YAxis, CartesianGrid
} from "recharts";
// Mock Data
const todayTimeData = [
{ name: "Deep Work", value: 240, color: "#6C5BB0" },
{ name: "Meetings", value: 90, color: "#a798e8" },
{ name: "Learning", value: 45, color: "#10b981" },
{ name: "Admin", value: 30, color: "#3b82f6" },
];
const weeklyTimeData = [
{ day: "Mon", hours: 8.5 },
{ day: "Tue", hours: 7.2 },
{ day: "Wed", hours: 9.0 },
{ day: "Thu", hours: 6.5 },
{ day: "Fri", hours: 8.0 },
{ day: "Sat", hours: 2.5 },
{ day: "Sun", hours: 0 },
];
const recentLogs = [
{ id: 1, task: "Database Migration Script", project: "Infrastructure", duration: "2h 15m", date: "Today, 10:30 AM", type: "Deep Work" },
{ id: 2, task: "UI Review & Polish", project: "Marketing Site", duration: "1h 45m", date: "Today, 02:00 PM", type: "Creative" },
{ id: 3, task: "Client Strategy Sync", project: "Acme Corp", duration: "1h 00m", date: "Yesterday", type: "Meeting" },
{ id: 4, task: "Security Audit", project: "Infrastructure", duration: "3h 30m", date: "Yesterday", type: "Deep Work" },
];
export default function TimeTrackingPage() {
const [isActive, setIsActive] = useState(false);
const [seconds, setSeconds] = useState(0);
useEffect(() => {
let interval: any = null;
if (isActive) {
interval = setInterval(() => {
setSeconds((seconds) => seconds + 1);
}, 1000);
} else if (!isActive && seconds !== 0) {
clearInterval(interval);
}
return () => clearInterval(interval);
}, [isActive, seconds]);
const formatTime = (totalSeconds: number) => {
const h = Math.floor(totalSeconds / 3600);
const m = Math.floor((totalSeconds % 3600) / 60);
const s = totalSeconds % 60;
return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
};
return (
<div className="mx-auto max-w-7xl animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col text-foreground font-sans space-y-6 pb-12 relative">
{/* Top Header */}
<div className="flex items-center justify-between pb-4 border-b border-white/5 mt-4 shrink-0">
<div className="flex items-center gap-4">
<h1 className="text-lg font-medium text-muted-foreground">
<span className="text-foreground">Performance</span> / Time Intelligence
</h1>
<div className="h-4 w-px bg-white/10" />
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-primary bg-primary/5 px-3 py-1 rounded-sm border border-primary/10">
<Clock className="h-3 w-3" /> 38.5 HOURS LOGGED THIS WEEK
</div>
</div>
<div className="flex items-center gap-3">
<button className="bg-[#150F1D] hover:bg-white/5 text-foreground border border-white/10 px-4 py-1.5 rounded-sm text-xs font-bold tracking-widest flex items-center gap-2 transition-all">
<Plus className="h-4 w-4" />
MANUAL LOG
</button>
</div>
</div>
{/* Main Content Grid */}
<div className="grid grid-cols-1 xl:grid-cols-3 gap-8 flex-1 min-h-0">
{/* Left: Active Timer & Recent Logs */}
<div className="xl:col-span-2 flex flex-col gap-8 overflow-hidden">
{/* Active Timer Attraction */}
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-10 flex flex-col items-center justify-center relative overflow-hidden shadow-2xl group">
<div className={`absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(108,91,176,0.05),transparent)] transition-opacity ${isActive ? 'opacity-100' : 'opacity-0'}`} />
<div className="flex flex-col items-center gap-8 relative z-10 w-full max-w-md">
<div className="text-center space-y-2">
<div className="text-[10px] font-black uppercase tracking-[0.4em] text-primary animate-pulse">Current Focus Block</div>
<h2 className="text-6xl font-black tracking-tighter tabular-nums text-foreground">{formatTime(seconds)}</h2>
</div>
<div className="w-full space-y-4">
<div className="flex items-center gap-4 bg-[#150F1D] border border-white/10 rounded-sm px-6 py-4">
<div className="p-2 bg-primary/10 rounded-sm"><Briefcase className="h-4 w-4 text-primary" /></div>
<div className="flex-1">
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground">Project</div>
<div className="text-sm font-bold">Marketing Site Redesign</div>
</div>
<div className="h-8 w-px bg-white/5" />
<div className="flex-1 text-right">
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground">Task</div>
<div className="text-sm font-bold truncate">UI Audit & Review</div>
</div>
</div>
<div className="flex gap-4">
<button
onClick={() => setIsActive(!isActive)}
className={`flex-1 flex items-center justify-center gap-3 py-4 rounded-sm text-sm font-black uppercase tracking-widest transition-all shadow-xl ${isActive ? 'bg-orange-500/10 text-orange-500 border border-orange-500/20' : 'bg-primary text-primary-foreground shadow-primary/20'}`}
>
{isActive ? <><Pause className="h-5 w-5" /> PAUSE TIMER</> : <><Play className="h-5 w-5" /> START FOCUS</>}
</button>
<button
onClick={() => {setIsActive(false); setSeconds(0);}}
className="px-8 bg-white/5 border border-white/10 text-muted-foreground hover:bg-white/10 transition-all rounded-sm"
>
<Square className="h-5 w-5" />
</button>
</div>
</div>
</div>
</div>
{/* Recent Logs Table */}
<div className="bg-[#0A0710] border border-white/5 rounded-sm flex-1 flex flex-col overflow-hidden shadow-2xl">
<div className="p-6 border-b border-white/5 bg-[#0F0B15]/40 flex justify-between items-center">
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground">Today's Activity Ledger</h3>
<button className="text-[10px] font-bold text-primary uppercase tracking-widest">Full History</button>
</div>
<div className="flex-1 overflow-y-auto tiny-scrollbar">
<div className="divide-y divide-white/5">
{recentLogs.map(log => (
<div key={log.id} className="grid grid-cols-12 gap-4 p-5 items-center hover:bg-white/[0.02] transition-all group">
<div className="col-span-5 flex items-center gap-4">
<div className="h-10 w-10 rounded-sm bg-white/5 flex items-center justify-center"><Clock className="h-5 w-5 text-muted-foreground group-hover:text-primary transition-colors" /></div>
<div className="min-w-0">
<div className="text-sm font-black truncate">{log.task}</div>
<div className="text-[9px] text-muted-foreground font-bold uppercase tracking-widest mt-1">{log.project} • {log.type}</div>
</div>
</div>
<div className="col-span-3 text-xs font-black text-muted-foreground uppercase">{log.date}</div>
<div className="col-span-2 text-sm font-black text-foreground">{log.duration}</div>
<div className="col-span-2 flex justify-end gap-1 opacity-0 group-hover:opacity-100 transition-all">
<button className="p-2 hover:bg-white/10 rounded-sm text-muted-foreground"><MoreHorizontal className="h-4 w-4" /></button>
</div>
</div>
))}
</div>
</div>
</div>
</div>
{/* Right: Analytics & AI */}
<div className="flex flex-col gap-8">
{/* Daily Distribution Chart */}
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex flex-col shadow-2xl">
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground mb-8">Daily Distribution</h3>
<div className="h-48 w-full flex items-center justify-center">
<ResponsiveContainer width="100%" height="100%">
<PieChart>
<Pie
data={todayTimeData}
cx="50%"
cy="50%"
innerRadius={50}
outerRadius={80}
paddingAngle={4}
dataKey="value"
stroke="none"
>
{todayTimeData.map((entry, index) => (
<Cell key={index} fill={entry.color} />
))}
</Pie>
<Tooltip contentStyle={{ backgroundColor: "#150F1D", border: "none" }} />
</PieChart>
</ResponsiveContainer>
</div>
<div className="mt-8 space-y-3">
{todayTimeData.map(item => (
<div key={item.name} className="flex justify-between items-center text-[10px] font-black uppercase tracking-widest">
<div className="flex items-center gap-3">
<div className="w-2 h-2 rounded-full" style={{ backgroundColor: item.color }} />
<span className="text-muted-foreground">{item.name}</span>
</div>
<span>{Math.floor(item.value / 60)}h {item.value % 60}m</span>
</div>
))}
</div>
</div>
{/* AI Productivity Pulse */}
<div className="bg-primary/5 border border-primary/20 rounded-sm p-8 flex flex-col gap-6 relative overflow-hidden group">
<div className="absolute -right-4 -top-4 opacity-5 rotate-12 transition-transform group-hover:scale-110">
<Brain className="h-24 w-24 text-primary" />
</div>
<div className="space-y-4 relative z-10">
<div className="flex items-center gap-3">
<div className="p-2 bg-primary/20 rounded-sm shadow-inner"><Brain className="h-4 w-4 text-primary" /></div>
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-primary">Focus Analysis</h3>
</div>
<p className="text-sm font-bold leading-relaxed text-foreground/90 italic">
"Your deep work output is highest between 9:00 AM and 11:30 AM. Weekly burnout risk is Low (12%). Strategic momentum is positive."
</p>
</div>
<button className="text-[10px] font-black text-primary uppercase tracking-widest flex items-center gap-2 group/btn border-b border-primary/20 pb-1 self-start hover:border-primary transition-all">
VIEW BURN RATE <ArrowRight className="h-3 w-3 group-hover/btn:translate-x-1 transition-transform" />
</button>
</div>
{/* Weekly Summary Stat */}
<div className="bg-[#0A0710] border border-white/5 rounded-sm p-8 flex flex-col gap-6 shadow-2xl">
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground">Weekly Performance</h3>
<div className="h-32 w-full">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={weeklyTimeData}>
<Bar dataKey="hours" fill="#6C5BB0" radius={[2, 2, 0, 0]} />
<Tooltip cursor={{ fill: '#ffffff05' }} contentStyle={{ backgroundColor: "#150F1D", border: "none" }} />
</BarChart>
</ResponsiveContainer>
</div>
<div className="flex justify-between items-end">
<div>
<div className="text-[10px] font-black uppercase tracking-widest text-muted-foreground mb-1">Average / Day</div>
<div className="text-2xl font-black">7.4h</div>
</div>
<div className="text-right">
<div className="text-emerald-500 flex items-center gap-1 text-[10px] font-black uppercase tracking-widest">
<TrendingUp className="h-3 w-3" /> +12% VS LAST WEEK
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}