forked from administration/panel
89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
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<User | null>(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 (
|
|
<div>
|
|
<Input
|
|
className="rounded-b-none"
|
|
style={{ boxShadow: "none" }} // doing this with tailwind just... doesnt work
|
|
placeholder="Enter an ID..."
|
|
value={input}
|
|
onChange={(e) => {
|
|
setInput(e.currentTarget.value);
|
|
setSearching(true);
|
|
}}
|
|
/>
|
|
<Card className="border-t-0 rounded-t-none">
|
|
<CardHeader>
|
|
<CardTitle className={`flex items-center gap-1 ${user ? "" : "text-gray-400"}`}>
|
|
<Avatar>
|
|
{user && <AvatarImage src={`${AUTUMN_URL}/avatars/${user.avatar?._id}`} />}
|
|
<AvatarFallback className="overflow-hidden overflow-ellipsis whitespace-nowrap">
|
|
{user
|
|
? (user.display_name ?? user.username)
|
|
.split(" ")
|
|
.slice(0, 2)
|
|
.map((x) => String.fromCodePoint(x.codePointAt(0) ?? 32) ?? "")
|
|
.join("")
|
|
: "?"}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
{user
|
|
? <>{user.username}#{user.discriminator} {user.display_name}</>
|
|
: "User#0000"
|
|
}
|
|
</CardTitle>
|
|
<CardDescription>
|
|
{
|
|
!input
|
|
? "Enter an ID..."
|
|
: input.length != 26
|
|
? "Invalid ID"
|
|
: searching
|
|
? "Searching..."
|
|
: user
|
|
? "User exists!"
|
|
: "Unknown user"
|
|
}
|
|
</CardDescription>
|
|
</CardHeader>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|