Feat: 워크스페이스 api 연결 - S11P21S002-141

This commit is contained in:
정현조 2024-09-11 13:46:08 +09:00
parent 3267f24e11
commit 81187fb0f2
2 changed files with 115 additions and 101 deletions

View File

@ -1,71 +1,84 @@
import { useParams } from 'react-router-dom';
import ProjectCard from '@/components/ProjectCard';
import { Button } from '@/components/ui/button';
import { Workspace } from '@/types';
import { Plus, Smile } from 'lucide-react';
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialogCustom';
import WorkSpaceCreateForm from '../WorkSpaceCreateModal/WorkSpaceCreateForm';
import { Smile } from 'lucide-react';
import ProjectCreateModal from '../ProjectCreateModal';
import { useGetAllProjects, useCreateProject } from '@/hooks/useProjectHooks';
import useAuthStore from '@/stores/useAuthStore';
import { Key } from 'react';
export default function WorkspaceBrowseDetail() {
const { workspaceId } = useParams<{ workspaceId: string }>();
const numericWorkspaceId: number = Number(workspaceId);
const workspace: Workspace = !workspaceId
? {
id: 0,
name: '',
projects: [],
const numericWorkspaceId = Number(workspaceId);
const { profile } = useAuthStore();
const memberId = profile.id ?? 0;
const { data: projectsResponse, isLoading, isError, refetch } = useGetAllProjects(numericWorkspaceId || 0, memberId);
const createProject = useCreateProject();
const handleCreateProject = (data: { title: string; labelType: 'Classification' | 'Detection' | 'Segmentation' }) => {
createProject.mutate(
{
workspaceId: numericWorkspaceId,
memberId,
data: { title: data.title, projectType: data.labelType.toLowerCase() },
},
{
onSuccess: () => {
console.log('프로젝트가 성공적으로 생성되었습니다.');
refetch();
},
onError: (error) => {
console.error('프로젝트 생성 실패:', error);
console.log('Error details:', JSON.stringify(error, null, 2));
const errorMessage = error?.response?.data?.message || error.message || '알 수 없는 오류';
console.error('프로젝트 생성 실패:', errorMessage);
},
}
: {
id: numericWorkspaceId,
name: `workspace-${workspaceId}`,
projects: [
{ id: 1, name: 'project1', type: 'Detection', children: [] },
{ id: 2, name: 'project2', type: 'Detection', children: [] },
{ id: 3, name: 'project3', type: 'Detection', children: [] },
{ id: 4, name: 'project4', type: 'Detection', children: [] },
{ id: 5, name: 'project5', type: 'Detection', children: [] },
],
};
);
};
const projects = Array.isArray(projectsResponse?.data?.workspaceResponses)
? projectsResponse.data.workspaceResponses
: [];
if (isLoading) {
return <p>Loading projects...</p>;
}
if (isError || !workspaceId) {
return (
<div className="flex h-full w-full flex-col items-center justify-center">
<div className="flex flex-col items-center">
<Smile
size={48}
className="mb-2 text-gray-300"
/>
<div className="body text-gray-400">
{!workspaceId ? '작업할 워크스페이스를 선택하세요.' : '작업할 프로젝트가 없습니다.'}
</div>
</div>
</div>
);
}
return (
<div className="flex h-full w-full flex-col gap-8 px-6 py-4">
<div className="flex items-center justify-center">
<h1 className="small-title flex grow">{workspaceId ? workspace.name : ''}</h1>
<h1 className="small-title flex grow">{`Workspace-${workspaceId}`}</h1>
<div className="flex flex-col">
<div className="flex gap-3">
<Dialog>
<DialogTrigger asChild>
<Button
variant="outline"
onClick={() => {
console.log('새 프로젝트 생성 모달');
}}
>
<div className="body flex items-center gap-2">
<Plus size={16} />
<span> </span>
</div>
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader title="새 워크스페이스" />
<WorkSpaceCreateForm
onSubmit={(data) => {
console.log(data);
}}
/>
</DialogContent>
</Dialog>
<ProjectCreateModal onSubmit={handleCreateProject} />
</div>
</div>
</div>
{workspaceId ? (
{projects.length > 0 ? (
<div className="flex flex-wrap gap-6">
{workspace.projects.map((project) => (
{projects.map((project: { id: Key | null | undefined; title: string; projectType: string }) => (
<ProjectCard
key={project.id}
title={project.name}
description={project.type}
title={project.title}
description={project.projectType}
onClick={() => {
console.log('project id : ' + project.id);
}}
@ -73,13 +86,13 @@ export default function WorkspaceBrowseDetail() {
))}
</div>
) : (
<div className="flex w-full grow items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<div className="flex flex-col items-center">
<Smile
size={48}
className="mb-2 text-gray-300"
/>
<div className="body text-gray-400"> .</div>
<div className="body text-gray-400"> .</div>
</div>
</div>
)}

View File

@ -1,39 +1,54 @@
import { Suspense } from 'react';
import { NavLink, Outlet } from 'react-router-dom';
import { Suspense, useEffect } from 'react';
import { NavLink, Outlet, useNavigate } from 'react-router-dom';
import Header from '../Header';
import { Workspace } from '@/types';
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialogCustom';
import { Plus } from 'lucide-react';
import WorkSpaceCreateForm from '../WorkSpaceCreateModal/WorkSpaceCreateForm';
import { useGetAllWorkspaces, useCreateWorkspace } from '@/hooks/useWorkspaceHooks';
import useAuthStore from '@/stores/useAuthStore';
import WorkSpaceCreateModal from '../WorkSpaceCreateModal';
import { useQueryClient } from '@tanstack/react-query';
import { AxiosError } from 'axios';
export default function WorkspaceBrowseLayout() {
const workspaces: Workspace[] = [
{
id: 1,
name: 'workspace-1',
projects: [],
},
{
id: 2,
name: 'workspace-2',
projects: [],
},
{
id: 3,
name: 'workspace-3',
projects: [],
},
{
id: 4,
name: 'workspace-4',
projects: [],
},
{
id: 5,
name: 'workspace-5',
projects: [],
},
];
const { profile, isLoggedIn } = useAuthStore();
const memberId = profile.id;
const navigate = useNavigate();
const queryClient = useQueryClient();
useEffect(() => {
if (!isLoggedIn || !memberId) {
console.error('로그인되지 않았거나 유효한 멤버 ID가 없습니다.');
navigate('/');
}
}, [isLoggedIn, memberId, navigate]);
const { data: workspacesResponse, isLoading, isError } = useGetAllWorkspaces(memberId || 0);
const workspaces = workspacesResponse?.data?.workspaceResponses || [];
const createWorkspace = useCreateWorkspace();
const handleCreateWorkspace = (data: { title: string; content: string }) => {
if (!memberId) return;
createWorkspace.mutate(
{ memberId, data },
{
onSuccess: () => {
console.log('워크스페이스가 성공적으로 생성되었습니다.');
queryClient.invalidateQueries({ queryKey: ['workspaces'] });
},
onError: (error: AxiosError) => {
console.error('워크스페이스 생성 실패:', error.message);
},
}
);
};
if (isLoading) {
return <p>Loading workspaces...</p>;
}
if (isError) {
return <p>Error loading workspaces. Please try again later.</p>;
}
return (
<>
@ -43,21 +58,7 @@ export default function WorkspaceBrowseLayout() {
<div className="flex w-[280px] flex-col gap-4 border-r border-gray-200 bg-gray-100 px-6 py-4">
<div className="flex items-center justify-center gap-5">
<h1 className="heading mr-2.5 w-full"> </h1>
<Dialog>
<DialogTrigger asChild>
<button className="p-2">
<Plus size={20} />
</button>
</DialogTrigger>
<DialogContent>
<DialogHeader title="새 워크스페이스" />
<WorkSpaceCreateForm
onSubmit={(data) => {
console.log(data);
}}
/>
</DialogContent>
</Dialog>
<WorkSpaceCreateModal onSubmit={handleCreateWorkspace} />
</div>
{workspaces.length > 0 ? (
workspaces.map((workspace) => (
@ -66,7 +67,7 @@ export default function WorkspaceBrowseLayout() {
key={workspace.id}
className={({ isActive }) => (isActive ? 'body-strong' : 'body') + ' cursor-pointer'}
>
{workspace.name}
{workspace.title}
</NavLink>
))
) : (