Files
qlockify-frontend-deployment/src/components/WorkspaceSelector.tsx

108 lines
4.4 KiB
TypeScript

import React, { useState, useRef, useEffect } from "react";
import { useWorkspace } from "../context/WorkspaceContext";
import { useTranslation } from "../hooks/useTranslation";
import { Check, ChevronDown, Plus, Briefcase } from "lucide-react";
import { CreateWorkspaceModal } from "./CreateWorkspaceModal"; // Adjust path if needed
export const WorkspaceSelector: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
const { workspaces, activeWorkspace, setActiveWorkspace, addWorkspace } = useWorkspace();
const { t, lang } = useTranslation();
const isFa = lang === "fa";
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
const handleCreateWorkspace = async (data: { name: string; description: string; members: any[] }) => {
await addWorkspace(data);
setIsCreateModalOpen(false);
};
return (
<div className="relative" ref={dropdownRef}>
{/* Selector Button */}
<button
type="button"
onClick={() => setIsOpen(!isOpen)}
className="flex items-center gap-2 px-3 py-2 text-sm font-medium text-slate-700 dark:text-slate-200 rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors"
>
<div className="w-6 h-6 flex items-center justify-center bg-blue-100 dark:bg-blue-900/50 text-blue-600 dark:text-blue-400 rounded-md">
{activeWorkspace?.name?.charAt(0) || <Briefcase className="w-4 h-4" />}
</div>
<span className="max-w-30 truncate">
{activeWorkspace?.name || t.workspace?.title || "Workspaces"}
</span>
<ChevronDown className="w-4 h-4 text-slate-400" />
</button>
{/* Dropdown Menu */}
{isOpen && (
<div
className={`absolute top-full mt-2 w-64 bg-white dark:bg-slate-900 rounded-xl shadow-lg border border-slate-200 dark:border-slate-800 py-2 z-40 ${
isFa ? "left-0" : "right-0"
}`}
>
<div className="px-3 py-2 text-xs font-semibold text-slate-500 uppercase tracking-wider">
{t.workspace?.title || "Workspaces"}
</div>
<div className="max-h-60 overflow-y-auto">
{workspaces.map((ws) => (
<button
key={ws.id}
type="button"
onClick={() => {
setActiveWorkspace(ws);
setIsOpen(false);
}}
className="w-full flex items-center justify-between px-3 py-2 text-sm text-slate-700 dark:text-slate-200 hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors"
>
<div className="flex items-center gap-2 truncate">
<div className="w-6 h-6 flex items-center justify-center bg-slate-100 dark:bg-slate-800 rounded-md font-medium">
{ws.name.charAt(0)}
</div>
<span className="truncate">{ws.name}</span>
</div>
{activeWorkspace?.id === ws.id && (
<Check className="w-4 h-4 text-blue-500 shrink-0" />
)}
</button>
))}
</div>
<div className="h-px bg-slate-200 dark:bg-slate-800 my-2" />
<button
type="button"
onClick={() => {
setIsOpen(false);
setIsCreateModalOpen(true);
}}
className="w-full flex items-center gap-2 px-3 py-2 text-sm text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-500/10 transition-colors"
>
<Plus className="w-4 h-4" />
{t.workspace?.createNew || "Create New Workspace"}
</button>
</div>
)}
{/* Advanced Create Workspace Modal */}
<CreateWorkspaceModal
isOpen={isCreateModalOpen}
onClose={() => setIsCreateModalOpen(false)}
onSubmit={handleCreateWorkspace}
/>
</div>
);
};