diff --git a/components/pages/inspector/ServerActions.tsx b/components/pages/inspector/ServerActions.tsx index 618663e..422e1f9 100644 --- a/components/pages/inspector/ServerActions.tsx +++ b/components/pages/inspector/ServerActions.tsx @@ -1,6 +1,6 @@ "use client"; -import { Server } from "revolt-api"; +import { Server, User } from "revolt-api"; import { Button, buttonVariants } from "../../ui/button"; import { Command, @@ -22,12 +22,13 @@ import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"; import { Input } from "@/components/ui/input"; import { Checkbox } from "@/components/ui/checkbox"; +import UserSelector from "@/components/ui/user-selector"; export function ServerActions({ server }: { server: Server }) { const [selectBadges, setSelectBadges] = useState(false); const [serverDraft, setDraft] = useState(server); - const [newOwner, setNewOwner] = useState(""); - const [newMember, setNewMember] = useState(""); + const [newOwner, setNewOwner] = useState(null); + const [newMember, setNewMember] = useState(null); const [newMemberEvent, setNewMemberEvent] = useState(true); const { toast } = useToast(); @@ -167,21 +168,19 @@ export function ServerActions({ server }: { server: Server }) { Enter the ID of the new server owner. - setNewOwner(e.currentTarget.value)} + setNewOwner(user)} /> Cancel { try { - await updateServerOwner(server._id, newOwner); - setNewOwner(""); + await updateServerOwner(server._id, newOwner!._id); + setNewOwner(null); toast({ title: "Server owner changed" }); } catch(e) { toast({ @@ -211,22 +210,18 @@ export function ServerActions({ server }: { server: Server }) { Enter the ID of the user you want to add. - setNewMember(e.currentTarget.value)} - /> + setNewMember(user)} /> setNewMemberEvent(state === true)}>Publish join event Cancel { try { - await addServerMember(server._id, newMember, newMemberEvent); - setNewMember(""); + await addServerMember(server._id, newMember!._id, newMemberEvent); + setNewMember(null); toast({ title: "User added to server" }); } catch(e) { toast({ diff --git a/components/ui/user-selector.tsx b/components/ui/user-selector.tsx new file mode 100644 index 0000000..a332d53 --- /dev/null +++ b/components/ui/user-selector.tsx @@ -0,0 +1,88 @@ +import { useEffect, useState } from "react"; +import { Input } from "./input"; +import { Card, CardDescription, CardHeader, CardTitle } from "./card"; +import { Avatar, AvatarFallback, AvatarImage } from "./avatar"; +import { User } from "revolt-api"; +import { AUTUMN_URL } from "@/lib/constants"; +import { fetchUserById } from "@/lib/db"; + +export default function UserSelector({ onChange }: { + onChange?: (user: User | null) => any, +}) { + const [input, setInput] = useState(""); + const [user, setUser] = useState(null); + const [searching, setSearching] = useState(false); + + useEffect(() => { + if (input.length != 26) { + onChange?.(null); + if (user) setUser(null); + return; + } + if (!searching) return; + if (input != user?._id) { + setSearching(true); + fetchUserById(input) + .then((user) => { + setUser(user); + onChange?.(user); + }) + .catch((e) => { + setUser(null); + onChange?.(null); + }) + .finally(() => setSearching(false)); + } + else setUser(null); + }, [input, user, searching, onChange]); + + return ( +
+ { + setInput(e.currentTarget.value); + setSearching(true); + }} + /> + + + + + {user && } + + {user + ? (user.display_name ?? user.username) + .split(" ") + .slice(0, 2) + .map((x) => String.fromCodePoint(x.codePointAt(0) ?? 32) ?? "") + .join("") + : "?"} + + + {user + ? <>{user.username}#{user.discriminator} {user.display_name} + : "User#0000" + } + + + { + !input + ? "Enter an ID..." + : input.length != 26 + ? "Invalid ID" + : searching + ? "Searching..." + : user + ? "User exists!" + : "Unknown user" + } + + + +
+ ) +}