// routes/tenant/applications/new/index.tsx import { define } from "../../../../utils.ts"; import { page } from "fresh"; import { getLeasesByTenant } from "../../../../services/leaseService.ts"; import { createTenantApplication } from "../../../../services/tenantApplicationService.ts"; import { uploadToLocalBlobStorage } from "../../../../utils/blobStorage.ts"; import { Lease } from "../../../../db/interfaces.ts"; import { FormField } from "../../maintenance/new/components/FormField.tsx"; import { TextAreaField } from "../../maintenance/new/components/TextAreaField.tsx"; import { FileUpload } from "../../maintenance/new/components/FileUpload.tsx"; import { AlertMessage } from "../../maintenance/new/components/AlertMessage.tsx"; import { SelectField } from "../../maintenance/new/components/SelectField.tsx"; interface NewApplicationPageData { currentLease?: Lease; error?: string; } const EMPLOYMENT_STATUSES = [ { value: "employed", label: "Employed" }, { value: "self_employed", label: "Self-Employed" }, { value: "student", label: "Student" }, { value: "unemployed", label: "Unemployed" }, ]; export const handler = define.handlers({ async GET(ctx) { const { user_id } = ctx.state.data; if (!user_id) { return new Response("", { status: 302, headers: { Location: "/auth/login" }, }); } try { const leases = await getLeasesByTenant(user_id); const currentLease = leases?.[0]; // Assuming tenant has one active lease return page({ currentLease, }); } catch (error) { console.error("Error loading new application form:", error); return page({ error: "Failed to load form", }); } }, async POST(ctx) { const { user_id } = ctx.state.data; if (!user_id) { return new Response("", { status: 302, headers: { Location: "/auth/login" }, }); } try { const formData = await ctx.req.formData(); const property_id = formData.get("property_id") as string; const monthly_income = formData.get("monthly_income") as string; const employment_status = formData.get("employment_status") as string; const current_address = formData.get("current_address") as string; const notes = formData.get("notes") as string; if ( !property_id || !monthly_income || !employment_status || !current_address ) { return new Response("Missing required fields", { status: 400 }); } // 1. Handle file uploads const documentUrls: { url: string; name: string; type: string }[] = []; const files = formData.getAll("documents") as File[]; for (const file of files) { if (file.size > 0) { const blob = new Blob([await file.arrayBuffer()], { type: file.type, }); const uploadResult = await uploadToLocalBlobStorage( file.name, blob, "image", { useTimestamp: true }, ); if (uploadResult.success && uploadResult.url) { documentUrls.push({ url: uploadResult.url, name: file.name, type: file.type, }); } } } // 2. Prepare application data (to be encrypted) const applicationData = { monthly_income: parseFloat(monthly_income), employment_status, current_address, notes, // In a real app, this would be encrypted. For now, we stringify the JSON. }; const application_data_encrypted = JSON.stringify(applicationData); // 3. Create the application const [newApplication] = await createTenantApplication( property_id, user_id, application_data_encrypted, documentUrls.length > 0 ? documentUrls : null, ); // Redirect to the new application's detail page return new Response("", { status: 302, headers: { Location: `/tenant/applications/${newApplication.id}` }, }); } catch (error) { console.error("Error submitting new application:", error); return page({ error: "Failed to submit application. Please try again.", }); } }, }); export default define.page(function NewTenantApplicationPage({ data }) { const { currentLease, error } = data as NewApplicationPageData; if (error && error !== "Failed to load form") { return ( ); } if (!currentLease) { return ( ); } return (
{/* Header */}

New Rental Application

Submit a new application for a rental property.

{/* Main Content */}
{/* Hidden Fields */}
{error && }

Applicant Details

Supporting Documents

Please upload documents such as pay stubs, bank statements, or ID.

Additional Notes

{/* Submit Button */}
Cancel
); });