80 lines
3.0 KiB
TypeScript
80 lines
3.0 KiB
TypeScript
import { useHotkeys } from "react-hotkeys-hook";
|
|
import { Ico } from "components/Ico";
|
|
import { PageSelector } from "components/Inputs/PageSelector";
|
|
import { atoms } from "contexts/atoms";
|
|
import { isUndefined } from "helpers/asserts";
|
|
import { useAtomGetter } from "helpers/atoms";
|
|
import { useFormat } from "hooks/useFormat";
|
|
import { useScrollTopOnChange } from "hooks/useScrollOnChange";
|
|
import { Ids } from "types/ids";
|
|
|
|
/*
|
|
* ╭─────────────╮
|
|
* ───────────────────────────────────────╯ COMPONENT ╰───────────────────────────────────────────
|
|
*/
|
|
|
|
interface Props {
|
|
page: number;
|
|
onPageChange: (newPage: number) => void;
|
|
totalNumberOfPages: number | null | undefined;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
|
|
|
export const Paginator = ({
|
|
page,
|
|
onPageChange,
|
|
totalNumberOfPages,
|
|
children,
|
|
}: Props): JSX.Element => {
|
|
useScrollTopOnChange(Ids.ContentPanel, [page]);
|
|
useHotkeys("left", () => onPageChange(page - 1), { enabled: page > 1 }, [page]);
|
|
useHotkeys("right", () => onPageChange(page + 1), { enabled: page < (totalNumberOfPages ?? 0) }, [
|
|
page,
|
|
]);
|
|
|
|
if (totalNumberOfPages === 0) return <DefaultRenderWhenEmpty />;
|
|
if (isUndefined(totalNumberOfPages) || totalNumberOfPages < 2) return <>{children}</>;
|
|
|
|
return (
|
|
<>
|
|
<PageSelector
|
|
page={page}
|
|
onChange={onPageChange}
|
|
pagesCount={totalNumberOfPages}
|
|
className="mb-12"
|
|
/>
|
|
{children}
|
|
<PageSelector
|
|
page={page}
|
|
onChange={onPageChange}
|
|
pagesCount={totalNumberOfPages}
|
|
className="mt-12"
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
/*
|
|
* ╭──────────────────────╮
|
|
* ───────────────────────────────────╯ PRIVATE COMPONENTS ╰──────────────────────────────────────
|
|
*/
|
|
|
|
const DefaultRenderWhenEmpty = () => {
|
|
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
|
const { format } = useFormat();
|
|
|
|
return (
|
|
<div className="grid h-full place-content-center">
|
|
<div
|
|
className="grid grid-flow-col place-items-center gap-9 rounded-2xl border-2 border-dotted
|
|
border-dark p-8 text-dark opacity-40">
|
|
{is3ColumnsLayout && <Ico icon="chevron_left" className="!text-[300%]" />}
|
|
<p className="max-w-xs text-2xl">{format("no_results_message")}</p>
|
|
{!is3ColumnsLayout && <Ico icon="chevron_right" className="!text-[300%]" />}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|