127 lines
3.0 KiB
TypeScript
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>
|
|
);
|
|
}
|