import axios from "axios"; import { useEffect, useState } from "react"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, } from "@/components/ui/sheet" import { z } from "zod"; import { Trash2 } from "lucide-react"; import RoleGate from "@/components/auth/role-gate"; interface UsersGroup { groupId: string groupName: string } const ITEMS_PER_PAGE: number = 10; const usernameSchema = z.string({ required_error: "Name is required.", invalid_type_error: "Name must be a string" }).regex(/^[\w\-]{4,25}$/, "Invalid Twitch username.") const UserList = ({ groupId, groupName }: UsersGroup) => { const [usersListOpen, setUsersListOpen] = useState(false) const [users, setUsers] = useState<{ id: number, username: string }[]>([]) const [addedUsers, setAddedUsers] = useState<{ id: number, username: string }[]>([]) const [deletedUsers, setDeletedUsers] = useState<{ id: number, username: string }[]>([]) const [newUser, setNewUser] = useState("") const [knownUsers, setKnownUsers] = useState<{ id: number, username: string }[]>([]) const [error, setError] = useState(undefined) const [page, setPage] = useState(0) const [maxPages, setMaxPages] = useState(1) useEffect(() => { axios.get('/api/settings/groups/chatters', { params: { groupId, page } }).then(d => { setUsers(d.data) setKnownUsers(d.data) var maxPages = Math.ceil(d.data.length / ITEMS_PER_PAGE) setMaxPages(maxPages) }) }, [groupId, page]) function close() { setUsers([...users.filter(u => !addedUsers.find(a => a.id == u.id)), ...deletedUsers]) setUsersListOpen(false) } function AddUsername() { setError(undefined) const usernameValidation = usernameSchema.safeParse(newUser) if (!usernameValidation.success) { setError(JSON.parse(usernameValidation.error['message'])[0].message) return } if (users.find(u => u.username == newUser.toLowerCase())) { setError("Username is already in this group.") return; } let user = knownUsers.find(u => u.username == newUser.toLowerCase()) if (!user) { axios.get('/api/settings/groups/twitchchatters', { params: { logins: newUser } }).then(d => { if (!d.data) { setError("That was not a known Twitch username.") return } user = d.data[0] if (!user) { setError("That was not a known Twitch username.") return } if (deletedUsers.find(u => u.id == user!.id)) setDeletedUsers(deletedUsers.filter(u => u.id != user!.id)) else setAddedUsers([...addedUsers, user]) setUsers([...users, user]) setKnownUsers([...users, user]) setNewUser("") setMaxPages(Math.ceil((users.length + 1) / ITEMS_PER_PAGE)) }).catch(e => { setError("That was not a known Twitch username.") }) return } if (deletedUsers.find(u => u.id == user!.id)) setDeletedUsers(deletedUsers.filter(u => u.id != user!.id)) else setAddedUsers([...addedUsers, user]) setUsers([...users, user]) setNewUser("") setMaxPages(Math.ceil((users.length + 1) / ITEMS_PER_PAGE)) if (deletedUsers.find(u => u.id == user!.id)) { setAddedUsers(addedUsers.filter(u => u.username != newUser.toLowerCase())) } } function DeleteUser(user: { id: number, username: string }) { if (addedUsers.find(u => u.id == user.id)) { setAddedUsers(addedUsers.filter(u => u.id != user.id)) } else { setDeletedUsers([...deletedUsers, user]) } setUsers(users.filter(u => u.id != user.id)) } function save() { setError(undefined) if (addedUsers.length > 0) { axios.post("/api/settings/groups/chatters", { groupId, users: addedUsers }).then(d => { setAddedUsers([]) if (deletedUsers.length > 0) axios.delete("/api/settings/groups/chatters", { params: { groupId, ids: deletedUsers.map(i => i.id.toString()).reduce((a, b) => a + ',' + b) } }).then(d => { setDeletedUsers([]) }).catch(() => { setError("Something went wrong.") }) }).catch(() => { setError("Something went wrong.") }) return } if (deletedUsers.length > 0) axios.delete("/api/settings/groups/chatters", { params: { groupId, ids: deletedUsers.map(i => i.id.toString()).reduce((a, b) => a + ',' + b) } }).then(d => { setDeletedUsers([]) }).catch(() => { setError("Something went wrong.") }) } return ( Edit group - {groupName} Make changes to this group's list of users. {!!error &&

{error}

}
setNewUser(e.target.value)} className="col-span-3" />

Id Username Delete {users.length ? ( users.slice(ITEMS_PER_PAGE * page, ITEMS_PER_PAGE * (page + 1)).map((user) => ( {user.id} {user.username} )) ) : ( No results. )}
); } export default UserList;