diff --git a/frontend/src/api/axiosConfig.ts b/frontend/src/api/axiosConfig.ts index 197b104..ee0cb3a 100644 --- a/frontend/src/api/axiosConfig.ts +++ b/frontend/src/api/axiosConfig.ts @@ -2,8 +2,7 @@ import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'ax import useAuthStore from '@/stores/useAuthStore'; import { BaseResponse, CustomError, SuccessResponse, RefreshTokenResponseDTO } from '@/types'; -const baseURL = 'https://j11s002.p.ssafy.io'; -// const baseURL = 'http://localhost:5173'; 모킹 테스트 +const baseURL = import.meta.env.VITE_API_URL; const api = axios.create({ baseURL, diff --git a/frontend/src/components/ImageCanvas/index.tsx b/frontend/src/components/ImageCanvas/index.tsx index e1dc476..6e1359f 100644 --- a/frontend/src/components/ImageCanvas/index.tsx +++ b/frontend/src/components/ImageCanvas/index.tsx @@ -3,42 +3,15 @@ import Konva from 'konva'; import { useEffect, useRef, useState } from 'react'; import { Circle, Image, Layer, Line, Rect, Stage } from 'react-konva'; import useImage from 'use-image'; -import { Label } from '@/types'; import LabelRect from './LabelRect'; import { Vector2d } from 'konva/lib/types'; import LabelPolygon from './LabelPolygon'; import CanvasControlBar from '../CanvasControlBar'; -const mockLabels: Label[] = Array.from({ length: 10 }, (_, i) => { - const startX = Math.random() * 1200 + 300; - const startY = Math.random() * 2000 + 300; - const color = Math.floor(Math.random() * 65535) - .toString(16) - .padStart(4, '0'); - - return { - id: i, - name: `label-${i}`, - type: i % 2 === 0 ? 'polygon' : 'rect', - color: i % 2 === 0 ? `#ff${color}` : `#${color}ff`, - coordinates: - i % 2 === 0 - ? [ - [startX, startY], - [startX + 200, startY + 50], - [startX + 300, startY + 300], - [startX + 100, startY + 250], - ] - : [ - [startX, startY], - [startX + 300, startY + 300], - ], - }; -}); - export default function ImageCanvas() { - const stageWidth = window.innerWidth; - const stageHeight = window.innerHeight; + const sidebarSize = useCanvasStore((state) => state.sidebarSize); + const stageWidth = window.innerWidth * ((100 - sidebarSize) / 100) - 280; + const stageHeight = window.innerHeight - 64; const stageRef = useRef(null); const dragLayerRef = useRef(null); const scale = useRef(0); @@ -100,7 +73,7 @@ export default function ImageCanvas() { const color = Math.floor(Math.random() * 65535) .toString(16) .padStart(6, '0'); - const id = labels.length; + const id = labels.length + 1; addLabel({ id: id, name: 'label', @@ -127,7 +100,7 @@ export default function ImageCanvas() { const color = Math.floor(Math.random() * 65535) .toString(16) .padStart(6, '0'); - const id = labels.length; + const id = labels.length + 1; addLabel({ id: id, name: 'label', @@ -209,11 +182,6 @@ export default function ImageCanvas() { return { x: scale.current, y: scale.current }; }; - // TODO: remove mock data - useEffect(() => { - useCanvasStore.setState({ labels: mockLabels }); - }, []); - useEffect(() => { if (!stageRef.current) return; stageRef.current.container().style.cursor = drawState === 'pointer' ? 'default' : 'crosshair'; diff --git a/frontend/src/components/WorkspaceLayout/index.tsx b/frontend/src/components/WorkspaceLayout/index.tsx index e7436ed..89d7f67 100644 --- a/frontend/src/components/WorkspaceLayout/index.tsx +++ b/frontend/src/components/WorkspaceLayout/index.tsx @@ -9,8 +9,47 @@ import { fetchFolderApi } from '@/api/folderApi'; import { getWorkspaceApi } from '@/api/workspaceApi'; import { getAllProjectsApi } from '@/api/projectApi'; import useAuthStore from '@/stores/useAuthStore'; +import useCanvasStore from '@/stores/useCanvasStore'; + +const mockLabels: Label[] = [ + { + id: 1, + name: 'Label 1', + color: '#FFaa33', + coordinates: [ + [700, 100], + [1200, 800], + ], + type: 'rect', + }, + { + id: 2, + name: 'Label 2', + color: '#aaFF55', + coordinates: [ + [200, 200], + [400, 200], + [500, 500], + [400, 800], + [200, 800], + [100, 500], + ], + type: 'polygon', + }, + { + id: 3, + name: 'Label 3', + color: '#77aaFF', + coordinates: [ + [1000, 1000], + [1800, 1800], + ], + type: 'rect', + }, +]; export default function WorkspaceLayout() { + const setLabels = useCanvasStore((state) => state.setLabels); const { workspaceId, projectId } = useParams<{ workspaceId: string; projectId: string }>(); const [workspace, setWorkspace] = useState<{ name: string; projects: Project[] }>({ name: '', @@ -109,29 +148,9 @@ export default function WorkspaceLayout() { } }, [workspaceId, projectId, memberId]); - const labels: Label[] = [ - { - id: 1, - name: 'Label 1', - color: '#FFaa33', - coordinates: [], - type: 'rect', - }, - { - id: 2, - name: 'Label 2', - color: '#aaFF55', - coordinates: [], - type: 'rect', - }, - { - id: 3, - name: 'Label 3', - color: '#77aaFF', - coordinates: [], - type: 'rect', - }, - ]; + useEffect(() => { + setLabels(mockLabels); + }, [setLabels]); return ( <> @@ -146,7 +165,7 @@ export default function WorkspaceLayout() {
- + diff --git a/frontend/src/components/WorkspaceSidebar/index.tsx b/frontend/src/components/WorkspaceSidebar/index.tsx index 91816d7..954e216 100644 --- a/frontend/src/components/WorkspaceSidebar/index.tsx +++ b/frontend/src/components/WorkspaceSidebar/index.tsx @@ -6,12 +6,13 @@ import ProjectStructure from './ProjectStructure'; import { Project } from '@/types'; import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '../ui/select'; import ProjectCreateModal from '../ProjectCreateModal'; +import useCanvasStore from '@/stores/useCanvasStore'; export default function WorkspaceSidebar({ workspaceName, projects }: { workspaceName: string; projects: Project[] }) { + const setSidebarSize = useCanvasStore((state) => state.setSidebarSize); const navigate = useNavigate(); const { workspaceId } = useParams<{ workspaceId: string }>(); const [selectedProjectId, setSelectedProjectId] = useState(); - const handleSelectProject = (projectId: string) => { setSelectedProjectId(projectId); navigate(`/workspace/${workspaceId}/project/${projectId}`); @@ -24,9 +25,7 @@ export default function WorkspaceSidebar({ workspaceName, projects }: { workspac maxSize={35} defaultSize={20} className="flex h-full flex-col bg-gray-100" - onResize={(size) => { - console.log(size); - }} + onResize={(size) => setSidebarSize(size)} >

{workspaceName}

diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index 60b2f3a..91f3b6b 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -14,8 +14,9 @@ import { Navigate } from 'react-router-dom'; export const webPath = { home: () => '/', browse: () => '/browse', - workspace: (workspaceId: string, projectId?: string) => - projectId ? `/workspace/${workspaceId}/project/${projectId}` : `/workspace/${workspaceId}`, + workspace: () => '/workspace', + // workspace: (workspaceId: string, projectId?: string) => + // projectId ? `/workspace/${workspaceId}/project/${projectId}` : `/workspace/${workspaceId}`, admin: (workspaceId: string) => `/admin/${workspaceId}`, oauthCallback: () => '/redirect/oauth2', }; @@ -46,12 +47,12 @@ const router = createBrowserRouter([ ], }, { - path: '/workspace/:workspaceId', + path: `${webPath.workspace()}/:workspaceId`, element: , children: [ { - path: '', - element:
workspace
, + index: true, + element: , }, { path: 'project/:projectId', diff --git a/frontend/src/stores/useCanvasStore.ts b/frontend/src/stores/useCanvasStore.ts index 234cc72..72dafbe 100644 --- a/frontend/src/stores/useCanvasStore.ts +++ b/frontend/src/stores/useCanvasStore.ts @@ -2,10 +2,13 @@ import { Label } from '@/types'; import { create } from 'zustand'; interface CanvasState { + sidebarSize: number; image: string; labels: Label[]; drawState: 'pen' | 'rect' | 'pointer'; + setSidebarSize: (width: number) => void; changeImage: (image: string, labels: Label[]) => void; + setLabels: (labels: Label[]) => void; addLabel: (label: Label) => void; removeLabel: (labelId: number) => void; updateLabel: (label: Label) => void; @@ -13,11 +16,14 @@ interface CanvasState { } const useCanvasStore = create()((set) => ({ + sidebarSize: 20, image: '', labels: [], drawState: 'pointer', + setSidebarSize: (width) => set({ sidebarSize: width }), changeImage: (image: string, labels: Label[]) => set({ image, labels }), addLabel: (label: Label) => set((state) => ({ labels: [...state.labels, label] })), + setLabels: (labels) => set({ labels }), removeLabel: (labelId: number) => set((state) => ({ labels: state.labels.filter((label) => label.id !== labelId) })), updateLabel: (label: Label) => set((state) => ({ labels: state.labels.map((l) => (l.id === label.id ? label : l)) })), setDrawState: (drawState) => set({ drawState }),