129 lines
3.2 KiB
TypeScript

import {
Link,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import { useEffect, useState } from "react";
import NewAppealBan from "./NewAppealBan.js";
import { useLoaderData } from "@remix-run/react";
export async function loader({ context }: { context: RequestContext }) {
const list = (
await context.env.D1.prepare(
"SELECT * FROM appeal_bans ORDER BY created_at DESC;",
).all()
).results as {
created_at: number | string;
created_by: string;
user: string;
}[];
for (const row of list)
row.created_at = new Date(row.created_at).toUTCString();
return list;
}
export default function (props: { isOpen: boolean; onClose: () => void }) {
const [entries, setEntries] = useState(
[] as { created_at: number | string; created_by: string; user: string }[],
);
const toast = useToast();
const { isOpen, onClose, onOpen } = useDisclosure();
setEntries(useLoaderData<typeof loader>());
async function removeBan(user: string) {
const removeResp = await fetch(`/api/appeals/${user}/ban`, {
method: "DELETE",
});
if (!removeResp.ok) {
let error;
try {
error = ((await removeResp.json()) as { error: string }).error;
} catch {
error = "Unknown error";
}
toast({
description: error,
isClosable: true,
status: "error",
title: "Failed to remove member",
});
return;
}
toast({
description: `User ${user} removed`,
isClosable: true,
status: "success",
title: "Success",
});
setEntries([...entries].filter((entry) => entry.user !== user));
}
useEffect(() => {}, []);
return (
<>
<Modal isCentered isOpen={props.isOpen} onClose={props.onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Appeal Bans</ModalHeader>
<ModalCloseButton />
<ModalBody>
<TableContainer>
<Table variant="simple">
<Thead>
<Tr>
<Th>User</Th>
<Th>Moderator</Th>
<Th>Time</Th>
<Th>Remove</Th>
</Tr>
</Thead>
<Tbody>
{entries.map((entry) => (
<Tr>
<Td>{entry.user}</Td>
<Td>{entry.created_by}</Td>
<Td>{new Date(entry.created_at).toUTCString()}</Td>
<Td>
<Link onClick={async () => await removeBan(entry.user)}>
Remove
</Link>
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</ModalBody>
<ModalFooter>
<Link onClick={onOpen}>Click here to ban someone</Link>
</ModalFooter>
</ModalContent>
</Modal>
<NewAppealBan isOpen={isOpen} onClose={onClose} />
</>
);
}