add workspace navbar status + creation modal
This commit is contained in:
107
src/components/WorkspaceSelector.tsx
Normal file
107
src/components/WorkspaceSelector.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user