// src/App.tsx // =================================================================== // COMPLETE NORTHWIND TEAMS APPLICATION // Single-file implementation (React + TanStack Router + Tailwind) // =================================================================== import React, { useState } from "react"; import { Activity, Bell, Calendar, CalendarDays, CalendarPlus, Check, CheckCheck, ChevronLeft, ChevronRight, Circle, Copy, FileText, FolderClosed, FolderPlus, Forward, Hand, Hash, Image as ImageIcon, KeyRound, Link as LinkIcon, Lock, LogOut, Mail, Menu, MessageSquare, Mic, MicOff, MonitorUp, MoreHorizontal, Palette, Paperclip, Pencil, Phone, PhoneOff, Pin, Play, Plus, Presentation, Reply, Search, Send, Settings, Shield, Smile, Sparkles, Trash2, Upload, UserPlus, Users, Video, VideoOff, Vote, Eye, EyeOff, Download, Share2, Star, Flag, CalendarClock, PhoneMissed, ArrowDownLeft, ArrowUpRight, Camera, ArrowRight, Settings2 } from "lucide-react"; import { Area, AreaChart, Bar, BarChart, CartesianGrid, Cell, Line, LineChart, Pie, PieChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts"; // VideoIcon is used as a distinct alias for the "camera on" state icon // elsewhere in this file β€” lucide-react only exports it as `Video`. const VideoIcon = Video; // =================================================================== // 1. MOCK DATA // =================================================================== export const currentUser = { id: "u1", name: "Aarav Mehta", initials: "AM", email: "aarav@northwind.io", role: "Lead Product Manager", department: "Product", presence: "online", favorite: true, }; export const people = [ { id: "u1", name: "Aarav Mehta", initials: "AM", email: "aarav@northwind.io", role: "Lead Product Manager", department: "Product", presence: "online", favorite: true }, { id: "u2", name: "Priya Nair", initials: "PN", email: "priya@northwind.io", role: "Engineering Manager", department: "Engineering", presence: "online" }, { id: "u3", name: "Sofia Rossi", initials: "SR", email: "sofia@northwind.io", role: "Lead Designer", department: "Design", presence: "busy" }, { id: "u4", name: "Kenji Watanabe", initials: "KW", email: "kenji@northwind.io", role: "Data Analyst", department: "Product", presence: "away", favorite: true }, { id: "u5", name: "Amara Diallo", initials: "AD", email: "amara@northwind.io", role: "Customer Success", department: "Sales", presence: "online" }, { id: "u6", name: "Daniel Osei", initials: "DO", email: "daniel@northwind.io", role: "Senior Engineer", department: "Engineering", presence: "online" }, { id: "u7", name: "Liam O'Connor", initials: "LO", email: "liam@northwind.io", role: "DevOps Engineer", department: "Engineering", presence: "offline" }, { id: "u8", name: "Hannah Blum", initials: "HB", email: "hannah@northwind.io", role: "Marketing Manager", department: "Marketing", presence: "offline" }, { id: "u9", name: "Marco Silva", initials: "MS", email: "marco@northwind.io", role: "VP of Sales", department: "Sales", presence: "busy", favorite: true }, ]; export const presenceLabel = { online: "Online", busy: "Busy", away: "Away", offline: "Offline", }; export const teams = [ { id: "t1", name: "Product Core", description: "Roadmap, discovery and release planning", visibility: "Private", members: 24, channels: ["General", "Roadmap", "Release 4.2", "Design reviews"], files: 148, meetings: 62, color: "oklch(0.583 0.183 268.5)" }, { id: "t2", name: "Platform Engineering", description: "Services, infra and reliability", visibility: "Private", members: 31, channels: ["General", "Incidents", "Deploys", "RFCs"], files: 402, meetings: 118, color: "oklch(0.442 0.132 262)" }, { id: "t3", name: "Design Studio", description: "Brand, product and systems design", visibility: "Public", members: 12, channels: ["General", "Critique", "Design system"], files: 97, meetings: 40, color: "oklch(0.7 0.13 200)" }, { id: "t4", name: "Go To Market", description: "Campaigns, launches and enablement", visibility: "Public", members: 18, channels: ["General", "Launches", "Content"], files: 63, meetings: 51, color: "oklch(0.63 0.15 155)" }, ]; export const conversations = [ { id: "c1", name: "Priya Nair", kind: "dm", preview: "Pushed the fix β€” can you re-check staging?", time: "09:41", unread: 2, presence: "online", initials: "PN" }, { id: "c2", name: "Release 4.2", kind: "channel", teamName: "Product Core", preview: "Sofia: Final specs are attached here.", time: "09:12", unread: 5, initials: "R4" }, { id: "c3", name: "Design Sync", kind: "group", preview: "Kenji: Numbers look good for the pilot.", time: "Yesterday", unread: 0, initials: "DS" }, { id: "c4", name: "Sofia Rossi", kind: "dm", preview: "Sent over the updated component sheet.", time: "Yesterday", unread: 0, presence: "busy", initials: "SR" }, { id: "c5", name: "Incidents", kind: "channel", teamName: "Platform Engineering", preview: "Daniel: All clear, latency back to normal.", time: "Mon", unread: 0, initials: "IN" }, { id: "c6", name: "Amara Diallo", kind: "dm", preview: "Customer asked about the export feature.", time: "Mon", unread: 0, presence: "online", initials: "AD" }, ]; export const messages = [ { id: "m1", author: "Priya Nair", initials: "PN", time: "09:02", body: "Morning! I merged the presence refactor overnight. Staging should be stable now.", reactions: [{ emoji: "πŸ‘", count: 3 }], pinned: true }, { id: "m2", author: "Aarav Mehta", initials: "AM", time: "09:05", body: "Nice. I'll run through the meeting flows before standup.", self: true, read: true }, { id: "m3", author: "Sofia Rossi", initials: "SR", time: "09:18", body: "Here's the updated spec with the new gallery view states.", attachment: { name: "meeting-gallery-spec-v4.pdf", size: "2.4 MB" } }, { id: "m4", author: "Aarav Mehta", initials: "AM", time: "09:20", body: "Perfect timing β€” sharing with the platform crew.", self: true, edited: true, read: true }, { id: "m5", author: "Priya Nair", initials: "PN", time: "09:41", body: "Pushed the fix β€” can you re-check staging?", reactions: [{ emoji: "πŸš€", count: 2 }, { emoji: "πŸŽ‰", count: 1 }] }, ]; export const meetings = [ { id: "mt1", title: "Daily standup β€” Product Core", time: "10:00", day: "Today", duration: "15 min", organizer: "Priya Nair", attendees: ["PN", "SR", "DO", "KW"], status: "live" }, { id: "mt2", title: "Release 4.2 go/no-go", time: "13:30", day: "Today", duration: "45 min", organizer: "Aarav Mehta", attendees: ["AM", "PN", "MS", "HB", "LO"], status: "upcoming" }, { id: "mt3", title: "Design critique", time: "16:00", day: "Today", duration: "60 min", organizer: "Sofia Rossi", attendees: ["SR", "AM", "AD"], status: "upcoming" }, { id: "mt4", title: "Quarterly business review", time: "09:30", day: "Tomorrow", duration: "90 min", organizer: "Marco Silva", attendees: ["MS", "AM", "HB", "PN", "KW", "AD"], status: "upcoming" }, { id: "mt5", title: "Incident retro β€” API latency", time: "15:00", day: "Yesterday", duration: "30 min", organizer: "Daniel Osei", attendees: ["DO", "PN", "LO"], status: "past", recorded: true }, { id: "mt6", title: "Customer advisory call", time: "11:00", day: "Yesterday", duration: "45 min", organizer: "Amara Diallo", attendees: ["AD", "AM"], status: "past", recorded: true }, ]; export const files = [ { id: "f1", name: "Release 4.2", kind: "folder", owner: "Priya Nair", modified: "Today, 09:12", size: "β€”", shared: 12 }, { id: "f2", name: "Design system", kind: "folder", owner: "Sofia Rossi", modified: "Yesterday", size: "β€”", shared: 9 }, { id: "f3", name: "meeting-gallery-spec-v4.pdf", kind: "pdf", owner: "Sofia Rossi", modified: "Today, 09:18", size: "2.4 MB", shared: 5 }, { id: "f4", name: "Q3 roadmap.docx", kind: "doc", owner: "Aarav Mehta", modified: "Today, 08:02", size: "820 KB", shared: 18 }, { id: "f5", name: "Adoption metrics.xlsx", kind: "sheet", owner: "Kenji Watanabe", modified: "Yesterday", size: "1.1 MB", shared: 7 }, { id: "f6", name: "Launch deck.pptx", kind: "slide", owner: "Hannah Blum", modified: "Mon", size: "14.2 MB", shared: 22 }, { id: "f7", name: "onboarding-flow.png", kind: "image", owner: "Sofia Rossi", modified: "Mon", size: "640 KB", shared: 4 }, ]; export const tasks = [ { id: "k1", title: "Finalize release notes for 4.2", scope: "Team", team: "Product Core", due: "Today", priority: "Urgent", status: "In progress", progress: 70, assignee: "AM" }, { id: "k2", title: "Review gallery view spec", scope: "Personal", due: "Today", priority: "High", status: "To do", progress: 0, assignee: "AM" }, { id: "k3", title: "Patch presence websocket reconnect", scope: "Team", team: "Platform Engineering", due: "Tomorrow", priority: "High", status: "In progress", progress: 45, assignee: "DO" }, { id: "k4", title: "Refresh onboarding illustrations", scope: "Team", team: "Design Studio", due: "Fri", priority: "Medium", status: "To do", progress: 10, assignee: "SR" }, { id: "k5", title: "Prepare QBR deck", scope: "Personal", due: "Fri", priority: "Medium", status: "In progress", progress: 30, assignee: "AM" }, { id: "k6", title: "Archive Q2 meeting recordings", scope: "Team", team: "Platform Engineering", due: "Done", priority: "Low", status: "Done", progress: 100, assignee: "LO" }, ]; export const notifications = [ { id: "n1", kind: "meeting", title: "Release 4.2 go/no-go", detail: "Starts in 40 minutes", time: "now", unread: true }, { id: "n2", kind: "message", title: "Priya Nair mentioned you", detail: "\"@Aarav can you re-check staging?\"", time: "12m", unread: true }, { id: "n3", kind: "file", title: "New file in Release 4.2", detail: "Sofia uploaded meeting-gallery-spec-v4.pdf", time: "38m", unread: true }, { id: "n4", kind: "team", title: "Team invitation", detail: "Go To Market invited you to join", time: "2h", unread: false }, { id: "n5", kind: "task", title: "Task due today", detail: "Finalize release notes for 4.2", time: "3h", unread: false }, ]; export const activity = [ { id: "a1", actor: "Sofia Rossi", initials: "SR", action: "uploaded a file to", target: "Release 4.2", time: "38m ago" }, { id: "a2", actor: "Daniel Osei", initials: "DO", action: "closed the incident in", target: "Platform Engineering", time: "1h ago" }, { id: "a3", actor: "Hannah Blum", initials: "HB", action: "scheduled a meeting in", target: "Go To Market", time: "2h ago" }, { id: "a4", actor: "Kenji Watanabe", initials: "KW", action: "commented on", target: "Adoption metrics.xlsx", time: "3h ago" }, { id: "a5", actor: "Priya Nair", initials: "PN", action: "added 2 members to", target: "Product Core", time: "5h ago" }, ]; export const callHistory = [ { id: "cl1", name: "Priya Nair", initials: "PN", type: "Video", direction: "Outgoing", time: "Today, 08:40", duration: "12 min" }, { id: "cl2", name: "Design Sync", initials: "DS", type: "Audio", direction: "Incoming", time: "Yesterday, 17:05", duration: "34 min" }, { id: "cl3", name: "Marco Silva", initials: "MS", type: "Audio", direction: "Missed", time: "Yesterday, 14:22", duration: "β€”" }, { id: "cl4", name: "Amara Diallo", initials: "AD", type: "Video", direction: "Incoming", time: "Mon, 11:10", duration: "22 min" }, ]; export const adminStats = [ { label: "Total users", value: "1,284", delta: "+42 this month" }, { label: "Active users", value: "912", delta: "71% of workspace" }, { label: "Meetings today", value: "186", delta: "+18% vs. yesterday" }, { label: "Messages sent", value: "48.2k", delta: "last 7 days" }, { label: "Files uploaded", value: "3,401", delta: "+126 today" }, { label: "Teams created", value: "94", delta: "+6 this month" }, ]; export const dauSeries = [ { day: "Mon", users: 720 }, { day: "Tue", users: 810 }, { day: "Wed", users: 865 }, { day: "Thu", users: 912 }, { day: "Fri", users: 848 }, { day: "Sat", users: 320 }, { day: "Sun", users: 288 }, ]; export const meetingSeries = [ { month: "Jan", meetings: 1240 }, { month: "Feb", meetings: 1380 }, { month: "Mar", meetings: 1610 }, { month: "Apr", meetings: 1520 }, { month: "May", meetings: 1740 }, { month: "Jun", meetings: 1980 }, ]; export const chatSeries = [ { day: "Mon", messages: 6200 }, { day: "Tue", messages: 7100 }, { day: "Wed", messages: 7650 }, { day: "Thu", messages: 8120 }, { day: "Fri", messages: 7380 }, { day: "Sat", messages: 1720 }, { day: "Sun", messages: 1410 }, ]; export const storageSeries = [ { name: "Documents", value: 42 }, { name: "Recordings", value: 28 }, { name: "Images", value: 18 }, { name: "Other", value: 12 }, ]; export const activityLogs = [ { id: "l1", actor: "priya@northwind.io", action: "team.member.added", target: "Product Core", ip: "10.4.22.8", time: "Today, 09:44" }, { id: "l2", actor: "daniel@northwind.io", action: "meeting.recording.deleted", target: "Incident retro", ip: "10.4.19.2", time: "Today, 08:58" }, { id: "l3", actor: "aarav@northwind.io", action: "role.updated", target: "hannah@northwind.io", ip: "10.4.31.7", time: "Yesterday, 18:20" }, { id: "l4", actor: "system", action: "storage.quota.warning", target: "Platform Engineering", ip: "β€”", time: "Yesterday, 12:03" }, ]; export const emojis = ["πŸ‘", "❀️", "πŸ˜‚", "😊", "πŸš€", "πŸŽ‰", "πŸ‘‹", "πŸ™Œ", "πŸ€”", "πŸ‘€", "πŸ’―", "πŸ”₯"]; // =================================================================== // 2. UTILITY FUNCTIONS // =================================================================== function cn(...classes) { return classes.filter(Boolean).join(" "); } // =================================================================== // 3. UI COMPONENTS (Stubs for shadcn/ui used in App) // =================================================================== function Badge({ children, className, variant = "default" }) { const variants = { default: "bg-primary text-primary-foreground", secondary: "bg-secondary text-secondary-foreground", destructive: "bg-destructive text-destructive-foreground", outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground" }; return {children}; } function Button({ children, className, variant = "default", size = "default", asChild, ...props }) { const variants = { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground", link: "text-primary underline-offset-4 hover:underline", }; const sizes = { default: "h-10 px-4 py-2", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "h-10 w-10", }; const Comp = asChild ? "span" : "button"; return {children}; } function Card({ children, className }) { return
{children}
; } function CardHeader({ children, className }) { return
{children}
; } function CardTitle({ children, className }) { return

{children}

; } function CardContent({ children, className }) { return
{children}
; } function Input({ className, ...props }) { return ; } function Label({ children, className, ...props }) { return ; } function Separator({ className }) { return
; } function Switch({ className, defaultChecked, checked, onCheckedChange }) { const [isChecked, setIsChecked] = useState(defaultChecked || checked || false); const toggle = () => { const newVal = !isChecked; setIsChecked(newVal); if (onCheckedChange) onCheckedChange(newVal); }; return ; } function Progress({ value, className }) { return
; } function Checkbox({ className, defaultChecked }) { const [checked, setChecked] = useState(defaultChecked || false); return ; } function ScrollArea({ children, className }) { return
{children}
; } // Dialog Stubs function Dialog({ children, open, onOpenChange }) { return <>{open &&
{children}
}; } function DialogTrigger({ children, asChild }) { return asChild ? children : ; } function DialogContent({ children }) { return <>{children}; } function DialogHeader({ children }) { return
{children}
; } function DialogTitle({ children }) { return

{children}

; } function DialogDescription({ children }) { return

{children}

; } function DialogFooter({ children }) { return
{children}
; } // Dropdown Stubs function DropdownMenu({ children }) { return
{children}
; } function DropdownMenuTrigger({ children, asChild }) { return asChild ? children : ; } function DropdownMenuContent({ children, align, className }) { return
{children}
; } function DropdownMenuItem({ children, className }) { return
{children}
; } function DropdownMenuLabel({ children }) { return
{children}
; } function DropdownMenuSeparator() { return
; } // Tabs Stubs function Tabs({ children, defaultValue, value, onValueChange }) { const [active, setActive] = useState(value || defaultValue); const handleChange = (val) => { setActive(val); if (onValueChange) onValueChange(val); }; return
{React.Children.map(children, child => React.cloneElement(child, { _active: active, _onChange: handleChange }))}
; } function TabsList({ children, className }) { return
{children}
; } function TabsTrigger({ children, value, className, _active, _onChange }) { const isActive = _active === value; return ; } function TabsContent({ children, value, className, _active }) { if (_active !== value) return null; return
{children}
; } // Popover Stubs function Popover({ children, open, onOpenChange }) { return <>{open &&
{children}
}; } function PopoverTrigger({ children, asChild }) { return asChild ? children : ; } function PopoverContent({ children, className, align }) { return
{children}
; } // Sheet Stubs function Sheet({ children, open, onOpenChange }) { return <>{open &&
{children}
}; } function SheetTrigger({ children, asChild }) { return asChild ? children : ; } function SheetContent({ children, side, className }) { return
{children}
; } function SheetTitle({ children }) { return

{children}

; } // Radio Stubs function RadioGroup({ children, defaultValue, className }) { return
{children}
; } function RadioGroupItem({ value, className }) { return
; } // Table Stubs function Table({ children, className }) { return
{children}
; } function TableHeader({ children }) { return {children}; } function TableBody({ children }) { return {children}; } function TableRow({ children, className }) { return {children}; } function TableHead({ children, className }) { return {children}; } function TableCell({ children, className }) { return {children}; } function Textarea({ className, ...props }) { return