"use client";
import { useState } from "react";
import { Shield, Check, Crown, Eye, Edit3 } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
const teamMembers = [
{
id: "1",
name: "Alex Morgan",
email: "[email protected]",
avatar: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&auto=format&fit=crop",
role: "editor",
},
{
id: "2",
name: "Jordan Lee",
email: "[email protected]",
avatar: "https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&auto=format&fit=crop",
role: "viewer",
},
{
id: "3",
name: "Sam Taylor",
email: "[email protected]",
avatar: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&auto=format&fit=crop",
role: "viewer",
},
{
id: "4",
name: "Casey Kim",
email: "[email protected]",
avatar: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&auto=format&fit=crop",
role: "editor",
},
];
const roles = [
{
id: "admin",
name: "Admin",
icon: Crown,
description: "Full access to all features",
permissions: ["Manage team", "Edit content", "View analytics", "Billing access"],
},
{
id: "editor",
name: "Editor",
icon: Edit3,
description: "Can edit and publish content",
permissions: ["Edit content", "View analytics", "Comment"],
},
{
id: "viewer",
name: "Viewer",
icon: Eye,
description: "Read-only access",
permissions: ["View content", "Comment"],
},
];
export const title = "React Dialog Block Team Role Assignment";
export default function DialogTeamRoles() {
const [open, setOpen] = useState(false);
const [selectedMembers, setSelectedMembers] = useState<string[]>([]);
const [selectedRole, setSelectedRole] = useState("");
const [saved, setSaved] = useState(false);
const toggleMember = (memberId: string) => {
setSelectedMembers((prev) =>
prev.includes(memberId)
? prev.filter((id) => id !== memberId)
: [...prev, memberId]
);
};
const selectAll = () => {
if (selectedMembers.length === teamMembers.length) {
setSelectedMembers([]);
} else {
setSelectedMembers(teamMembers.map((m) => m.id));
}
};
const currentRoleInfo = roles.find((r) => r.id === selectedRole);
const handleSave = () => {
console.log({ members: selectedMembers, role: selectedRole });
setSaved(true);
};
const handleClose = () => {
setOpen(false);
setTimeout(() => {
setSelectedMembers([]);
setSelectedRole("");
setSaved(false);
}, 200);
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<div className="flex min-h-[350px] items-center justify-center">
<DialogTrigger asChild>
<Button variant="outline">
<Shield className="mr-2 h-4 w-4" />
Manage Roles
</Button>
</DialogTrigger>
</div>
<DialogContent style={{ maxWidth: "384px" }}>
{saved ? (
<div className="flex flex-col items-center justify-center py-6 text-center">
<Check className="h-8 w-8 text-primary" />
<h3 className="mt-4 text-lg font-medium">Roles Updated</h3>
<p className="mt-1 text-sm text-muted-foreground">
{selectedMembers.length} member{selectedMembers.length !== 1 ? "s" : ""} assigned as {currentRoleInfo?.name}.
</p>
<Button onClick={handleClose} className="mt-6">
Done
</Button>
</div>
) : (
<>
<DialogHeader>
<DialogTitle>Assign Roles</DialogTitle>
<DialogDescription>
Select members and assign a role.
</DialogDescription>
</DialogHeader>
<div className="py-4 space-y-4">
{/* Members */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label className="text-sm">Members</Label>
<button
className="text-xs text-muted-foreground hover:text-foreground"
onClick={selectAll}
>
{selectedMembers.length === teamMembers.length ? "Deselect all" : "Select all"}
</button>
</div>
<ScrollArea className="h-[160px]">
<div className="space-y-1">
{teamMembers.map((member) => (
<div
key={member.id}
className="flex items-center gap-2 rounded-lg p-2 hover:bg-muted/50 cursor-pointer"
onClick={() => toggleMember(member.id)}
>
<Checkbox
checked={selectedMembers.includes(member.id)}
onCheckedChange={() => toggleMember(member.id)}
/>
<Avatar className="h-7 w-7">
<AvatarImage src={member.avatar} alt={member.name} />
<AvatarFallback className="text-xs">
{member.name.split(" ").map((n) => n[0]).join("")}
</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<p className="text-sm truncate">{member.name}</p>
</div>
<span className="text-xs text-muted-foreground capitalize">{member.role}</span>
</div>
))}
</div>
</ScrollArea>
</div>
{/* Role Select */}
<div className="space-y-2">
<Label className="text-sm">New Role</Label>
<Select value={selectedRole} onValueChange={setSelectedRole}>
<SelectTrigger>
<SelectValue placeholder="Select role" />
</SelectTrigger>
<SelectContent>
{roles.map((role) => (
<SelectItem key={role.id} value={role.id}>
<div className="flex items-center gap-2">
<role.icon className="h-4 w-4" />
<span>{role.name}</span>
<span className="text-muted-foreground">— {role.description}</span>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={handleClose}>
Cancel
</Button>
<Button
onClick={handleSave}
disabled={selectedMembers.length === 0 || !selectedRole}
>
Update {selectedMembers.length > 0 ? `(${selectedMembers.length})` : ""}
</Button>
</DialogFooter>
</>
)}
</DialogContent>
</Dialog>
);
}