mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
working on os api
This commit is contained in:
parent
48c26d4258
commit
a26cdb3d14
1 changed files with 50 additions and 23 deletions
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/app/shadcn_components/ui/button";
|
||||
import { Input } from "@/app/shadcn_components/ui/input";
|
||||
import { Card } from "@/app/shadcn_components/ui/card";
|
||||
|
|
@ -14,6 +14,11 @@ import {
|
|||
} from "@/app/shadcn_components/ui/select";
|
||||
import usePostcodeLookup from "./usePostcodeLookup";
|
||||
|
||||
interface AddressItem {
|
||||
uprn: string;
|
||||
address: string;
|
||||
}
|
||||
|
||||
export default function AddressSearch({
|
||||
onAddressSelect,
|
||||
onPostcodeSelect,
|
||||
|
|
@ -23,33 +28,50 @@ export default function AddressSearch({
|
|||
onPostcodeSelect: (postcode: string) => void;
|
||||
postcode: string;
|
||||
}) {
|
||||
const [addresses, setAddresses] = useState<string[]>([]);
|
||||
const [addresses, setAddresses] = useState<AddressItem[]>([]);
|
||||
const [selectedAddress, setSelectedAddress] = useState<string | null>(null);
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
const [triggerSearch, setTriggerSearch] = useState(false);
|
||||
const [loadingAddresses, setLoadingAddresses] = useState(false);
|
||||
const [addressError, setAddressError] = useState<string | null>(null);
|
||||
|
||||
const { data, isFetching, refetch } = usePostcodeLookup(
|
||||
postcode,
|
||||
triggerSearch
|
||||
);
|
||||
|
||||
// When postcode data returns successfully (status 200), populate mock addresses
|
||||
useEffect(() => {
|
||||
if (data && data.status === 200 && data.result) {
|
||||
setAddresses([
|
||||
`10 Downing Street, London, ${data.result.postcode}`,
|
||||
`11 Downing Street, London, ${data.result.postcode}`,
|
||||
`12 Downing Street, London, ${data.result.postcode}`,
|
||||
]);
|
||||
setShowDropdown(true);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
async function handleSearch() {
|
||||
if (!postcode.trim()) return;
|
||||
setTriggerSearch(true);
|
||||
await refetch();
|
||||
setTriggerSearch(false); // Reset trigger after refetch
|
||||
const validation = await refetch();
|
||||
setTriggerSearch(false);
|
||||
|
||||
// Only continue if postcode is valid
|
||||
if (!validation.data || validation.data.status !== 200) return;
|
||||
|
||||
// Fetch addresses from backend
|
||||
setLoadingAddresses(true);
|
||||
setAddressError(null);
|
||||
try {
|
||||
const res = await fetch(
|
||||
`/api/postcode/${encodeURIComponent(postcode)}/addresses`
|
||||
);
|
||||
const json = await res.json();
|
||||
|
||||
if (!res.ok) {
|
||||
setAddressError(json.error || "Unable to retrieve addresses");
|
||||
setShowDropdown(false);
|
||||
} else if (json.results?.length) {
|
||||
setAddresses(json.results);
|
||||
setShowDropdown(true);
|
||||
} else {
|
||||
setAddressError("No addresses found for this postcode");
|
||||
}
|
||||
} catch (err: any) {
|
||||
setAddressError("There was an issue contacting the address service.");
|
||||
} finally {
|
||||
setLoadingAddresses(false);
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelectAddress(value: string) {
|
||||
|
|
@ -67,6 +89,8 @@ export default function AddressSearch({
|
|||
const showInvalid = data && data.status === 404;
|
||||
const showServerError = data && data.status === 500;
|
||||
|
||||
const isLoading = isFetching || loadingAddresses;
|
||||
|
||||
return (
|
||||
<Card className="p-6">
|
||||
<h2 className="text-xl font-semibold text-brandbrown mb-4">
|
||||
|
|
@ -83,15 +107,15 @@ export default function AddressSearch({
|
|||
/>
|
||||
<Button
|
||||
onClick={handleSearch}
|
||||
disabled={isFetching || !postcode}
|
||||
disabled={isLoading || !postcode}
|
||||
className="bg-brandbrown text-white"
|
||||
>
|
||||
{isFetching ? "Searching..." : "Search"}
|
||||
{isLoading ? "Searching..." : "Search"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Validation + Error feedback */}
|
||||
{/* Validation or server errors */}
|
||||
{showInvalid && (
|
||||
<p className="text-sm text-red-600 mb-3">
|
||||
Invalid postcode — please check and try again.
|
||||
|
|
@ -102,8 +126,11 @@ export default function AddressSearch({
|
|||
The postcode service is currently unavailable. Please try again later.
|
||||
</p>
|
||||
)}
|
||||
{addressError && (
|
||||
<p className="text-sm text-orange-600 mb-3">{addressError}</p>
|
||||
)}
|
||||
|
||||
{/* Address Dropdown */}
|
||||
{/* Address dropdown */}
|
||||
{showDropdown && addresses.length > 0 && (
|
||||
<div className="mt-2">
|
||||
<label className="block text-sm text-gray-700 mb-2">
|
||||
|
|
@ -118,8 +145,8 @@ export default function AddressSearch({
|
|||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{addresses.map((a) => (
|
||||
<SelectItem key={a} value={a}>
|
||||
{a}
|
||||
<SelectItem key={a.uprn} value={a.address}>
|
||||
{a.address}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
|
|
@ -127,7 +154,7 @@ export default function AddressSearch({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* Selected Address Display */}
|
||||
{/* Selected address display */}
|
||||
{selectedAddress && !showDropdown && (
|
||||
<div className="relative bg-gray-100 border rounded-xl p-6 mt-4">
|
||||
<h3 className="text-lg font-semibold text-brandblue mb-2">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue