Skip to content
Permalink
19a7dbb6e5
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
242 lines (219 sloc) 5.73 KB
import {
Button,
Container,
Heading,
Link,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Table,
TableContainer,
Tbody,
Td,
Text,
Textarea,
Th,
Thead,
Tr,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import { LoaderFunctionArgs } from "@remix-run/cloudflare";
import { useLoaderData } from "@remix-run/react";
import { useState } from "react";
export async function loader({
context,
params,
}: {
context: RequestContext;
params: LoaderFunctionArgs & { uid: string };
}) {
const { current_user: user } = context.data;
if (!user)
throw new Response(null, {
status: 401,
});
if (![1 << 3, 1 << 4, 1 << 12].find((p) => user.permissions & p))
throw new Response(null, {
status: 403,
});
const strikeData = await context.env.D1.prepare(
"SELECT * FROM et_strikes WHERE user = ?;",
)
.bind(params.uid)
.all();
return {
can_manage: Boolean([1 << 4, 1 << 12].find((p) => user.permissions & p)),
strikes: strikeData.results,
user: params.uid,
};
}
export default function () {
const { can_manage, strikes, user } = useLoaderData<typeof loader>();
const [strikeData, setStrikeData] = useState(strikes);
const toast = useToast();
const [rmStrikeId, setRmStrikeId] = useState("");
const [strikeReason, setStrikeReason] = useState("");
async function removeStrike(id: string) {
const removeResp = await fetch(`/api/events-team/strikes/${id}`, {
method: "DELETE",
});
if (!removeResp.ok) {
let msg = "Unknown error";
try {
msg = ((await removeResp.json()) as { error: string }).error;
} catch {}
toast({
description: msg,
status: "error",
title: "Failed to remove strike",
});
return;
}
toast({
description: `Strike ${id} was removed`,
status: "success",
title: "Strike Removed",
});
setStrikeData(strikeData.filter((strike) => strike.id !== id));
closeRmStrike();
}
async function addStrike() {
const addStrikeResp = await fetch("/api/events-team/strikes/new", {
body: JSON.stringify({
reason: strikeReason,
user,
}),
headers: {
"content-type": "application/json",
},
method: "POST",
});
if (!addStrikeResp.ok) {
let msg = "Unknown error";
try {
msg = ((await addStrikeResp.json()) as { error: string }).error;
} catch {}
toast({
description: msg,
status: "error",
title: "Failed to add strike",
});
return;
}
toast({
description: "Strike added",
status: "success",
title: "Success",
});
const newStrikeData = strikeData;
newStrikeData.push(await addStrikeResp.json());
setStrikeData(newStrikeData);
closeAddStrike();
}
const {
isOpen: rmStrikeOpen,
onClose: closeRmStrike,
onOpen: openRmStrike,
} = useDisclosure();
const {
isOpen: addStrikeOpen,
onClose: closeAddStrike,
onOpen: openAddStrike,
} = useDisclosure();
return (
<Container maxW="container.lg">
<Modal isOpen={rmStrikeOpen} onClose={closeRmStrike}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Remove Strike</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text>Are you sure you want to remove this strike?</Text>
</ModalBody>
<ModalFooter>
<Button mr="8px">No</Button>
<Button
colorScheme="red"
onClick={async () => await removeStrike(rmStrikeId)}
>
Yes
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<Modal isOpen={addStrikeOpen} onClose={closeAddStrike}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Add Strike</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Heading mb="8px" size="xs">
Reason
</Heading>
<Textarea
onChange={(e) => setStrikeReason(e.target.value)}
placeholder="Strike reason"
value={strikeReason}
/>
</ModalBody>
<ModalFooter>
<Button
mr="8px"
onClick={() => {
closeAddStrike();
setStrikeReason("");
}}
>
Cancel
</Button>
<Button colorScheme="red" onClick={async () => await addStrike()}>
Add Strike
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<Heading my="16px">Strikes</Heading>
<TableContainer>
<Table variant="simple">
<Thead>
<Tr>
<Th>Time Added</Th>
<Th>Added By</Th>
<Th>Reason</Th>
<Th>Remove</Th>
</Tr>
</Thead>
<Tbody>
{strikeData.map((strike: { [k: string]: any }) => (
<Tr>
<Td>{new Date(strike.created_at).toUTCString()}</Td>
<Td>{strike.created_by}</Td>
<Td>{strike.reason}</Td>
<Td>
{can_manage ? (
<Link
onClick={() => {
setRmStrikeId(strike.id);
openRmStrike();
}}
>
Remove
</Link>
) : null}
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
<Link color="#646cff" onClick={openAddStrike} py="16px">
Add Strike
</Link>
</Container>
);
}