librarian-web/src/app/catalogue/overlay.tsx

118 lines
2.9 KiB
TypeScript

import { getBookDetail } from "@/lib/api";
import { DetailedBook } from "@/lib/book";
import { Button, Table } from "flowbite-react";
import { useState, useEffect } from "react";
import type { Dispatch, ReactNode, SetStateAction } from "react";
let setId: Dispatch<SetStateAction<number | null>>;
const idRegex = new RegExp(/\|([0-9]+)\|/);
export function handleOverlay(id: string) {
if (id.length <= 3) {
return;
}
const regexRes = idRegex.exec(id)?.[1];
if (!regexRes) {
return;
}
const idInt = parseInt(regexRes);
if (isNaN(idInt)) {
return;
} else if (!isFinite(idInt)) {
return;
}
setId(idInt);
}
export function BookDetailOverlay() {
const [id, setIdI] = useState(null as number | null);
setId = setIdI;
const [book, setBook] = useState(null as DetailedBook | null);
useEffect(() => {
if (!id) return setBook(null);
getBookDetail(id.toString()).then((data) => {
if (!data) {
console.error("Failed to fetch book details");
setBook(null);
alert("Failed to fetch book details. View console for more info.");
return;
}
setBook(data);
});
}, [id]);
if (!book) {
return "";
}
const rows2 = getRows(book);
const rows1 = rows2.splice(0, 7);
return (
<div className="fixed left-0 top-0 z-50 flex h-full w-full items-center justify-center bg-zinc-400 bg-opacity-75">
<div className="rounded-md bg-white p-8">
<Button
color="failure"
className="relative right-0 top-0 float-right m-0 p-0"
onClick={() => setId(null)}
>
X
</Button>
<h2 className="text-3xl font-bold">{book.title}</h2>
<p className="text-lg">{`(${book.subtitle})`}</p>
<p className="pb-10 text-lg">{book.authors}</p>
<div className="justify-between overflow-x-auto pb-8">
<table className="m-auto w-10/12">
<tr className="m-5 p-10">
<td>
<Table className="max-w-xl">
<Table.Head>
<Table.HeadCell colSpan={5}></Table.HeadCell>
</Table.Head>
<Table.Body className="divide-y">{rows1}</Table.Body>
</Table>
</td>
<td>
<Table className="max-w-xl">
<Table.Head>
<Table.HeadCell colSpan={5}></Table.HeadCell>
</Table.Head>
<Table.Body className="divide-y">{rows2}</Table.Body>
</Table>
</td>
</tr>
</table>
</div>
<Button gradientDuoTone="purpleToBlue" className="float-right">
Checkout
</Button>
</div>
</div>
);
}
function getRows(book: DetailedBook) {
const rows: ReactNode[] = [];
Object.entries(book).forEach(([key, value]) => {
if (key === "id") return;
if (key == "last_updated") return;
rows.push(
<Table.Row key={key}>
<Table.Cell>{key}</Table.Cell>
<Table.Cell>{value || "Undefined"}</Table.Cell>
<Table.Cell>
<a
href="#"
className="font-medium text-cyan-600 hover:underline dark:text-cyan-500"
>
Edit
</a>
</Table.Cell>
</Table.Row>
);
});
console.log(rows);
return rows;
}