Create short link creation page
This commit is contained in:
parent
4b42a173bf
commit
f040e8f160
113
app/routes/short-links_.create.tsx
Normal file
113
app/routes/short-links_.create.tsx
Normal file
@ -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>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user