Merge branch 'fe/refactor/review-detail' into 'fe/develop'
Refactor: 리뷰 요청 zod 조건 추가 See merge request s11-s-project/S11P21S002!268
This commit is contained in:
commit
f11e8d91d6
@ -18,7 +18,7 @@ const reviewFormSchema = z.object({
|
|||||||
projectId: z.string().min(1, '프로젝트를 선택해주세요.'),
|
projectId: z.string().min(1, '프로젝트를 선택해주세요.'),
|
||||||
title: z.string().min(1, '제목을 입력해주세요.'),
|
title: z.string().min(1, '제목을 입력해주세요.'),
|
||||||
content: z.string().min(1, '내용을 입력해주세요.'),
|
content: z.string().min(1, '내용을 입력해주세요.'),
|
||||||
imageIds: z.array(z.number()),
|
imageIds: z.array(z.number()).min(1, '최소 한 개의 이미지를 선택해주세요.'),
|
||||||
});
|
});
|
||||||
|
|
||||||
type ReviewFormData = z.infer<typeof reviewFormSchema>;
|
type ReviewFormData = z.infer<typeof reviewFormSchema>;
|
||||||
|
@ -5,71 +5,37 @@ import { Project } from '@/types';
|
|||||||
import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '../ui/select';
|
import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '../ui/select';
|
||||||
import useCanvasStore from '@/stores/useCanvasStore';
|
import useCanvasStore from '@/stores/useCanvasStore';
|
||||||
import { webPath } from '@/router';
|
import { webPath } from '@/router';
|
||||||
import { useState } from 'react';
|
import { Suspense, useEffect } from 'react';
|
||||||
import useUploadImageFileQuery from '@/queries/projects/useUploadImageFileQuery';
|
|
||||||
import useAuthStore from '@/stores/useAuthStore';
|
|
||||||
|
|
||||||
export default function WorkspaceSidebar({ workspaceName, projects }: { workspaceName: string; projects: Project[] }) {
|
export default function WorkspaceSidebar({ workspaceName, projects }: { workspaceName: string; projects: Project[] }) {
|
||||||
const { projectId: selectedProjectId } = useParams<{ projectId: string }>();
|
const { setImage } = useCanvasStore();
|
||||||
const selectedProject = projects.find((project) => project.id.toString() === selectedProjectId);
|
const { projectId: selectedProjectId, workspaceId } = useParams<{ projectId: string; workspaceId: string }>();
|
||||||
|
const selectedProject = projects.find((project) => project.id.toString() === selectedProjectId) || null;
|
||||||
const setSidebarSize = useCanvasStore((state) => state.setSidebarSize);
|
const setSidebarSize = useCanvasStore((state) => state.setSidebarSize);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { workspaceId } = useParams<{ workspaceId: string }>();
|
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
|
||||||
const uploadImageFileMutation = useUploadImageFileQuery();
|
|
||||||
const { profile } = useAuthStore();
|
|
||||||
|
|
||||||
const handleSelectProject = (projectId: string) => {
|
const handleSelectProject = (projectId: string) => {
|
||||||
navigate(`${webPath.workspace()}/${workspaceId}/project/${projectId}`);
|
setImage(null);
|
||||||
|
navigate(`${webPath.workspace()}/${workspaceId}/${projectId}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragOver = (e: React.DragEvent) => {
|
useEffect(() => {
|
||||||
e.preventDefault();
|
if (!selectedProject) {
|
||||||
setIsDragging(true);
|
setImage(null);
|
||||||
};
|
}
|
||||||
|
}, [selectedProject, setImage]);
|
||||||
const handleDragLeave = () => {
|
|
||||||
setIsDragging(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDrop = (e: React.DragEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setIsDragging(false);
|
|
||||||
|
|
||||||
if (!selectedProjectId || !profile) return;
|
|
||||||
|
|
||||||
const files = Array.from(e.dataTransfer.files);
|
|
||||||
const memberId = profile.id;
|
|
||||||
const projectId = parseInt(selectedProjectId);
|
|
||||||
const folderId = 0;
|
|
||||||
|
|
||||||
uploadImageFileMutation.mutate({
|
|
||||||
memberId,
|
|
||||||
projectId,
|
|
||||||
folderId,
|
|
||||||
files,
|
|
||||||
progressCallback: (progress) => {
|
|
||||||
console.log(`업로드 진행률: ${progress}%`);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ResizablePanel
|
<ResizablePanel
|
||||||
minSize={10}
|
minSize={10}
|
||||||
maxSize={35}
|
maxSize={35}
|
||||||
defaultSize={20}
|
defaultSize={15}
|
||||||
className={`flex h-full flex-col bg-gray-50 ${isDragging ? 'bg-blue-100' : ''}`}
|
|
||||||
onResize={(size) => setSidebarSize(size)}
|
onResize={(size) => setSidebarSize(size)}
|
||||||
onDragOver={(e) => handleDragOver(e as unknown as React.DragEvent<Element>)}
|
|
||||||
onDragLeave={handleDragLeave}
|
|
||||||
onDrop={(e) => handleDrop(e as unknown as React.DragEvent<Element>)}
|
|
||||||
>
|
>
|
||||||
<header className="body flex w-full items-center gap-2 p-2">
|
<div className="box-border flex h-full flex-col gap-2 bg-gray-50 p-3">
|
||||||
<h1 className="w-full overflow-hidden text-ellipsis whitespace-nowrap">{workspaceName}</h1>
|
<header className="body flex w-full items-center gap-2">
|
||||||
</header>
|
<h1 className="subheading w-full overflow-hidden text-ellipsis whitespace-nowrap">{workspaceName}</h1>
|
||||||
<div className="p-2">
|
</header>
|
||||||
<Select
|
<Select
|
||||||
onValueChange={handleSelectProject}
|
onValueChange={handleSelectProject}
|
||||||
defaultValue={selectedProjectId}
|
defaultValue={selectedProjectId}
|
||||||
@ -88,8 +54,10 @@ export default function WorkspaceSidebar({ workspaceName, projects }: { workspac
|
|||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
<Suspense fallback={<div></div>}>
|
||||||
|
{selectedProject && <ProjectStructure project={selectedProject} />}
|
||||||
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
{selectedProject && <ProjectStructure project={selectedProject} />}
|
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
<ResizableHandle className="bg-gray-300" />
|
<ResizableHandle className="bg-gray-300" />
|
||||||
</>
|
</>
|
||||||
|
@ -3,23 +3,14 @@ import * as ResizablePrimitive from 'react-resizable-panels';
|
|||||||
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
type PanelGroupProps = React.ComponentProps<typeof ResizablePrimitive.PanelGroup>;
|
const ResizablePanelGroup = ({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
|
||||||
|
|
||||||
const ResizablePanelGroup = ({ className, ...props }: PanelGroupProps) => (
|
|
||||||
<ResizablePrimitive.PanelGroup
|
<ResizablePrimitive.PanelGroup
|
||||||
className={cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', className)}
|
className={cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
type PanelProps = React.ComponentProps<typeof ResizablePrimitive.Panel>;
|
const ResizablePanel = ResizablePrimitive.Panel;
|
||||||
|
|
||||||
const ResizablePanel = ({ className, ...props }: PanelProps) => (
|
|
||||||
<ResizablePrimitive.Panel
|
|
||||||
className={cn('resizable-panel', className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const ResizableHandle = ({
|
const ResizableHandle = ({
|
||||||
withHandle,
|
withHandle,
|
||||||
|
Loading…
Reference in New Issue
Block a user