// routes/landlord/approvals/index.tsx import { define } from "../../../utils.ts"; import { page } from "fresh"; import { SessionCookie } from "../../auth/callback.ts"; import { createPublicId } from "../../../helpers.ts"; interface PendingApproval { id: string; property_id?: string; tenant_id?: string; approval_status?: string; approval_requested_at?: number; approved_at?: number; approved_by?: string; rejection_reason?: string | null; property?: { id: string; title?: string; address_1?: string; address_2?: string; city?: string; state?: string; zip?: string; monthly_rent?: number; bedrooms?: number; bathrooms?: number; } | null; tenant?: { id: string; name?: string; email?: string; phone?: string; } | null; } interface LandlordApprovalsData { stateData?: SessionCookie; approvals?: PendingApproval[]; error?: string; publicId?: string; [key: string]: unknown; } interface LandlordApprovalsProps { data: LandlordApprovalsData; } export const handler = define.handlers({ async GET(ctx) { const stateData: SessionCookie = ctx.state.data; if (!stateData || !stateData.user_id) { return new Response("", { status: 302, headers: { Location: "/auth/login" }, }); } const { user_id } = stateData; try { const response = await fetch(`http://${ctx.req.headers.get("host")}/api/lease/pending-approvals`, { headers: { "Content-Type": "application/json", "Cookie": ctx.req.headers.get("cookie") || "", }, }); if (!response.ok) { throw new Error("Failed to fetch pending approvals"); } const data = await response.json(); const publicId = await createPublicId(user_id); return page({ stateData, approvals: data.approvals || [], error: "", publicId, }); } catch (error) { console.error("Error loading pending approvals:", error); const publicId = await createPublicId(user_id); return page({ stateData, error: "Failed to load pending approvals", publicId, }); } }, async POST(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 formData = await ctx.req.formData(); const lease_id = formData.get("lease_id") as string; const action = formData.get("action") as string; const rejection_reason = formData.get("rejection_reason") as string || ""; if (!lease_id || !action) { return new Response( JSON.stringify({ error: "lease_id and action are required" }), { status: 400, headers: { "Content-Type": "application/json" }, }, ); } const apiEndpoint = action === "approve" ? `http://${ctx.req.headers.get("host")}/api/lease/approve` : `http://${ctx.req.headers.get("host")}/api/lease/reject`; const body = action === "reject" ? { lease_id, rejection_reason } : { lease_id }; const response = await fetch(apiEndpoint, { method: "POST", headers: { "Content-Type": "application/json", "Cookie": ctx.req.headers.get("cookie") || "", }, body: JSON.stringify(body), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: "Unknown error", })); return new Response( JSON.stringify({ error: errorData.error || "Failed to process approval", }), { status: response.status, headers: { "Content-Type": "application/json" }, }, ); } return new Response("", { status: 302, headers: { Location: "/landlord/approvals" }, }); } catch (error) { console.error("Error processing approval:", error); return new Response( JSON.stringify({ error: String(error) }), { status: 500, headers: { "Content-Type": "application/json" }, }, ); } }, }); export default define.page( function LandlordApprovals({ data }: LandlordApprovalsProps) { const { approvals, error } = data; return (

Lease Approvals

Review and manage pending lease approval requests

{error && (
{error}
)} {approvals && approvals.length > 0 ? (
    {approvals.map((approval) => (
  • {approval.tenant?.name?.charAt(0) || "T"}

    {approval.tenant?.name || "Tenant"}

    {approval.approval_status}

    {approval.tenant?.email}

    Property: {approval.property?.title || approval.property?.address_1 || "Property Address"}

    Monthly Rent: ${approval.property?.monthly_rent ? `$${approval.property.monthly_rent.toLocaleString()}/mo` : "N/A"}

    Requested: {approval.approval_requested_at ? new Date(approval.approval_requested_at) .toLocaleDateString() : "Unknown date"}

    {approval.approval_status === "pending" && (