Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Create short link creation page
  • Loading branch information
regalijan committed Nov 1, 2024
1 parent 4b42a17 commit f040e8f
Showing 1 changed file with 113 additions and 0 deletions.
113 changes: 113 additions & 0 deletions app/routes/short-links_.create.tsx
@@ -0,0 +1,113 @@
import {
Container,
FormControl,
FormHelperText,
FormLabel,
Heading,
Input,
useToast,
} from "@chakra-ui/react";
import { useLoaderData } from "@remix-run/react";
import { useState } from "react";

export function meta() {
return [
{
title: "Create a Short Link",
},
];
}

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,
});

return null;
}

export default function () {
useLoaderData<typeof loader>();
const [destination, setDestination] = useState("");
const [code, setCode] = useState("");
const toast = useToast();

async function createLink() {
// Create random 14 character string if no code is provided
const linkCode =
code ||
Array.from(Array(14), () =>
Math.floor(Math.random() * 36).toString(36),
).join("");

const createResp = await fetch("/api/short-links/new", {
body: JSON.stringify({ destination, path: linkCode }),
headers: {
"content-type": "application/json",
},
method: "POST",
});

if (!createResp.ok) {
let error = "Unknown error";

try {
error = ((await createResp.json()) as { error: string }).error;
} catch {}

toast({
description: error,
status: "error",
title: "Failed to create link",
});

return;
}

toast({
description: "You will momentarily be redirected to the short links page",
onCloseComplete: () => location.assign("/short-links"),
status: "success",
title: "Link created",
});
}

return (
<Container maxW="container.md">
<Heading size="xl">Create a Link</Heading>
<FormControl isRequired mt="16px">
<FormLabel>Destination URL</FormLabel>
<Input
onChange={(e) => setDestination(e.target.value)}
type="url"
value={destination}
/>
</FormControl>
<FormControl mt="16px">
<FormLabel>Link Code</FormLabel>
<Input
maxLength={256}
onChange={(e) => setCode(e.target.value)}
placeholder="totally-not-a-rickroll"
value={code}
/>
<FormHelperText>
Your custom link code. One will be automatically generated if you do
not provide one. Max 256 characters.
</FormHelperText>
</FormControl>
</Container>
);
}

0 comments on commit f040e8f

Please sign in to comment.