Fixed creation of users + better frontend handling of permissions
This commit is contained in:
@@ -10,21 +10,19 @@ import {
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import MemberDialog, { Member } from "./member-dialog";
|
||||
import { useApi } from "@/hooks/use-api";
|
||||
import request from "@/lib/request";
|
||||
import {
|
||||
CircleX,
|
||||
Loader2,
|
||||
Trash2,
|
||||
UserRoundPen,
|
||||
UserRoundPlus,
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Loader2, MoreHorizontal, UserRoundPlus } from "lucide-react";
|
||||
import IUser from "@/interfaces/IUser";
|
||||
import hasPermissions from "@/lib/hasPermissions";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "./ui/dropdown-menu";
|
||||
|
||||
export default function MembersTable({ user }: { user: IUser }) {
|
||||
const {
|
||||
@@ -34,23 +32,12 @@ export default function MembersTable({ user }: { user: IUser }) {
|
||||
success,
|
||||
isLoading,
|
||||
} = useApi<Member[]>("/users", undefined, true, false);
|
||||
const [selectMode, setSelectMode] = useState(false);
|
||||
const [selectedMembers, setSelectedMembers] = useState<string[]>([]);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [currentMember, setCurrentMember] = useState<Member | null>(null);
|
||||
|
||||
const toggleSelectMode = () => {
|
||||
setSelectMode(!selectMode);
|
||||
setSelectedMembers([]);
|
||||
};
|
||||
|
||||
const toggleMemberSelection = (userId: string) => {
|
||||
setSelectedMembers((prev) =>
|
||||
prev.includes(userId)
|
||||
? prev.filter((id) => id !== userId)
|
||||
: [...prev, userId],
|
||||
);
|
||||
};
|
||||
const { users } = hasPermissions(user.roles, {
|
||||
users: ["delete", "update", "insert"],
|
||||
} as const);
|
||||
|
||||
const handleOpenDialog = (member: Member | null) => {
|
||||
setCurrentMember(member);
|
||||
@@ -59,10 +46,12 @@ export default function MembersTable({ user }: { user: IUser }) {
|
||||
|
||||
const handleSaveMember = async (savedMember: Member) => {
|
||||
if (savedMember.userId) {
|
||||
const dif = DiffUtils.getDifferences(currentMember!, savedMember);
|
||||
if (DiffUtils.isEmpty(dif)) return;
|
||||
const res = await request<unknown>(
|
||||
`/users/${savedMember.userId}/update`,
|
||||
{
|
||||
body: savedMember,
|
||||
body: dif,
|
||||
requiresAuth: true,
|
||||
method: "PATCH",
|
||||
},
|
||||
@@ -96,105 +85,83 @@ export default function MembersTable({ user }: { user: IUser }) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between">
|
||||
<Button onClick={toggleSelectMode}>
|
||||
{selectMode ? <CircleX /> : "Selectionner"}
|
||||
</Button>
|
||||
{hasPermissions(user.roles, { users: ["insert"] }) && (
|
||||
{users.insert && (
|
||||
<Button onClick={() => handleOpenDialog(null)}>
|
||||
<UserRoundPlus />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="relative">
|
||||
{isLoading && <Loader2 className="animate-spin" />}
|
||||
<ScrollArea className="h-full rounded-md border">
|
||||
<Table>
|
||||
<TableHeader className="sticky top-0 bg-background z-10 shadow-sm">
|
||||
<TableRow>
|
||||
{selectMode && (
|
||||
<TableHead className="w-[50px]">
|
||||
Sélectionner
|
||||
</TableHead>
|
||||
)}
|
||||
<TableHead>Prénom</TableHead>
|
||||
<TableHead>Nom</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Téléphone</TableHead>
|
||||
<TableHead>Rôle</TableHead>
|
||||
<TableHead>Rôles</TableHead>
|
||||
<TableHead className="text-right">
|
||||
Actions
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{isLoading && <Loader2 className="animate-spin" />}
|
||||
{members &&
|
||||
members.map((member) => (
|
||||
<TableRow key={member.userId}>
|
||||
{selectMode && (
|
||||
<TableCell>
|
||||
<Checkbox
|
||||
checked={selectedMembers.includes(
|
||||
member.userId!,
|
||||
)}
|
||||
onCheckedChange={() =>
|
||||
toggleMemberSelection(
|
||||
member.userId!,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
)}
|
||||
members.map((_member) => (
|
||||
<TableRow key={_member.userId}>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/dashboard/members/${member.userId}`}
|
||||
>
|
||||
<span className="underline">
|
||||
{member.firstname}
|
||||
</span>
|
||||
</Link>
|
||||
{_member.firstname}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/dashboard/members/${member.userId}`}
|
||||
>
|
||||
<span className="underline">
|
||||
{member.lastname}
|
||||
</span>
|
||||
</Link>
|
||||
{_member.lastname}
|
||||
</TableCell>
|
||||
<TableCell>{_member.email}</TableCell>
|
||||
<TableCell>{_member.phone}</TableCell>
|
||||
<TableCell>
|
||||
{_member.roles
|
||||
?.map((r) => r.name)
|
||||
.join(", ")}
|
||||
</TableCell>
|
||||
<TableCell>{member.email}</TableCell>
|
||||
<TableCell>{member.phone}</TableCell>
|
||||
<TableCell>{member.role}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
{hasPermissions(user.roles, {
|
||||
users: ["update"],
|
||||
}) && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="mr-2"
|
||||
onClick={() =>
|
||||
handleOpenDialog(member)
|
||||
}
|
||||
>
|
||||
<UserRoundPen />
|
||||
</Button>
|
||||
)}
|
||||
{hasPermissions(user.roles, {
|
||||
users: ["delete"],
|
||||
}) && (
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
onClick={() =>
|
||||
handleDelete(
|
||||
member.userId!,
|
||||
)
|
||||
}
|
||||
>
|
||||
<Trash2 />
|
||||
</Button>
|
||||
)}
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="h-8 w-8 p-0"
|
||||
>
|
||||
<span className="sr-only">
|
||||
Ouvrir le menu
|
||||
</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{users.update && (
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
handleOpenDialog(
|
||||
_member,
|
||||
)
|
||||
}
|
||||
>
|
||||
Mettre à jour
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{users.delete && (
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
handleDelete(
|
||||
_member.userId!,
|
||||
)
|
||||
}
|
||||
>
|
||||
Supprimer
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user