diff --git a/routes/api/update/lease_accept.ts b/routes/api/update/lease_accept.ts new file mode 100644 index 0000000..356e9a9 --- /dev/null +++ b/routes/api/update/lease_accept.ts @@ -0,0 +1,54 @@ +// routes/api/update/lease_accept.ts +import { define } from "../../../utils.ts"; +import { signLease } from "../../../services/leaseService.ts"; +import { SessionCookie } from "../../auth/callback.ts"; + +export const handler = define.handlers({ + async POST(ctx) { + try { + const stateData: SessionCookie = ctx.state.data; + const { user_id } = stateData || {}; + + if (!user_id) { + return new Response(JSON.stringify({ error: "Unauthorized" }), { + status: 401, + headers: { "Content-Type": "application/json" }, + }); + } + + const contentType = ctx.req.headers.get("content-type") || ""; + let data: Record = {}; + if (contentType.includes("application/json")) { + data = await ctx.req.json(); + } else { + const form = await ctx.req.formData(); + for (const [k, v] of form.entries()) { + data[k] = typeof v === "string" ? v : String(v); + } + } + + const lease_id = (data.lease_id as string) || + (data["lease_id"] as string); + if (!lease_id) { + return new Response(JSON.stringify({ error: "lease_id is required" }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const result = await signLease(lease_id, user_id as string); + return new Response( + JSON.stringify({ success: true, lease: result?.[0] || null }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ); + } catch (err) { + return new Response(JSON.stringify({ error: String(err) }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } + }, +}); diff --git a/routes/api/update/lease_invite.ts b/routes/api/update/lease_invite.ts new file mode 100644 index 0000000..93bf3b6 --- /dev/null +++ b/routes/api/update/lease_invite.ts @@ -0,0 +1,67 @@ +// routes/api/update/lease_invite.ts +import { define } from "../../../utils.ts"; +import { getLeaseById } from "../../../services/leaseService.ts"; +import { createTenantInvite } from "../../../services/tenantInviteService.ts"; +import { SessionCookie } from "../../auth/callback.ts"; + +export const handler = define.handlers({ + async POST(ctx) { + try { + const stateData: SessionCookie = ctx.state.data; + const { user_id } = stateData || {}; + + if (!user_id) { + return new Response(JSON.stringify({ error: "Unauthorized" }), { + status: 401, + headers: { "Content-Type": "application/json" }, + }); + } + + const contentType = ctx.req.headers.get("content-type") || ""; + let data: Record = {}; + if (contentType.includes("application/json")) { + data = await ctx.req.json(); + } else { + const form = await ctx.req.formData(); + for (const [k, v] of form.entries()) { + data[k] = typeof v === "string" ? v : String(v); + } + } + + const lease_id = (data.lease_id as string) || (data["lease_id"] as string); + if (!lease_id) { + return new Response(JSON.stringify({ error: "lease_id is required" }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const lease = await getLeaseById(lease_id); + if (!lease) { + return new Response(JSON.stringify({ error: "lease not found" }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + const property_id = lease.property_id as string | undefined; + if (!property_id) { + return new Response(JSON.stringify({ error: "lease has no property_id" }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const invite = await createTenantInvite(user_id as string, property_id); + return new Response(JSON.stringify({ success: true, invite }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (err) { + return new Response(JSON.stringify({ error: String(err) }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } + }, +}); diff --git a/routes/landlord/dashboard/index.tsx b/routes/landlord/dashboard/index.tsx index fc733fc..bcf8668 100644 --- a/routes/landlord/dashboard/index.tsx +++ b/routes/landlord/dashboard/index.tsx @@ -536,3 +536,20 @@ export default define.page( ); }, ); + + + + + + + + + + + + + + + + + diff --git a/routes/landlord/payments/index.tsx b/routes/landlord/payments/index.tsx index b973a2f..6f0dd53 100644 --- a/routes/landlord/payments/index.tsx +++ b/routes/landlord/payments/index.tsx @@ -282,3 +282,4 @@ export default define.page(function LandlordPayments({ data }) { ); }); + diff --git a/routes/landlord/portfolio/index.tsx b/routes/landlord/portfolio/index.tsx index 46f7260..f391d1d 100644 --- a/routes/landlord/portfolio/index.tsx +++ b/routes/landlord/portfolio/index.tsx @@ -171,3 +171,4 @@ export default define.page(function LandlordPortfolio({ data }) { ); }); + diff --git a/routes/landlord/properties/cleanup.tsx b/routes/landlord/properties/cleanup.tsx index 01f6c10..a8da508 100644 --- a/routes/landlord/properties/cleanup.tsx +++ b/routes/landlord/properties/cleanup.tsx @@ -536,3 +536,4 @@ export default define.page(function LandlordPropertyCleanup({ data }) { ); }); +