Add modal to add et members
This commit is contained in:
parent
d8b6bc406a
commit
e5fbdb953c
@ -3,6 +3,7 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Container,
|
Container,
|
||||||
Heading,
|
Heading,
|
||||||
|
Input,
|
||||||
Link,
|
Link,
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
@ -28,7 +29,7 @@ import {
|
|||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { useState } from "react";
|
import { FormEvent, useState } from "react";
|
||||||
|
|
||||||
export async function loader({ context }: { context: RequestContext }) {
|
export async function loader({ context }: { context: RequestContext }) {
|
||||||
if (!context.data.current_user)
|
if (!context.data.current_user)
|
||||||
@ -54,7 +55,10 @@ export async function loader({ context }: { context: RequestContext }) {
|
|||||||
status: 500,
|
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 () {
|
export default function () {
|
||||||
@ -88,17 +92,58 @@ export default function () {
|
|||||||
setMemberData(memberData.filter((member) => member.id !== id));
|
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 [realtimePoints, setRealtimePoints] = useState(0);
|
||||||
const [currentModalMember, setModalMember] = useState("");
|
const [currentModalMember, setModalMember] = useState("");
|
||||||
const [currentDelMember, setDelMember] = useState({ id: "", name: "" });
|
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, onClose, onOpen } = useDisclosure();
|
||||||
const {
|
const {
|
||||||
isOpen: isDelConfirmOpen,
|
isOpen: isDelConfirmOpen,
|
||||||
onClose: closeDelConfirm,
|
onClose: closeDelConfirm,
|
||||||
onOpen: openDelConfirm,
|
onOpen: openDelConfirm,
|
||||||
} = useDisclosure();
|
} = 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) {
|
async function updatePoints(id: string, points: number) {
|
||||||
const updateResp = await fetch(`/api/events-team/points/${id}`, {
|
const updateResp = await fetch(`/api/events-team/points/${id}`, {
|
||||||
@ -216,6 +261,67 @@ export default function () {
|
|||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
</Modal>
|
</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>
|
<Heading>Events Team Members</Heading>
|
||||||
<TableContainer pt="16px">
|
<TableContainer pt="16px">
|
||||||
<Table variant="simple">
|
<Table variant="simple">
|
||||||
@ -252,20 +358,27 @@ export default function () {
|
|||||||
)}
|
)}
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<Link
|
{isManagement ? (
|
||||||
onClick={() => {
|
<Link
|
||||||
setDelMember({ id: member.id, name: member.name });
|
onClick={() => {
|
||||||
openDelConfirm();
|
setDelMember({ id: member.id, name: member.name });
|
||||||
}}
|
openDelConfirm();
|
||||||
>
|
}}
|
||||||
Remove
|
>
|
||||||
</Link>
|
Remove
|
||||||
|
</Link>
|
||||||
|
) : null}
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
))}
|
))}
|
||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
{isManagement ? (
|
||||||
|
<Link color="#646cff" onClick={openAddMember} pt="16px">
|
||||||
|
Add Member
|
||||||
|
</Link>
|
||||||
|
) : null}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user