import { redirect } from "next/navigation" import { eq } from "drizzle-orm" import { db } from "@/lib/db" import { profiles } from "@/lib/db/schema" import { getSessionUser } from "@/lib/session" import { getDashboardStats, getRecentRentPayments, getOpenMaintenanceRequests, getExpiringLeases, getMonthlyRevenue, getExpenseBreakdown, } from "@/lib/db/queries" import { StatsCard } from "@/components/dashboard/stats-card" import { RevenueChart } from "@/components/dashboard/revenue-chart" import { ExpenseBreakdownChart } from "@/components/dashboard/expense-breakdown-chart" import { QuickActions } from "@/components/dashboard/quick-actions" import { RentStatusBadge } from "@/components/dashboard/rent-status-badge" import { MaintenanceStatusBadge, PriorityBadge } from "@/components/dashboard/maintenance-status-badge" import { EmptyState } from "@/components/shared/empty-state" import { formatCurrency, formatDate, daysUntil } from "@/lib/utils" import { Building2, CreditCard, Wrench, TrendingUp, AlertTriangle, ArrowRight, CheckCircle2, Clock, Sparkles, ChevronRight, } from "lucide-react" import Link from "next/link" function GreetingBanner({ name }: { name: string }) { const hour = new Date().getHours() const greeting = hour < 12 ? "Good morning" : hour < 17 ? "Good afternoon" : "Good evening" const now = new Date() const dateStr = now.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" }) return (

{greeting}, {name?.split(" ")[0] ?? "there"} 👋

{dateStr}

All systems operational
) } function OnboardingChecklist() { const steps = [ { label: "Add your first property", href: "/properties/new", icon: Building2 }, { label: "Create a tenant profile", href: "/tenants/new", icon: TrendingUp }, { label: "Record a rent payment", href: "/rent", icon: CreditCard }, { label: "Set up a lease", href: "/leases/new", icon: CheckCircle2 }, ] return (

Welcome to Property Management Network!

Complete these steps to get started

{steps.map((step, i) => ( {i + 1} {step.label} ))}
) } export default async function DashboardPage() { const user = await getSessionUser() if (!user) redirect("/login") // Fetch profile for greeting const profile = await db.query.profiles.findFirst({ where: eq(profiles.id, user.id), columns: { full_name: true }, }) const [stats, recentPayments, openMaintenance, expiringLeases, monthlyRevenue, expenseBreakdown] = await Promise.all([ getDashboardStats(user.id), getRecentRentPayments(user.id), getOpenMaintenanceRequests(user.id), getExpiringLeases(user.id), getMonthlyRevenue(user.id), getExpenseBreakdown(user.id), ]) const hasData = stats.totalProperties > 0 const rentTrendPct = stats.rentCollectedLastMonth > 0 ? Math.round(((stats.rentCollectedThisMonth - stats.rentCollectedLastMonth) / stats.rentCollectedLastMonth) * 100) : null const occupancyColor: "default" | "success" | "warning" | "danger" = stats.occupancyRate >= 80 ? "success" : stats.occupancyRate >= 50 ? "warning" : "danger" return (
{/* Greeting */} {/* Onboarding */} {!hasData && } {/* KPI Cards */}
0 ? Math.min(100, (stats.totalProperties / 10) * 100) : 0} /> 0 ? `${formatCurrency(stats.rentOverdue)} overdue` : "No overdue rent"} icon={Wrench} variant={stats.openMaintenanceRequests > 0 ? "warning" : "default"} />
{/* Expiring leases alert */} {expiringLeases.length > 0 && (
{expiringLeases.length} lease{expiringLeases.length > 1 ? "s" : ""} expiring soon View all
{expiringLeases.slice(0, 4).map((lease: any) => { const days = daysUntil(lease.lease_end) return (
{lease.tenant?.first_name} {lease.tenant?.last_name}
{days <= 0 ? "Expired" : `${days}d`}
) })}
)} {/* Middle row: Revenue chart + Quick Actions */}
{/* Bottom row: Recent payments + Open maintenance */}
{/* Recent Payments */}

Recent Payments

View all
{recentPayments.length === 0 ? ( ) : (
{recentPayments.map((payment: any) => (
{payment.tenant?.first_name?.[0]}{payment.tenant?.last_name?.[0]}

{payment.tenant?.first_name} {payment.tenant?.last_name}

{payment.property?.name} · {formatDate(payment.due_date)}

{formatCurrency(payment.amount)}
))}
)}
{/* Open Maintenance */}

Open Maintenance

{stats.openMaintenanceRequests > 0 && ( {stats.openMaintenanceRequests} )}
View all
{openMaintenance.length === 0 ? ( ) : (
{openMaintenance.map((req: any) => (

{req.title}

{req.property?.name}{req.tenant ? ` · ${req.tenant.first_name} ${req.tenant.last_name}` : ""}

))}
)}
) }