Adding in dynamic api routing

This commit is contained in:
Khalim Conn-Kowlessar 2023-05-28 09:56:16 +01:00
parent c98d28cc00
commit a4f6b00a1c
9 changed files with 51 additions and 123 deletions

View file

@ -1,22 +0,0 @@
"use server";
import type { SearchData } from "./types";
export async function fetchAddresses(postcode: string) {
let url: string;
url = `https://epc.opendatacommunities.org/api/v1/domestic/search?postcode=${postcode}&size=1000`;
const headers = new Headers({
Accept: "application/json",
Authorization: `Basic ${process.env.EPC_AUTH_TOKEN ?? ""}`,
});
const request = await fetch(url, {
headers: headers,
next: { revalidate: 60 },
});
// Explicitly assert typing of the response
const data = (await request.json()) as SearchData;
return data;
}

View file

@ -1,91 +0,0 @@
"use client";
import { ReactElement } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import type { SearchData, SearchResult } from "./types";
import SubmitButton from "../components/search/SubmitButton";
import { fetchAddresses } from "./api";
interface ToggleAddressButtonProps {
rowKey: string;
setButtonDisabled: (value: boolean) => void;
setAddress: (value: string) => void;
setCurrentlyToggled: (value: string) => void;
toggleClassName: string;
address: string;
}
const defaultToggleClass =
"mb-1 block max-w-sm rounded-lg border border-gray-200 bg-white p-6 shadow hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700";
const toggledButtonClass =
"text-white mb-1 block max-w-sm rounded-lg border border-gray-200 bg-purple-500 p-6 shadow hover:bg-purple-500 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700";
const ToggleAddressButton = ({
rowKey,
setButtonDisabled,
setAddress,
setCurrentlyToggled,
toggleClassName,
address,
}: ToggleAddressButtonProps) => {
const handleOnClick = () => {
setCurrentlyToggled(rowKey);
setAddress(address);
setButtonDisabled(false);
};
return (
<li key={rowKey}>
<a onClick={handleOnClick} className={toggleClassName}>
{address}
</a>
</li>
);
};
export default async function Addresses() {
const searchParams = useSearchParams();
// console.log("HELLo");
// console.log(searchParams);
// const postcode = searchParams.get("postcode") ?? "";
// const addresses = await fetchAddresses(postcode);
// function redirectToEpc() {
// const res = data.rows.find(
// (row: SearchResult) => row["lmk-key"] === currentlyToggled
// );
// // router
// // .push({
// // pathname: "/epc",
// // query: {
// // address: address,
// // res: encodeURIComponent(JSON.stringify(res)),
// // },
// // })
// // .catch((error) => console.log(error));
// }
function buttonDisabled() {
return true;
}
function redirectToEpc() {
return;
}
return (
<>
<div className="flex max-h-[40rem] flex-col items-center pt-10">
<h1 className="mb-5">Select your address</h1>
<ul className=" overflow-y-auto ">list of addresses</ul>
{/* <SubmitButton
buttonDisabled={buttonDisabled}
redirectFunc={redirectToEpc}
/> */}
</div>
</>
);
}

View file

@ -0,0 +1,19 @@
export async function getEPCData(postcode: string) {
const url = `https://epc.opendatacommunities.org/api/v1/domestic/search?postcode=${postcode}&size=1000`;
const headers = {
Accept: "application/json",
Authorization: `Basic ${process.env.EPC_AUTH_TOKEN ?? ""}`,
};
try {
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Failed to fetch EPC data:", error);
throw error;
}
}

View file

@ -1,14 +1,14 @@
interface SubmitButtonProps {
buttonDisabled: boolean;
redirectFunc: () => void;
onClickFunc: () => void;
}
const SubmitButton = ({ buttonDisabled, redirectFunc }: SubmitButtonProps) => {
const SubmitButton = ({ buttonDisabled, onClickFunc }: SubmitButtonProps) => {
return (
<button
type="button"
disabled={buttonDisabled}
onClick={redirectFunc}
onClick={onClickFunc}
className="focus:shadow-outline mt-3 rounded bg-brandtan px-4 py-2 font-bold text-white shadow hover:bg-hovertan focus:outline-none disabled:opacity-25 disabled:hover:bg-hovetan"
>
Submit

View file

@ -12,6 +12,10 @@ export default function RootLayout({
}: {
children: React.ReactNode;
}) {
// TODO: With this, the NavBar is being applied to the route layout so across all pages, including the sign in page, which we
// possibly don't want, or at least don't want it to look exactly like this, with the same links and ability to sign out
// on small screens.
return (
<html lang="en">
<body>

View file

@ -66,8 +66,6 @@ export default async function Page({
];
const demo_id = "f290f1ee-6c54-4b01-90e6-d701748f0851";
console.log(params);
console.log(searchParams);
let page_config;
let pageName;
if (params.slug === demo_id) {
@ -87,8 +85,6 @@ export default async function Page({
// Add an empty state for when there are no properties
// Create populated state for when there are properties
console.log(page_config);
return (
<>
<div className="flex justify-center">

View file

@ -7,12 +7,13 @@ import { useRouter } from "next/navigation";
export default function Search() {
const [postcode, setPostcode] = useState("");
const [buttonDisabled, setButtonDisabled] = useState(true);
const [data, setData] = useState(null);
const router = useRouter();
// Do something better than logging the error
// Should probablt redirect to a something went wrong page
const redirectToSearch = () => {
router.push(`/results?postcode=${postcode}`);
router.push(`/addresses?postcode=${postcode}`);
};
const handleSubmit = (e: React.KeyboardEvent<HTMLInputElement>) => {
@ -33,9 +34,22 @@ export default function Search() {
return;
};
const fetchData = async () => {
const response = await fetch(`/api/addresses/${postcode}`);
if (!response.ok) {
// handle error
console.error("An error occurred while fetching data");
return;
}
const data = await response.json();
setData(data);
};
const submitProps = {
buttonDisabled: buttonDisabled,
redirectFunc: redirectToSearch,
onClickFunc: fetchData,
};
return (
@ -65,6 +79,7 @@ export default function Search() {
</div>
<SubmitButton {...submitProps} />
</form>
{data && <div>{JSON.stringify(data, null, 2)}</div>}
</div>
</div>
);

View file

@ -1,3 +1,10 @@
export const config = { matcher: ["/home/:path*", "/portfolio/:path*"] };
export const config = {
matcher: [
"/home/:path*",
"/portfolio/:path*",
"/search/:path*",
"/addresses/:path",
],
};
export { default } from "next-auth/middleware";