150 lines
5.0 KiB
TypeScript
150 lines
5.0 KiB
TypeScript
import { Lease, Property } from "../db/interfaces.ts";
|
|
import { PopAddLeaseDialog } from "./dialogs/PopAddLeaseDialog.tsx";
|
|
|
|
interface LeasedHomeProps {
|
|
leases: Lease[];
|
|
properties: Property[];
|
|
}
|
|
|
|
import { useState } from "preact/hooks";
|
|
|
|
export default function LeasedHome({ leases, properties }: LeasedHomeProps) {
|
|
const [selectedPropertyId, setSelectedPropertyId] = useState(
|
|
properties[0]?.id || "",
|
|
);
|
|
const [popAddLease, popupAddLeaseDialog] = PopAddLeaseDialog(
|
|
leases,
|
|
properties,
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{popupAddLeaseDialog}
|
|
<div class="mb-4">
|
|
<label htmlFor="property-select" class="block mb-1 font-semibold">
|
|
Select Property:
|
|
</label>
|
|
<select
|
|
id="property-select"
|
|
class="border rounded px-3 py-2 w-full"
|
|
value={selectedPropertyId}
|
|
onChange={(e) =>
|
|
setSelectedPropertyId((e.target as HTMLSelectElement).value)}
|
|
>
|
|
{properties.map((property) => (
|
|
<option key={property.id} value={property.id}>
|
|
{property.title} — {property.address_1}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
aria-label="Go back"
|
|
onClick={() => globalThis.location.href = "/"}
|
|
style={{
|
|
position: "fixed",
|
|
bottom: 300,
|
|
left: 4,
|
|
background: "none",
|
|
border: "none",
|
|
zIndex: 50,
|
|
cursor: "pointer",
|
|
}}
|
|
>
|
|
<svg
|
|
width="32"
|
|
height="32"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<polyline points="15 18 9 12 15 6" />
|
|
</svg>
|
|
</button>
|
|
<div class="flex flex-col gap-4">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h2 class="text-2xl font-bold">Leased Homes</h2>
|
|
<button
|
|
type="button"
|
|
class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded shadow"
|
|
onClick={() => popAddLease(selectedPropertyId, Date.now())}
|
|
>
|
|
Add Lease
|
|
</button>
|
|
</div>
|
|
{leases.length === 0
|
|
? <div class="text-gray-500">No leases found.</div>
|
|
: (
|
|
<ul class="space-y-2">
|
|
{leases.map((lease) => (
|
|
<li
|
|
key={lease.id}
|
|
class="border rounded p-4 bg-white shadow relative group"
|
|
>
|
|
<form
|
|
method="POST"
|
|
action="/api/delete/lease"
|
|
className="absolute top-1/2 -right-0 transform -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-opacity duration-200"
|
|
style={{ display: "inline" }}
|
|
onSubmit={(e) => {
|
|
// Set sender input to current page
|
|
const form = e.currentTarget;
|
|
form.sender.value = location.pathname;
|
|
}}
|
|
>
|
|
<input type="hidden" name="lease_id" value={lease.id} />
|
|
<input
|
|
type="hidden"
|
|
name="sender"
|
|
value={typeof location !== "undefined"
|
|
? location.pathname
|
|
: ""}
|
|
/>
|
|
<button
|
|
type="submit"
|
|
aria-label="Delete lease"
|
|
className="text-red-700"
|
|
style={{ background: "none", border: "none", padding: 0 }}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="h-6 w-6"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</form>
|
|
<div class="font-semibold">Title: {lease.title}</div>
|
|
<div>Rent: {lease.rent}</div>
|
|
<div>Deposit: {lease.security_deposit}</div>
|
|
<div>
|
|
Start: {lease.start_date
|
|
? new Date(lease.start_date).toLocaleDateString()
|
|
: ""}
|
|
</div>
|
|
<div>
|
|
End: {lease.end_date
|
|
? new Date(lease.end_date).toLocaleDateString()
|
|
: ""}
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|