Skip to content
Permalink
Newer
Older
100644 151 lines (141 sloc) 3.91 KB
October 19, 2023 16:49
1
import {
2
Box,
October 19, 2023 16:49
3
Button,
October 19, 2023 16:49
4
Card,
5
CardBody,
6
CardFooter,
7
CardHeader,
8
Heading,
October 19, 2023 16:49
9
Modal,
10
ModalBody,
11
ModalContent,
12
ModalFooter,
13
ModalHeader,
14
ModalOverlay,
October 19, 2023 16:49
15
Stack,
16
StackDivider,
17
Text,
October 19, 2023 16:49
18
Textarea,
19
useDisclosure,
October 21, 2023 00:05
20
useToast
October 19, 2023 16:49
21
} from "@chakra-ui/react";
22
import { useEffect, useState } from "react";
October 19, 2023 16:49
23
24
export default function(props: AppealCardProps & { port?: MessagePort }) {
25
const [dateString, setDateString] = useState(
October 21, 2023 00:05
26
new Date(props.created_at).toUTCString()
27
);
October 19, 2023 16:49
28
const [action, setAction] = useState("");
29
const [feedback, setFeedback] = useState("");
October 19, 2023 16:50
30
const [loading, setLoading] = useState(false);
October 19, 2023 16:50
31
const toast = useToast();
32
33
useEffect(() => {
34
setDateString(new Date(props.created_at).toLocaleString());
35
}, [props.created_at]);
36
October 19, 2023 16:49
37
const { isOpen, onClose, onOpen } = useDisclosure();
38
39
function showModal(action: "Accept" | "Deny") {
40
setAction(action);
41
onOpen();
42
}
43
44
async function takeAction(action: string) {
October 19, 2023 16:50
45
setLoading(true);
October 19, 2023 16:49
46
const actionReq = await fetch(`/api/appeals/${props.id}/${action}`, {
47
body: feedback ? JSON.stringify({ feedback }) : "{}",
48
headers: {
October 21, 2023 00:05
49
"content-type": "application/json"
October 19, 2023 16:49
50
},
October 21, 2023 00:05
51
method: "POST"
October 19, 2023 16:49
52
});
53
54
if (actionReq.ok) {
October 19, 2023 16:50
55
setLoading(false);
October 19, 2023 16:50
56
toast({
October 19, 2023 16:49
57
description: `Appeal ${action === "accept" ? "accepted" : "denied"}`,
58
duration: 5000,
59
status: "success",
October 21, 2023 00:05
60
title: "Success"
October 19, 2023 16:49
61
});
62
63
document.getElementById(`appeal_${props.id}`)?.remove();
October 19, 2023 16:50
64
} else {
October 19, 2023 16:51
65
let error;
66
67
try {
68
error = ((await actionReq.json()) as { error: string }).error;
69
} catch {
70
error = "Unknown error";
71
}
October 19, 2023 16:50
72
setLoading(false);
October 19, 2023 16:50
73
toast({
October 19, 2023 16:51
74
description: error,
October 19, 2023 16:50
75
duration: 10000,
76
status: "error",
October 21, 2023 00:05
77
title: "Oops!"
October 19, 2023 16:50
78
});
October 19, 2023 16:49
79
}
80
October 19, 2023 16:50
81
onClose();
October 19, 2023 16:50
82
setLoading(false);
83
props.port?.postMessage(`appeal_${props.id}`);
October 19, 2023 16:49
84
}
85
October 19, 2023 16:49
86
return (
October 19, 2023 16:51
87
<Card id={`appeal_${props.id}`} key={props.id} w="100%">
October 19, 2023 16:49
88
<Modal isOpen={isOpen} onClose={onClose}>
89
<ModalOverlay />
90
<ModalContent>
91
<ModalHeader>{action} this appeal?</ModalHeader>
92
<ModalBody>
93
<Text size="xs">Optionally provide feedback</Text>
94
<Textarea
95
onChange={(e) => setFeedback(e.target.value)}
96
placeholder="Your feedback"
97
/>
98
</ModalBody>
99
<ModalFooter>
100
<Button
101
onClick={async () => await takeAction(action.toLowerCase())}
October 19, 2023 16:50
102
isLoading={loading}
October 19, 2023 16:50
103
loadingText="Submitting..."
October 19, 2023 16:49
104
>
105
Submit
106
</Button>
107
</ModalFooter>
108
</ModalContent>
109
</Modal>
October 19, 2023 16:49
110
<CardHeader>
October 19, 2023 16:50
111
<Heading size="md">Appeal for {props.user.username}</Heading>
112
<Text fontSize="xs">ID: {props.user.id}</Text>
October 19, 2023 16:49
113
</CardHeader>
114
<CardBody>
115
<Stack divider={<StackDivider />}>
October 19, 2023 16:49
116
<Box>
October 19, 2023 16:49
117
<Heading size="xs">Response: Why were you banned?</Heading>
118
<Text>{props.ban_reason}</Text>
October 19, 2023 16:49
119
</Box>
October 19, 2023 16:49
120
<Box>
121
<Heading size="xs">Response: Why should we unban you?</Heading>
122
<Text>{props.reason_for_unban}</Text>
123
</Box>
124
<Box>
125
<Heading size="xs">
126
Response: What have you learned from your mistake?
127
</Heading>
128
<Text>{props.learned}</Text>
129
</Box>
130
</Stack>
131
</CardBody>
132
<CardFooter pb="4px">
October 21, 2023 00:05
133
<Box display={props.open ? undefined : "none"}>
October 19, 2023 16:49
134
<Button colorScheme="red" onClick={() => showModal("Deny")}>
135
Deny
136
</Button>
137
<Button
138
colorScheme="blue"
139
ml="8px"
140
onClick={() => showModal("Accept")}
141
>
October 19, 2023 16:49
142
Accept
143
</Button>
144
</Box>
145
</CardFooter>
146
<CardFooter py="4px">
147
<Text fontSize="xs">Submitted at: {dateString}</Text>
148
</CardFooter>
149
</Card>
October 19, 2023 16:49
150
);
151
}