// 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";
import ConfirmSubmitGuard from "../../../islands/ConfirmSubmitGuard.tsx";
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;
const { user_id } = stateData;
try {
const response = await fetch("/api/lease/pending-approvals", {
headers: {
"Content-Type": "application/json",
},
});
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) {
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"
? "/api/lease/approve"
: "/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",
},
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 (
<>
Review and manage pending lease approval requests
{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"}
This lease has been approved and is now active.
This lease request has been rejected.
{approval.rejection_reason && (Reason:{" "} {approval.rejection_reason}
)}You don't have any pending lease approval requests at this time.