From 44089ee019fb0cfd02da6cfb9bde71ed0af2cfdb Mon Sep 17 00:00:00 2001 From: Regalijan Date: Sun, 27 Oct 2024 01:35:55 -0400 Subject: [PATCH] Create short links page --- app/routes/short-links.tsx | 117 +++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 app/routes/short-links.tsx diff --git a/app/routes/short-links.tsx b/app/routes/short-links.tsx new file mode 100644 index 0000000..2c2f823 --- /dev/null +++ b/app/routes/short-links.tsx @@ -0,0 +1,117 @@ +import { + Button, + Container, + Heading, + Link, + Table, + TableCaption, + TableContainer, + Tbody, + Td, + Th, + Thead, + Tr, + useToast, +} from "@chakra-ui/react"; +import { useLoaderData } from "@remix-run/react"; + +export function meta() { + return [ + { + title: "Short Link Manager - Car Crushers", + }, + ]; +} + +export async function loader({ context }: { context: RequestContext }) { + const userId = context.data.current_user?.id; + + if (!userId) + throw new Response(null, { + status: 401, + }); + + if ( + ![0, 2, 4, 5, 6, 7, 9, 10, 11, 12].find( + (i) => context.data.current_user.permissions & (1 << i), + ) + ) + throw new Response(null, { + status: 403, + }); + + const { results } = await context.env.D1.prepare( + "SELECT destination, path FROM short_links WHERE user = ?;", + ) + .bind(userId) + .all(); + + return results as Record[]; +} + +export default function () { + const data = useLoaderData(); + const toast = useToast(); + + async function deleteLink(path: string) { + const deleteResp = await fetch(`/api/short-links/${path}`, { + method: "DELETE", + }); + + if (!deleteResp.ok) { + let error = "Unknown error"; + + try { + error = ((await deleteResp.json()) as { error: string }).error; + } catch {} + + toast({ + description: error, + status: "error", + title: "Failed to delete link", + }); + + return; + } + + toast({ + description: `Link ${path} was successfully deleted.`, + status: "success", + title: "Deleted", + }); + } + + return ( + + Short Links + + + Your short links + + + + + + + + + {data.map((entry) => { + return ( + + + + + + ); + })} + +
DestinationCodeDelete
{entry.destination}{entry.path} + +
+
+ + Create a new link + +
+ ); +}