Bettersplit/src/app/_components/group/add-to-group-drawer.tsx
2025-04-13 22:19:54 +02:00

127 lines
3.0 KiB
TypeScript

"use client";
import React from "react";
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
import { Button } from "@/components/ui/button";
import { api } from "@/trpc/react";
import { Input } from "@/components/ui/input";
import { useDebounce } from "use-debounce";
import { Skeleton } from "@/components/ui/skeleton";
import { toast } from "sonner";
import type { User } from "@/server/db/schema";
import UserCard from "../user-card";
const SearchResultCard = ({
addUser,
user,
}: {
addUser: (userId: string) => void;
user: User;
}) => {
return (
<UserCard user={user}>
<Button
size={"sm"}
className="ml-auto"
variant={"outline"}
onClick={() => {
addUser(user.id!);
}}
>
Add
</Button>
</UserCard>
);
};
export default function AddToGroupDrawer({
groupId,
className,
}: {
groupId: string;
className?: string;
}) {
const utils = api.useUtils();
const [open, setOpen] = React.useState(false);
const [value, setValue] = React.useState("");
const [searchValue] = useDebounce(value, 1000);
const { data: searchResult, isFetching } = api.user.search.useQuery(
{
search: searchValue,
},
{
enabled: !!searchValue,
}
);
const addFriend = api.group.addMember.useMutation({
onSuccess() {
toast.success("User added to group.");
setOpen(false);
setValue("");
utils.group.get.invalidate();
utils.group.getAll.invalidate();
},
});
const handleAddFriend = (userId: string) => {
addFriend.mutate({
groupId,
userId,
});
};
return (
<Drawer open={open} onOpenChange={setOpen}>
<DrawerTrigger asChild>
<Button size={"sm"} className={className}>
Add People
</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Add a user to group</DrawerTitle>
</DrawerHeader>
<div className="px-4 space-y-4">
<Input
autoFocus
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
placeholder="Search for a user"
/>
<ul className="space-y-2">
{isFetching ? (
<Skeleton className="h-6 w-full" />
) : searchResult?.length ? (
searchResult.map((user) => (
<li key={user.id}>
<SearchResultCard addUser={handleAddFriend} user={user} />
</li>
))
) : (
<p className="text-muted-foreground text-sm">
{searchValue.length
? "No results found"
: "Start typing to search for a user"}
</p>
)}
</ul>
</div>
<DrawerFooter>
<DrawerClose asChild>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
);
}