118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
/* eslint-disable no-constant-binary-expression */
|
|
"use client";
|
|
import { checkingApi } from "@/api/checking-api";
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { Card } from "@/components/ui/card";
|
|
import { TabsContent } from "@/components/ui/tabs";
|
|
import { cn } from "@/lib/utils";
|
|
import useUserStore from "@/stores/use-user-store";
|
|
import { Users } from "lucide-react";
|
|
import { useEffect, useState } from "react";
|
|
|
|
export default function TabUsers({ value }: { value: string }) {
|
|
const [users, setUsers] = useState<IUser[]>([]);
|
|
const { currentUser, setCurrentUser } = useUserStore();
|
|
|
|
const loadUsers = async () => {
|
|
try {
|
|
const { data } = await checkingApi.users();
|
|
|
|
setUsers(data);
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
};
|
|
|
|
const toggle = (data: IUser) => {
|
|
if (currentUser) {
|
|
if (data.id === currentUser.id) {
|
|
setCurrentUser(null);
|
|
} else {
|
|
setCurrentUser(data);
|
|
}
|
|
} else {
|
|
setCurrentUser(data);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
loadUsers();
|
|
}, []);
|
|
|
|
return (
|
|
<TabsContent value={value} className="">
|
|
<div className="flex flex-col gap-2 flex-1 p-4 space-y-2 overflow-y-auto h-[90vh]">
|
|
{users.map((user) => (
|
|
<Card
|
|
key={user.id}
|
|
className={cn(
|
|
"p-4 cursor-pointer transition-all duration-200 hover:shadow-md hover:scale-[1.01] select-none",
|
|
currentUser?.id === user.id &&
|
|
"bg-blue-50 dark:bg-blue-950 border-blue-500 shadow-md"
|
|
)}
|
|
onClick={() => toggle(user)}
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<Avatar className="size-12">
|
|
<AvatarImage
|
|
src={
|
|
`https://ms.prology.net/image/storage/${user?.avatar}` || ""
|
|
}
|
|
/>
|
|
<AvatarFallback> {user.name.charAt(0)}</AvatarFallback>
|
|
</Avatar>
|
|
|
|
<div className="flex-1">
|
|
<h4 className="font-semibold text-gray-900 dark:text-gray-100">
|
|
{user.name}
|
|
</h4>
|
|
<p className="text-sm text-gray-600 dark:text-gray-400">
|
|
{user.email}
|
|
</p>
|
|
</div>
|
|
|
|
{/* <DropdownMenu>
|
|
<DropdownMenuTrigger
|
|
asChild
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<Button variant="ghost" size="icon" className="h-8 w-8">
|
|
<MoreVertical className="h-4 w-4" />
|
|
<span className="sr-only">Mở menu</span>
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end" className="w-48">
|
|
<DropdownMenuItem onClick={(e) => handleViewDetails(user, e)}>
|
|
<UserCheck className="mr-2 h-4 w-4" />
|
|
<span>Xem chi tiết</span>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem onClick={(e) => handleEdit(user, e)}>
|
|
<Edit className="mr-2 h-4 w-4" />
|
|
<span>Chỉnh sửa</span>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem
|
|
onClick={(e) => handleDelete(user, e)}
|
|
className="text-red-600 focus:text-red-600 dark:text-red-400 dark:focus:text-red-400"
|
|
>
|
|
<Trash2 className="mr-2 h-4 w-4" />
|
|
<span>Xóa</span>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu> */}
|
|
</div>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
|
|
{users.length <= 0 && (
|
|
<div className="flex flex-col items-center justify-center h-full text-gray-400">
|
|
<Users className="size-16 mb-3" />
|
|
<p>Chưa có dữ liệu điểm danh</p>
|
|
</div>
|
|
)}
|
|
</TabsContent>
|
|
);
|
|
}
|