From 7a33ae175d51c4a9e198db5888feda71f96e356f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=95=9C=EB=8F=99=ED=98=84?= <hando1220@ajou.ac.kr> Date: Mon, 10 Mar 2025 17:32:16 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20?= =?UTF-8?q?Role=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/project-switcher.tsx | 13 ++++++++++++- src/stores/authStore.ts | 27 ++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/components/project-switcher.tsx b/src/components/project-switcher.tsx index 1a78082..c075eca 100644 --- a/src/components/project-switcher.tsx +++ b/src/components/project-switcher.tsx @@ -1,5 +1,6 @@ import { useAuthStore } from '@/stores/authStore'; import { Check, ChevronsUpDown, GalleryVerticalEnd } from 'lucide-react'; +import { toast } from 'sonner'; import { DropdownMenu, DropdownMenuContent, @@ -7,10 +8,20 @@ import { DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar'; +import { Project } from '@/types/project'; export function ProjectSwitcher() { const { projects, selectedProject, setSelectedProject } = useAuthStore(); + const handleSelectProject = async (project: Project) => { + try { + await setSelectedProject(project); + } catch (error) { + console.error(error); + toast.error('프로젝트 권한을 조회할 수 없습니다.'); + } + }; + return ( <SidebarMenu> <SidebarMenuItem> @@ -38,7 +49,7 @@ export function ProjectSwitcher() { </DropdownMenuTrigger> <DropdownMenuContent className="w-[--radix-dropdown-menu-trigger-width]" align="start"> {projects.map((project) => ( - <DropdownMenuItem key={project.id} onSelect={() => setSelectedProject(project)}> + <DropdownMenuItem key={project.id} onSelect={() => handleSelectProject(project)}> {project.name} {project.id === selectedProject?.id && <Check className="ml-auto" />} </DropdownMenuItem> ))} diff --git a/src/stores/authStore.ts b/src/stores/authStore.ts index 4dfbc7c..ff8324c 100644 --- a/src/stores/authStore.ts +++ b/src/stores/authStore.ts @@ -7,21 +7,37 @@ export interface AuthStore { username: string; isAdmin: boolean; projects: Project[]; - selectedProject: Project | null; - setSelectedProject: (project: Project) => void; + selectedProject: (Project & { role?: string }) | null; + setSelectedProject: (project: Project) => Promise<void>; login: (username: string, password: string) => void; logout: () => void; } export const useAuthStore = create<AuthStore>()( persist( - (set) => ({ + (set, get) => ({ token: null, username: '', isAdmin: false, projects: [], selectedProject: null, - setSelectedProject: (project) => set({ selectedProject: project }), + setSelectedProject: async (project) => { + set({ selectedProject: project }); + console.log(project); + + const response = await fetch(`/api/auth/role?projectId=${project.id}`, { + headers: { 'X-Subject-Token': get().token! }, + }); + + if (!response.ok) { + throw new Error('프로젝트 정보를 가져오지 못했습니다.'); + } + + const { role } = await response.json(); + set({ selectedProject: { ...project, role } }); + + console.log(role); + }, login: async (username, password) => { const response = await fetch('/api/auth/login', { method: 'POST', @@ -36,7 +52,8 @@ export const useAuthStore = create<AuthStore>()( const token = response.headers.get('X-Subject-Token')!; const { isAdmin, projects } = await response.json(); - set({ token, username, isAdmin, projects, selectedProject: projects[0] }); + set({ token, username, isAdmin, projects }); + get().setSelectedProject(projects[0]); }, logout: () => set({ token: null, username: '', isAdmin: false, projects: [], selectedProject: null }), }), -- GitLab