// routes/landlord/dashboard/index.tsx import { define } from "../../../utils.ts"; import { getLandlordDashboardData, getPendingLeaseApprovals } from "../../../services/landlordService.ts"; import { DashboardTenantApplication } from "../../../services/tenantApplicationService.ts"; import { DashboardMaintenanceRequest } from "../../../services/maintenanceRequestService.ts"; import { DashboardMessage } from "../../../services/messageService.ts"; import { page } from "fresh"; import { SessionCookie } from "../../auth/callback.ts"; import { MakeNewDate } from "../../../helpers.ts"; // Flexible interface for dashboard data - allows any structure interface FlexibleDashboardData { // Core dashboard stats from LandlordDashboardData properties?: { total: number; id: string; address_1: string; city: string; state: string; rental_status: string; monthly_rent: number; bedrooms: number; bathrooms: number; available: number; occupied: number; draft: number; }[]; leases?: { active: number; draft: number; expired: number; }[]; applications?: { pending: number; total_this_month: number; title: string; }[]; payments?: { expected_this_month: number; received_this_month: number; overdue: number; }[]; // Additional UI properties with proper types from service layer tenantApplications?: DashboardTenantApplication[]; maintenanceRequests?: DashboardMaintenanceRequest[]; recentMessages?: DashboardMessage[]; monthlyRevenue?: number; pendingLeaseApprovals?: any[]; [key: string]: unknown; // Allow any additional properties } // Flexible interface for component data interface LandlordDashboardPageData { stateData?: SessionCookie; dashboardData?: FlexibleDashboardData; error?: string; [key: string]: unknown; // Allow additional properties with unknown type } interface LandlordDashboardProps { data: LandlordDashboardPageData; } export const handler = define.handlers({ async GET(ctx) { const stateData: SessionCookie = ctx.state.data; const { user_id } = stateData; if (!user_id) { return new Response("", { status: 302, headers: { Location: "/auth/login" }, }); } try { const dashboardData = await getLandlordDashboardData(user_id); const pendingApprovals = await getPendingLeaseApprovals(user_id); return page({ stateData, dashboardData: { ...dashboardData, pendingApprovals, }, }); } catch (error) { console.error("Error loading landlord dashboard:", error); return page({ stateData, error: "Failed to load dashboard data", }); } }, }); export default define.page( function LandlordDashboard({ data }: LandlordDashboardProps) { const { stateData: _stateData, dashboardData, error } = data; if (error) { return (
Welcome back! Here's what's happening with your properties.
{property.address_1}
{property.city}, {property.state}
{property.rental_status}
${property.monthly_rent}/mo
{property.bedrooms}bd/{property.bathrooms}ba
No properties yet
Add your first property{message.sender_name || "Tenant"}
{message.subject}
{MakeNewDate( (message as DashboardMessage) .created_on as number, ) .toLocaleDateString()}
No messages yet
{application.applicant_name}
{application.applicant_email}
Applied {application.submitted_on ? new Date(application.submitted_on) .toLocaleDateString() : "Unknown date"}
No pending applications
{approval.property?.title || approval.property_address || "Property"}
Tenant: {approval.tenant?.name || approval.tenant?.email || "Unknown"}
Requested {approval.approval_requested_at ? new Date(approval.approval_requested_at).toLocaleDateString() : "Unknown date"}
No pending lease approvals
{request.description}
Priority: {request.priority}
{request.created_on ? new Date(request.created_on) .toLocaleDateString() : "Unknown date"}
No open maintenance requests