import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import Layout from "@/components/Layout"; import { Button } from "@/components/ui/button"; import { useAuth } from "@/contexts/AuthContext"; import { useArmTheme } from "@/contexts/ArmThemeContext"; import { supabase } from "@/lib/supabase"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import LoadingScreen from "@/components/LoadingScreen"; import { Shield, Target, DollarSign, FileText, Users, Link as LinkIcon, Calendar, Book, AlertCircle, Search, ExternalLink, } from "lucide-react"; import { DirectoryWidget } from "@/components/DirectoryWidget"; const API_BASE = import.meta.env.VITE_API_BASE || ""; export default function StaffDashboard() { const navigate = useNavigate(); const { user, loading: authLoading } = useAuth(); const { theme } = useArmTheme(); const [activeTab, setActiveTab] = useState("overview"); const [staffMember, setStaffMember] = useState(null); const [okrs, setOkrs] = useState([]); const [invoices, setInvoices] = useState([]); const [directory, setDirectory] = useState([]); const [searchQuery, setSearchQuery] = useState(""); const [loading, setLoading] = useState(true); useEffect(() => { if (!authLoading && user) { loadDashboardData(); } }, [user, authLoading]); const loadDashboardData = async () => { try { setLoading(true); const { data: { session }, } = await supabase.auth.getSession(); const token = session?.access_token; if (!token) throw new Error("No auth token"); try { const memberRes = await fetch(`${API_BASE}/api/staff/me`, { headers: { Authorization: `Bearer ${token}` }, }); if ( memberRes.ok && memberRes.headers.get("content-type")?.includes("application/json") ) { const data = await memberRes.json(); setStaffMember(data); } } catch (err) { // Silently ignore API errors } try { const okrRes = await fetch(`${API_BASE}/api/staff/okrs`, { headers: { Authorization: `Bearer ${token}` }, }); if ( okrRes.ok && okrRes.headers.get("content-type")?.includes("application/json") ) { const data = await okrRes.json(); setOkrs(Array.isArray(data) ? data : []); } } catch (err) { // Silently ignore API errors } try { const invRes = await fetch(`${API_BASE}/api/staff/invoices`, { headers: { Authorization: `Bearer ${token}` }, }); if ( invRes.ok && invRes.headers.get("content-type")?.includes("application/json") ) { const data = await invRes.json(); setInvoices(Array.isArray(data) ? data : []); } } catch (err) { // Silently ignore API errors } try { const dirRes = await fetch(`${API_BASE}/api/staff/directory`, { headers: { Authorization: `Bearer ${token}` }, }); if ( dirRes.ok && dirRes.headers.get("content-type")?.includes("application/json") ) { const data = await dirRes.json(); setDirectory(Array.isArray(data) ? data : []); } } catch (err) { // Silently ignore API errors } } catch (error) { // Silently ignore errors } finally { setLoading(false); } }; const isEmployee = staffMember?.employment_type === "employee"; const isContractor = staffMember?.employment_type === "contractor"; const filteredDirectory = directory.filter( (member) => member.full_name?.toLowerCase().includes(searchQuery.toLowerCase()) || member.role?.toLowerCase().includes(searchQuery.toLowerCase()), ); if (authLoading || loading) { return ; } if (!user) { return (

STAFF Portal

Employee & Contractor Hub

); } return (
{/* Header */}

STAFF Portal

Employee & Contractor Management | Professional Utility Purple

{/* Tabs */} Overview {isEmployee && OKRs} {isEmployee && ( Pay & Benefits )} {isContractor && ( Invoices )} Directory {/* Overview Tab */}

Employment Type

{staffMember?.employment_type || "—"}

Department

{staffMember?.department || "—"}

Start Date

{staffMember?.start_date ? new Date(staffMember.start_date).toLocaleDateString() : "—"}

{/* Quick Links */} Quick Actions
{/* OKRs Tab - Employee Only */} {isEmployee && ( My OKRs Quarterly Objectives & Key Results {okrs.length === 0 ? (

No OKRs set for this quarter

) : (
{okrs.map((okr: any) => (

{okr.objective}

{okr.description}

{okr.status}
{okr.key_results?.map((kr: any) => (

{kr.title}

Progress {kr.progress}%
))}
))}
)} )} {/* Pay & Benefits Tab - Employee Only */} {isEmployee && ( Pay & Benefits Payroll and compensation information

Base Salary

${staffMember?.salary?.toLocaleString() || "—"}

View your paystubs, tax documents, and benefits in the Rippling employee portal.

)} {/* Invoices Tab - Contractor Only */} {isContractor && ( My Invoices SOP-301: Contractor Invoice Portal {invoices.length === 0 ? (

No invoices submitted

) : (
{invoices.map((invoice: any) => (

{invoice.invoice_number}

{new Date(invoice.date).toLocaleDateString()}

${invoice.amount?.toLocaleString()}

{invoice.status}
))}
)}
)} {/* Directory Tab */} ({ id: m.id, name: m.full_name, role: m.role || "Team Member", department: m.department, email: m.email, phone: m.phone, location: m.location, avatar_url: m.avatar_url, employment_type: m.employment_type === "employee" ? "employee" : "contractor", }))} title="Internal Directory" description="Find employees and contractors" />
); }