()
| 6 | import { dummyWorkspaces } from "../assets/assets"; |
| 7 | |
| 8 | function WorkspaceDropdown() { |
| 9 | |
| 10 | const { workspaces } = useSelector((state) => state.workspace); |
| 11 | const currentWorkspace = useSelector((state) => state.workspace?.currentWorkspace || null); |
| 12 | const [isOpen, setIsOpen] = useState(false); |
| 13 | const dropdownRef = useRef(null); |
| 14 | |
| 15 | const dispatch = useDispatch(); |
| 16 | const navigate = useNavigate(); |
| 17 | |
| 18 | const onSelectWorkspace = (organizationId) => { |
| 19 | dispatch(setCurrentWorkspace(organizationId)) |
| 20 | setIsOpen(false); |
| 21 | navigate('/') |
| 22 | } |
| 23 | |
| 24 | // Close dropdown on outside click |
| 25 | useEffect(() => { |
| 26 | function handleClickOutside(event) { |
| 27 | if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { |
| 28 | setIsOpen(false); |
| 29 | } |
| 30 | } |
| 31 | document.addEventListener("mousedown", handleClickOutside); |
| 32 | return () => document.removeEventListener("mousedown", handleClickOutside); |
| 33 | }, []); |
| 34 | |
| 35 | return ( |
| 36 | <div className="relative m-4" ref={dropdownRef}> |
| 37 | <button onClick={() => setIsOpen(prev => !prev)} className="w-full flex items-center justify-between p-3 h-auto text-left rounded hover:bg-gray-100 dark:hover:bg-zinc-800" > |
| 38 | <div className="flex items-center gap-3"> |
| 39 | <img src={currentWorkspace?.image_url} alt={currentWorkspace?.name} className="w-8 h-8 rounded shadow" /> |
| 40 | <div className="min-w-0 flex-1"> |
| 41 | <p className="font-semibold text-gray-800 dark:text-white text-sm truncate"> |
| 42 | {currentWorkspace?.name || "Select Workspace"} |
| 43 | </p> |
| 44 | <p className="text-xs text-gray-500 dark:text-zinc-400 truncate"> |
| 45 | {workspaces.length} workspace{workspaces.length !== 1 ? "s" : ""} |
| 46 | </p> |
| 47 | </div> |
| 48 | </div> |
| 49 | <ChevronDown className="w-4 h-4 text-gray-500 dark:text-zinc-400 flex-shrink-0" /> |
| 50 | </button> |
| 51 | |
| 52 | {isOpen && ( |
| 53 | <div className="absolute z-50 w-64 bg-white dark:bg-zinc-900 border border-gray-200 dark:border-zinc-700 rounded shadow-lg top-full left-0"> |
| 54 | <div className="p-2"> |
| 55 | <p className="text-xs text-gray-500 dark:text-zinc-400 uppercase tracking-wider mb-2 px-2"> |
| 56 | Workspaces |
| 57 | </p> |
| 58 | {dummyWorkspaces.map((ws) => ( |
| 59 | <div key={ws.id} onClick={() => onSelectWorkspace(ws.id)} className="flex items-center gap-3 p-2 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-800" > |
| 60 | <img src={ws.image_url} alt={ws.name} className="w-6 h-6 rounded" /> |
| 61 | <div className="flex-1 min-w-0"> |
| 62 | <p className="text-sm font-medium text-gray-800 dark:text-white truncate"> |
| 63 | {ws.name} |
| 64 | </p> |
| 65 | <p className="text-xs text-gray-500 dark:text-zinc-400 truncate"> |
nothing calls this directly
no test coverage detected