188 lines
6.3 KiB
TypeScript
188 lines
6.3 KiB
TypeScript
// routes/tenant/reminders/new/index.tsx
|
|
import { define } from "../../../../utils.ts";
|
|
import { page } from "fresh";
|
|
import { getLeasesByTenant } from "../../../../services/leaseService.ts";
|
|
import { createReminder } from "../../../../services/reminderService.ts";
|
|
import { Lease } from "../../../../db/interfaces.ts";
|
|
import { FormField } from "../../maintenance/new/components/FormField.tsx";
|
|
import { TextAreaField } from "../../maintenance/new/components/TextAreaField.tsx";
|
|
import { AlertMessage } from "../../maintenance/new/components/AlertMessage.tsx";
|
|
import { SelectField } from "../../maintenance/new/components/SelectField.tsx";
|
|
|
|
interface NewReminderPageData {
|
|
currentLease?: Lease;
|
|
error?: string;
|
|
}
|
|
|
|
const REMINDER_TYPES = [
|
|
{ value: "general", label: "General" },
|
|
{ value: "payment", label: "Payment Due" },
|
|
{ value: "lease_event", label: "Lease Event" },
|
|
];
|
|
|
|
export const handler = define.handlers({
|
|
async GET(ctx) {
|
|
const { user_id } = ctx.state.data;
|
|
|
|
try {
|
|
const leases = await getLeasesByTenant(user_id);
|
|
const currentLease = leases?.[0]; // Get the current lease for context/lease_id
|
|
|
|
return page<NewReminderPageData>({
|
|
currentLease,
|
|
});
|
|
} catch (error) {
|
|
console.error("Error loading new reminder form:", error);
|
|
return page<NewReminderPageData>({
|
|
error: "Failed to load form",
|
|
});
|
|
}
|
|
},
|
|
|
|
async POST(ctx) {
|
|
const { user_id } = ctx.state.data;
|
|
|
|
try {
|
|
const formData = await ctx.req.formData();
|
|
const title = formData.get("title") as string;
|
|
const description = formData.get("description") as string || null;
|
|
const due_date_str = formData.get("due_date") as string;
|
|
const reminder_type = formData.get("reminder_type") as string;
|
|
const lease_id = formData.get("lease_id") as string || null;
|
|
|
|
if (!title || !due_date_str || !reminder_type) {
|
|
return new Response(
|
|
"Missing required fields: Title, Due Date, and Type.",
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
// Convert date string (YYYY-MM-DD) to Unix timestamp (milliseconds)
|
|
const due_date = new Date(due_date_str).getTime();
|
|
|
|
if (isNaN(due_date)) {
|
|
return new Response("Invalid due date format.", { status: 400 });
|
|
}
|
|
|
|
await createReminder(
|
|
user_id,
|
|
lease_id,
|
|
reminder_type,
|
|
title,
|
|
description,
|
|
due_date,
|
|
);
|
|
|
|
// Redirect to the reminders list
|
|
return new Response("", {
|
|
status: 302,
|
|
headers: { Location: "/tenant/reminders?success=true" },
|
|
});
|
|
} catch (error) {
|
|
console.error("Error submitting new reminder:", error);
|
|
return page<NewReminderPageData>({
|
|
error: "Failed to create reminder. Please try again.",
|
|
});
|
|
}
|
|
},
|
|
});
|
|
|
|
export default define.page(function NewTenantReminderPage({ data }) {
|
|
const { currentLease, error } = data as NewReminderPageData;
|
|
|
|
return (
|
|
<div class="min-h-screen bg-gray-50 tenant-route">
|
|
{/* Header */}
|
|
<div class="bg-white shadow">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="py-6">
|
|
<h1 class="text-3xl font-bold text-gray-900">
|
|
Create New Reminder
|
|
</h1>
|
|
<p class="mt-1 text-sm text-gray-500">
|
|
Set a custom reminder for important dates or tasks.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Main Content */}
|
|
<div class="max-w-4xl mx-auto sm:px-6 lg:px-8 py-8">
|
|
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
|
<div class="p-6">
|
|
<form method="POST">
|
|
{/* Hidden Fields */}
|
|
{currentLease && (
|
|
<input
|
|
type="hidden"
|
|
name="lease_id"
|
|
value={currentLease.id}
|
|
/>
|
|
)}
|
|
|
|
<div class="space-y-6">
|
|
{error && <AlertMessage type="error">{error}</AlertMessage>}
|
|
|
|
<FormField label="Reminder Title" required>
|
|
<input
|
|
type="text"
|
|
name="title"
|
|
id="title"
|
|
required
|
|
placeholder="e.g., Pay Rent, Lease Renewal Date"
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
|
/>
|
|
</FormField>
|
|
|
|
<FormField label="Reminder Type" required>
|
|
<SelectField
|
|
id="reminder_type"
|
|
name="reminder_type"
|
|
options={REMINDER_TYPES}
|
|
required
|
|
/>
|
|
</FormField>
|
|
|
|
<FormField label="Due Date" required>
|
|
<input
|
|
type="date"
|
|
name="due_date"
|
|
id="due_date"
|
|
required
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
|
/>
|
|
</FormField>
|
|
|
|
<FormField label="Description (Optional)">
|
|
<TextAreaField
|
|
id="description"
|
|
name="description"
|
|
rows={4}
|
|
placeholder="Add more details about the reminder..."
|
|
/>
|
|
</FormField>
|
|
|
|
{/* Submit Button */}
|
|
<div class="flex justify-between pt-6">
|
|
<a
|
|
href="/tenant/reminders"
|
|
class="inline-flex justify-center py-2 px-4 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
|
>
|
|
Cancel
|
|
</a>
|
|
<button
|
|
type="submit"
|
|
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
|
>
|
|
Create Reminder
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
});
|