"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { Megaphone, MessageSquare, Mail, Plus, FileText, Calendar, Receipt, Users, Sparkles, RefreshCcw, ChevronRight, DollarSign, Briefcase, ArrowUpRight, ArrowDownRight, } from "lucide-react"; import { Card, CardContent } from "@/components/ui/card"; import { fetchConversations } from "@/lib/supabase/comms-actions"; import { fetchSentEmails } from "@/lib/supabase/invoicing-actions"; import { fetchAnnouncements } from "@/lib/supabase/noticeboard-actions"; import { fetchDashboardData, type DashboardData } from "@/lib/supabase/dashboard-actions"; import { getCurrentUserInfo } from "@/lib/supabase/rbac-actions"; import { generateFinancialNarrative } from "@/lib/gemini"; import { usePermissions } from "@/hooks/usePermissions"; import PageSkeleton from "./PageSkeleton"; // Quick action definitions with required permissions interface QuickAction { label: string; icon: typeof FileText; href: string; color: string; requiredPermission?: "can_manage_invoices" | "can_manage_expenses" | "can_manage_noticeboard" | "can_approve_leave"; } const ALL_QUICK_ACTIONS: QuickAction[] = [ { label: "New Invoice", icon: FileText, href: "/invoices?view=new", color: "bg-blue-50 text-blue-600 hover:bg-blue-100", requiredPermission: "can_manage_invoices" }, { label: "Request Leave", icon: Calendar, href: "/leave", color: "bg-purple-50 text-purple-600 hover:bg-purple-100", requiredPermission: "can_approve_leave" }, { label: "Add Expense", icon: Receipt, href: "/expenses", color: "bg-orange-50 text-orange-600 hover:bg-orange-100", requiredPermission: "can_manage_expenses" }, { label: "Post Update", icon: Megaphone, href: "/noticeboard", color: "bg-teal-50 text-teal-600 hover:bg-teal-100", requiredPermission: "can_manage_noticeboard" }, ]; export default function HomePage() { const router = useRouter(); const { hasPermission, hasAnyPermission, isOwnerOrAdmin } = usePermissions(); const [loading, setLoading] = useState(true); const [userInfo, setUserInfo] = useState(null); const [dashboardData, setDashboardData] = useState(null); const [announcements, setAnnouncements] = useState([]); const [conversations, setConversations] = useState([]); const [sentEmails, setSentEmails] = useState([]); const [aiNarrative, setAiNarrative] = useState(null); const [generatingAi, setGeneratingAi] = useState(false); useEffect(() => { let cancelled = false; const loadData = async () => { try { const [user, dash, anns, convos, emails] = await Promise.all([ getCurrentUserInfo().catch(() => null), fetchDashboardData().catch(() => null), fetchAnnouncements().catch(() => []), fetchConversations().catch(() => []), fetchSentEmails(10).catch(() => []), ]); if (cancelled) return; setUserInfo(user); setDashboardData(dash); setAnnouncements((anns as any[]).slice(0, 3)); setConversations((convos as any[]).slice(0, 3)); setSentEmails(emails || []); // Initial AI Narrative load if (dash && user) { setGeneratingAi(true); const narrative = await generateFinancialNarrative(dash); if (!cancelled) setAiNarrative(narrative); setGeneratingAi(false); } } catch (err) { console.error("Home Page data load failed:", err); } finally { if (!cancelled) setLoading(false); } }; loadData(); return () => { cancelled = true; }; }, []); const handleRefreshAi = async () => { if (!dashboardData) return; setGeneratingAi(true); const narrative = await generateFinancialNarrative(dashboardData); setAiNarrative(narrative); setGeneratingAi(false); }; if (loading) return ; const firstName = userInfo?.fullName?.split(" ")[0] || "there"; // Filter quick actions based on user permissions const visibleQuickActions = ALL_QUICK_ACTIONS.filter((action) => { if (isOwnerOrAdmin) return true; if (!action.requiredPermission) return true; return hasPermission(action.requiredPermission); }); // Determine what dashboard sections to show based on permissions const canViewFinances = isOwnerOrAdmin || hasAnyPermission(["can_view_dashboard", "can_view_invoices", "can_view_expenses"]); const canViewNoticeboard = isOwnerOrAdmin || hasPermission("can_view_noticeboard"); const canUseComms = isOwnerOrAdmin || hasPermission("can_use_comms"); const canViewSentEmails = isOwnerOrAdmin || hasPermission("can_view_sent_emails"); return (
{/* 1. Personal Greeting & AI Summary */}

Hello, {firstName}.

Everything is ready for you today.

{new Date().toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' })}
{/* AI Insight Card - Simple and approachable */} {aiNarrative && (

Smart Summary

"{aiNarrative}"

)}
{/* 2. Quick Actions - Big, friendly tiles for newbies */} {visibleQuickActions.length > 0 && (

Quick Actions

{visibleQuickActions.map((action) => ( ))}
)} {/* 3. The Dashboard - Simplified Metrics */} {dashboardData && (

Your Numbers

Cash Available

${(dashboardData.metrics.cash_on_hand / 100).toLocaleString()}

{dashboardData.trends.cash && ( {dashboardData.trends.cash.direction === 'up' ? '↑' : '↓'}{dashboardData.trends.cash.value}% )}

Owed to you

${(dashboardData.metrics.outstanding_invoices / 100).toLocaleString()}

Total Team

{dashboardData.metrics.headcount}

)} {/* 4. Company Hub & Activity */} {(canViewNoticeboard || canUseComms || canViewSentEmails) && (
{/* Noticeboard & Messaging */} {(canViewNoticeboard || canUseComms) && (
{canViewNoticeboard && (

Company Hub

)} {canViewNoticeboard && (
{announcements.length > 0 ? announcements.map((a) => (
router.push('/noticeboard')}>
New {new Date(a.created_at).toLocaleDateString()}

{a.title}

{a.body}

)) : (
No recent updates
)}
)} {canUseComms && (

Need to talk?

Jump into a team conversation

)}
)} {/* Recent Emails / Activity */} {canViewSentEmails && (

Recent Emails

{sentEmails.length > 0 ? sentEmails.slice(0, 5).map((e) => (

{e.subject}

To: {e.to_email}

{new Date(e.sent_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}

)) : (
No emails sent recently
)}
)} {/* Spacer for single-column when only one section is visible */} {!(canViewNoticeboard || canUseComms) && canViewSentEmails && (
)} {(canViewNoticeboard || canUseComms) && !canViewSentEmails && (
)}
)}
); }