Add modal to add et members
This commit is contained in:
parent
d8b6bc406a
commit
e5fbdb953c
@ -3,6 +3,7 @@ import {
|
||||
Button,
|
||||
Container,
|
||||
Heading,
|
||||
Input,
|
||||
Link,
|
||||
Modal,
|
||||
ModalBody,
|
||||
@ -28,7 +29,7 @@ import {
|
||||
useDisclosure,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import { useState } from "react";
|
||||
import { FormEvent, useState } from "react";
|
||||
|
||||
export async function loader({ context }: { context: RequestContext }) {
|
||||
if (!context.data.current_user)
|
||||
@ -54,7 +55,10 @@ export async function loader({ context }: { context: RequestContext }) {
|
||||
status: 500,
|
||||
});
|
||||
|
||||
return etData.results as { [k: string]: any }[];
|
||||
return { can_manage: true, members: etData.results } as {
|
||||
can_manage: boolean;
|
||||
members: { [k: string]: any }[];
|
||||
};
|
||||
}
|
||||
|
||||
export default function () {
|
||||
@ -88,17 +92,58 @@ export default function () {
|
||||
setMemberData(memberData.filter((member) => member.id !== id));
|
||||
}
|
||||
|
||||
async function addMember() {
|
||||
const addResp = await fetch("/api/events-team/team-members/user", {
|
||||
body: JSON.stringify({
|
||||
id: addingMemberId,
|
||||
name: addingMemberName,
|
||||
roblox_username: addingMemberRoblox,
|
||||
}),
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
});
|
||||
|
||||
if (!addResp.ok) {
|
||||
toast({
|
||||
description: "Failed to add member, try again later",
|
||||
status: "error",
|
||||
title: "Oops",
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
toast({
|
||||
description: `Member ${addingMemberName} was added to the roster`,
|
||||
status: "success",
|
||||
title: "Member Added",
|
||||
});
|
||||
|
||||
location.reload();
|
||||
}
|
||||
|
||||
const data = useLoaderData<typeof loader>();
|
||||
const [realtimePoints, setRealtimePoints] = useState(0);
|
||||
const [currentModalMember, setModalMember] = useState("");
|
||||
const [currentDelMember, setDelMember] = useState({ id: "", name: "" });
|
||||
const [memberData, setMemberData] = useState(useLoaderData<typeof loader>());
|
||||
const [memberData, setMemberData] = useState(data.members);
|
||||
const [addingMemberId, setAddingMemberId] = useState("");
|
||||
const [addingMemberName, setAddingMemberName] = useState("");
|
||||
const [addingMemberRoblox, setAddingMemberRoblox] = useState("");
|
||||
const { isOpen, onClose, onOpen } = useDisclosure();
|
||||
const {
|
||||
isOpen: isDelConfirmOpen,
|
||||
onClose: closeDelConfirm,
|
||||
onOpen: openDelConfirm,
|
||||
} = useDisclosure();
|
||||
const isManagement = Math.round(Math.random()) === 1;
|
||||
const {
|
||||
isOpen: isAddMemberOpen,
|
||||
onClose: closeAddMember,
|
||||
onOpen: openAddMember,
|
||||
} = useDisclosure();
|
||||
const isManagement = data.can_manage;
|
||||
|
||||
async function updatePoints(id: string, points: number) {
|
||||
const updateResp = await fetch(`/api/events-team/points/${id}`, {
|
||||
@ -216,6 +261,67 @@ export default function () {
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
<Modal isOpen={isAddMemberOpen} onClose={closeAddMember}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Add Member</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<Heading size="xs">User ID</Heading>
|
||||
<Input
|
||||
maxLength={19}
|
||||
onBeforeInput={(e) => {
|
||||
const {
|
||||
data,
|
||||
}: { data?: string } & FormEvent<HTMLInputElement> = e;
|
||||
|
||||
if (data?.match(/\D/)) e.preventDefault();
|
||||
}}
|
||||
onChange={(e) => setAddingMemberId(e.target.value)}
|
||||
pb="16px"
|
||||
type="number"
|
||||
/>
|
||||
<Heading size="xs">Name</Heading>
|
||||
<Input
|
||||
maxLength={64}
|
||||
onChange={(e) => setAddingMemberName(e.target.value)}
|
||||
pb="16px"
|
||||
/>
|
||||
<Heading size="xs">Roblox Username (optional)</Heading>
|
||||
<Input
|
||||
maxLength={20}
|
||||
onBeforeInput={(e) => {
|
||||
const {
|
||||
data,
|
||||
}: { data?: string } & FormEvent<HTMLInputElement> = e;
|
||||
|
||||
if (!data) return;
|
||||
|
||||
if (
|
||||
data.match(/\W/) ||
|
||||
data.length > 20 ||
|
||||
data.length < 4 ||
|
||||
(data.match(/_/g)?.length || 0) > 1 ||
|
||||
data.startsWith("_") ||
|
||||
data.endsWith("_")
|
||||
)
|
||||
e.preventDefault();
|
||||
}}
|
||||
onChange={(e) => setAddingMemberRoblox(e.target.value)}
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button onClick={closeAddMember}>Close</Button>
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
onClick={async () => await addMember()}
|
||||
pl="8px"
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
<Heading>Events Team Members</Heading>
|
||||
<TableContainer pt="16px">
|
||||
<Table variant="simple">
|
||||
@ -252,20 +358,27 @@ export default function () {
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
<Link
|
||||
onClick={() => {
|
||||
setDelMember({ id: member.id, name: member.name });
|
||||
openDelConfirm();
|
||||
}}
|
||||
>
|
||||
Remove
|
||||
</Link>
|
||||
{isManagement ? (
|
||||
<Link
|
||||
onClick={() => {
|
||||
setDelMember({ id: member.id, name: member.name });
|
||||
openDelConfirm();
|
||||
}}
|
||||
>
|
||||
Remove
|
||||
</Link>
|
||||
) : null}
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
{isManagement ? (
|
||||
<Link color="#646cff" onClick={openAddMember} pt="16px">
|
||||
Add Member
|
||||
</Link>
|
||||
) : null}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user