import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { Shield, Search, Loader2, User, Clock, AlertTriangle, CheckCircle, Mail, ExternalLink } from "lucide-react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { api, OrgComplianceMember, create403Handler } from "@/lib/api"; import { useQuery, useMutation } from "@tanstack/react-query"; import { useToast } from "@/hooks/use-toast"; import { useOrg } from "@/contexts/OrgContext"; const STATUS_CONFIG: Record = { compliant: { label: "Compliant", color: "bg-success/10 text-success border-success/20", icon: CheckCircle, }, in_grace: { label: "In Grace", color: "bg-primary/10 text-primary border-primary/20", icon: Clock, }, past_due: { label: "Past Due", color: "bg-warning/10 text-warning border-warning/20", icon: AlertTriangle, }, suspended: { label: "Suspended", color: "bg-destructive/10 text-destructive border-destructive/20", icon: AlertTriangle, }, pending: { label: "Pending", color: "bg-muted text-muted-foreground", icon: Clock, }, not_applicable: { label: "Not Applicable", color: "bg-muted text-muted-foreground", icon: Shield, }, }; export default function CompliancePage() { const navigate = useNavigate(); const { toast } = useToast(); const { selectedOrgId: currentOrgId } = useOrg(); const [searchQuery, setSearchQuery] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); // Fetch compliance data const { data: complianceData, isLoading: complianceLoading } = useQuery({ queryKey: ['org-compliance', currentOrgId], queryFn: () => currentOrgId ? api.policies.listOrgCompliance(currentOrgId, {}, { on403: create403Handler(toast), }) : null, enabled: !!currentOrgId, }); // Send MFA reminder mutation const { mutate: sendReminder, variables: reminderVars, isPending: isSendingReminder } = useMutation({ mutationFn: ({ userId }: { userId: string }) => api.organizations.sendMfaReminder(currentOrgId!, userId), onSuccess: () => { toast({ title: "Reminder sent", description: "MFA reminder email sent successfully." }); }, onError: () => { toast({ title: "Failed to send", description: "Could not send the reminder. Please try again.", variant: "destructive" }); }, }); // Filter members based on search and status const filteredMembers = complianceData?.members?.filter((member) => { const matchesSearch = member.user_email.toLowerCase().includes(searchQuery.toLowerCase()) || member.user_name?.toLowerCase().includes(searchQuery.toLowerCase()); const matchesStatus = statusFilter === "all" || member.status === statusFilter; return matchesSearch && matchesStatus; }) || []; // Calculate stats const stats = { total: complianceData?.count || 0, compliant: complianceData?.members?.filter(m => m.status === 'compliant').length || 0, inGrace: complianceData?.members?.filter(m => m.status === 'in_grace').length || 0, pastDue: complianceData?.members?.filter(m => m.status === 'past_due').length || 0, suspended: complianceData?.members?.filter(m => m.status === 'suspended').length || 0, }; if (complianceLoading) { return (
); } return (

MFA Compliance

Monitor and manage multi-factor authentication compliance for organization members

{/* Stats Overview */}

{stats.total}

Total Members

{stats.compliant}

Compliant

{stats.inGrace}

In Grace

{stats.pastDue}

Past Due

{stats.suspended}

Suspended

{/* Filters */}
setSearchQuery(e.target.value)} className="pl-10" />
{/* Members Table */} Members {filteredMembers.length} of {complianceData?.count || 0} members shown {filteredMembers.length === 0 ? (

No members found matching your criteria

) : (
{filteredMembers.map((member) => { const config = STATUS_CONFIG[member.status] || STATUS_CONFIG.pending; const StatusIcon = config.icon; return (

{member.user_name || "Unknown"}

{member.user_email}

{member.deadline_at && member.status !== 'compliant' && member.status !== 'not_applicable' && (
Deadline: {new Date(member.deadline_at).toLocaleDateString()}
)} {config.label}
); })}
)}
); }