summaryrefslogtreecommitdiff
path: root/components/project/ProjectNav.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'components/project/ProjectNav.tsx')
-rw-r--r--components/project/ProjectNav.tsx149
1 files changed, 149 insertions, 0 deletions
diff --git a/components/project/ProjectNav.tsx b/components/project/ProjectNav.tsx
new file mode 100644
index 00000000..acf9bfd8
--- /dev/null
+++ b/components/project/ProjectNav.tsx
@@ -0,0 +1,149 @@
+// components/project/ProjectNav.tsx
+'use client';
+
+import { useState, useEffect } from 'react';
+import { useRouter, usePathname } from 'next/navigation';
+import {
+ Home,
+ FolderOpen,
+ Users,
+ Settings,
+ BarChart3,
+ Share2,
+ ChevronDown,
+ ExternalLink
+} from 'lucide-react';
+import { Button } from '@/components/ui/button';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import {
+ Breadcrumb,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbSeparator,BreadcrumbList
+} from '@/components/ui/breadcrumb';
+import { Badge } from '@/components/ui/badge';
+import { cn } from '@/lib/utils';
+
+interface ProjectNavProps {
+ projectId: string;
+}
+
+export function ProjectNav({ projectId }: ProjectNavProps) {
+ const [projectName, setProjectName] = useState('');
+ const [projectRole, setProjectRole] = useState('');
+ const router = useRouter();
+ const pathname = usePathname();
+
+ useEffect(() => {
+ // 프로젝트 정보 가져오기
+ fetchProjectInfo();
+ }, [projectId]);
+
+ const fetchProjectInfo = async () => {
+ try {
+ const response = await fetch(`/api/projects/${projectId}`);
+ const data = await response.json();
+ setProjectName(data.name);
+ setProjectRole(data.role);
+ } catch (error) {
+ console.error('프로젝트 정보 로드 실패:', error);
+ }
+ };
+
+ const navItems = [
+ {
+ label: '대시보드',
+ icon: Home,
+ href: `/evcp/data-room/${projectId}`,
+ active: pathname === `/evcp/data-room/${projectId}`,
+ },
+ {
+ label: '파일',
+ icon: FolderOpen,
+ href: `/evcp/data-room/${projectId}/files`,
+ active: pathname === `/evcp/data-room/${projectId}/files`,
+ },
+ {
+ label: '멤버',
+ icon: Users,
+ href: `/evcp/data-room/${projectId}/members`,
+ active: pathname === `/evcp/data-room/${projectId}/members`,
+ requireRole: ['owner', 'admin'],
+ },
+ {
+ label: '통계',
+ icon: BarChart3,
+ href: `/evcp/data-room/${projectId}/stats`,
+ active: pathname === `/evcp/data-room/${projectId}/stats`,
+ requireRole: ['owner'],
+ },
+ {
+ label: '설정',
+ icon: Settings,
+ href: `/evcp/data-room/${projectId}/settings`,
+ active: pathname === `/evcp/data-room/${projectId}/settings`,
+ requireRole: ['owner', 'admin'],
+ },
+ ];
+
+ const visibleNavItems = navItems.filter(item =>
+ !item.requireRole || item.requireRole.includes(projectRole)
+ );
+
+ return (
+ <div className="border-b bg-white">
+ <div className="px-6 py-3">
+ {/* Breadcrumb */}
+ <div className="flex items-center justify-between mb-3">
+ <Breadcrumb>
+ <BreadcrumbList>
+ <BreadcrumbItem>
+ <BreadcrumbLink href="/evcp/data-room">프로젝트</BreadcrumbLink>
+ </BreadcrumbItem>
+ <BreadcrumbSeparator />
+ <BreadcrumbItem>
+ {projectName || '로딩...'}
+ </BreadcrumbItem>
+ </BreadcrumbList>
+ </Breadcrumb>
+
+ <div className="flex items-center gap-2">
+ <Badge variant="outline">
+ {projectRole || 'viewer'}
+ </Badge>
+ <Button variant="outline" size="sm">
+ <Share2 className="h-4 w-4 mr-1" />
+ 공유
+ </Button>
+ </div>
+ </div>
+
+ {/* 네비게이션 탭 */}
+ <div className="flex items-center gap-1">
+ {visibleNavItems.map(item => (
+ <Button
+ key={item.label}
+ variant={item.active ? "secondary" : "ghost"}
+ size="sm"
+ onClick={() => router.push(item.href)}
+ className={cn(
+ "gap-2",
+ item.active && "bg-secondary"
+ )}
+ >
+ <item.icon className="h-4 w-4" />
+ {item.label}
+ </Button>
+ ))}
+ </div>
+ </div>
+ </div>
+ );
+}
+