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

119 lines
2.9 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 UserCard from "../user-card";
import type { User } from "@/server/db/schema";
const SearchResultCard = ({
addFriend,
user,
pending,
}: {
addFriend: (userId: string) => void;
pending: boolean;
user: User;
}) => {
return (
<UserCard user={user}>
<Button
size={"sm"}
className="ml-auto"
variant={"outline"}
disabled={pending}
onClick={() => {
if (!pending) addFriend(user.id!);
}}
>
{pending ? "Pending" : "Add Friend"}
</Button>
</UserCard>
);
};
export default function AddFriendDrawer() {
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.friend.search.useQuery(
{
search: searchValue,
},
{
enabled: !!searchValue,
}
);
const addFriend = api.friend.add.useMutation({
onSuccess() {
toast.success("Friend request sent!");
setOpen(false);
setValue("");
utils.friend.getAll.invalidate();
},
});
const handleAddFriend = (userId: string) => {
addFriend.mutate({
userId,
});
};
return (
<Drawer open={open} onOpenChange={setOpen}>
<DrawerTrigger asChild>
<Button size={"sm"}>Add Friend</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Add a friend</DrawerTitle>
</DrawerHeader>
<div className="px-4 space-y-4">
<Input
autoFocus
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
placeholder="Search for a friend"
/>
<ul>
{isFetching ? (
<Skeleton className="h-6 w-full" />
) : searchResult?.length ? (
searchResult.map((res) => (
<li key={res.user.id}>
<SearchResultCard addFriend={handleAddFriend} {...res} />
</li>
))
) : (
<p className="text-muted-foreground text-sm">
{searchValue.length
? "No results found"
: "Start typing to search for a friend"}
</p>
)}
</ul>
</div>
<DrawerFooter>
<DrawerClose asChild>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
);
}