"use client" import { useState } from "react" import { toast } from "sonner" import { Zap, TrendingUp, AlertTriangle, Wrench, FileText, DollarSign, RefreshCw, CheckCircle, XCircle, Loader2, Lightbulb, ShieldAlert, } from "lucide-react" const typeConfig: Record = { rent_increase: { icon: TrendingUp, color: "text-emerald-400", bg: "bg-emerald-500/10", border: "border-emerald-500/20" }, vacancy_alert: { icon: AlertTriangle, color: "text-amber-400", bg: "bg-amber-500/10", border: "border-amber-500/20" }, maintenance_urgent: { icon: Wrench, color: "text-red-400", bg: "bg-red-500/10", border: "border-red-500/20" }, lease_renewal: { icon: FileText, color: "text-blue-400", bg: "bg-blue-500/10", border: "border-blue-500/20" }, expense_alert: { icon: DollarSign, color: "text-orange-400", bg: "bg-orange-500/10", border: "border-orange-500/20" }, cash_flow: { icon: TrendingUp, color: "text-indigo-400", bg: "bg-indigo-500/10", border: "border-indigo-500/20" }, risk_alert: { icon: ShieldAlert, color: "text-red-400", bg: "bg-red-500/10", border: "border-red-500/20" }, opportunity: { icon: Lightbulb, color: "text-violet-400", bg: "bg-violet-500/10", border: "border-violet-500/20" }, } const priorityBadge: Record = { high: "text-red-400 bg-red-500/10 ring-red-500/20", medium: "text-amber-400 bg-amber-500/10 ring-amber-500/20", low: "text-white/40 bg-white/5 ring-white/10", } export function RecommendationsClient({ recommendations: initial }: { recommendations: any[] }) { const [recs, setRecs] = useState(initial) const [generating, setGenerating] = useState(false) const [actionLoading, setActionLoading] = useState(null) const [filter, setFilter] = useState<"pending" | "approved" | "dismissed">("pending") const filtered = recs.filter((r) => r.status === filter) const pendingCount = recs.filter((r) => r.status === "pending").length async function generate() { setGenerating(true) try { const res = await fetch("/api/ai/recommendations", { method: "POST" }) const data = await res.json() if (!res.ok) { toast.error(data.error ?? "Failed to generate"); return } setRecs((prev) => [...data, ...prev.filter((r) => r.status !== "pending")]) toast.success(`${data.length} recommendations generated`) setFilter("pending") } catch { toast.error("Network error — please try again") } finally { setGenerating(false) } } async function updateStatus(id: string, status: "approved" | "dismissed") { setActionLoading(id + status) try { const res = await fetch(`/api/ai/recommendations/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }), }) const data = await res.json() if (!res.ok) { toast.error(data.error ?? "Failed to update"); return } setRecs((prev) => prev.map((r) => r.id === id ? data : r)) toast.success(status === "approved" ? "Recommendation approved!" : "Dismissed") } catch { toast.error("Network error — please try again") } finally { setActionLoading(null) } } return (
{/* Header */}

AI Recommendations

Smart suggestions based on your portfolio data {pendingCount > 0 && {pendingCount} pending}

{/* Filter tabs */}
{(["pending", "approved", "dismissed"] as const).map((s) => ( ))}
{/* List */} {filtered.length === 0 ? (

{filter === "pending" ? "No pending recommendations" : `No ${filter} recommendations`}

{filter === "pending" && (

Click "Generate New" to analyze your portfolio

)}
) : (
{filtered.map((rec) => { const cfg = typeConfig[rec.type] ?? typeConfig.opportunity const Icon = cfg.icon return (

{rec.title}

{rec.priority}

{rec.description}

{rec.impact && (

↗ {rec.impact}

)}
{rec.status === "pending" && (
)} {rec.status === "approved" && (
Approved
)} {rec.status === "dismissed" && (
Dismissed
)}
) })}
)}
) }