Merge branch 'fe/refactor/improve-design' into 'fe/develop'
Refactor: 리뷰 탭 분리 See merge request s11-s-project/S11P21S002!269
This commit is contained in:
commit
b82000562a
@ -6,10 +6,6 @@ export default function AdminMenuSidebar() {
|
|||||||
const { workspaceId, projectId } = useParams<{ workspaceId: string; projectId?: string }>();
|
const { workspaceId, projectId } = useParams<{ workspaceId: string; projectId?: string }>();
|
||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
{
|
|
||||||
label: '리뷰',
|
|
||||||
path: projectId ? `/admin/${workspaceId}/reviews/${projectId}` : `/admin/${workspaceId}/reviews`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '멤버 관리',
|
label: '멤버 관리',
|
||||||
path: projectId ? `/admin/${workspaceId}/members/${projectId}` : `/admin/${workspaceId}/members`,
|
path: projectId ? `/admin/${workspaceId}/members/${projectId}` : `/admin/${workspaceId}/members`,
|
||||||
|
@ -2,11 +2,8 @@ import { ResizablePanel, ResizableHandle } from '../ui/resizable';
|
|||||||
import { Link, useLocation, useParams } from 'react-router-dom';
|
import { Link, useLocation, useParams } from 'react-router-dom';
|
||||||
import { SquarePen } from 'lucide-react';
|
import { SquarePen } from 'lucide-react';
|
||||||
import useProjectListQuery from '@/queries/projects/useProjectListQuery';
|
import useProjectListQuery from '@/queries/projects/useProjectListQuery';
|
||||||
import useCreateProjectQuery from '@/queries/projects/useCreateProjectQuery';
|
|
||||||
import useWorkspaceQuery from '@/queries/workspaces/useWorkspaceQuery';
|
import useWorkspaceQuery from '@/queries/workspaces/useWorkspaceQuery';
|
||||||
import { ProjectRequest } from '@/types';
|
|
||||||
import useAuthStore from '@/stores/useAuthStore';
|
import useAuthStore from '@/stores/useAuthStore';
|
||||||
import ProjectCreateModal from '../ProjectCreateModal';
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
export default function AdminProjectSidebar(): JSX.Element {
|
export default function AdminProjectSidebar(): JSX.Element {
|
||||||
@ -20,20 +17,7 @@ export default function AdminProjectSidebar(): JSX.Element {
|
|||||||
|
|
||||||
const { data: projects } = useProjectListQuery(Number(workspaceId), memberId);
|
const { data: projects } = useProjectListQuery(Number(workspaceId), memberId);
|
||||||
|
|
||||||
const createProject = useCreateProjectQuery();
|
|
||||||
|
|
||||||
const handleCreateProject = (data: ProjectRequest) => {
|
|
||||||
createProject.mutate({
|
|
||||||
workspaceId: Number(workspaceId),
|
|
||||||
memberId,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getNewPath = (newProjectId: string) => {
|
const getNewPath = (newProjectId: string) => {
|
||||||
if (location.pathname.includes('reviews')) {
|
|
||||||
return `/admin/${workspaceId}/reviews/${newProjectId}`;
|
|
||||||
}
|
|
||||||
if (location.pathname.includes('members')) {
|
if (location.pathname.includes('members')) {
|
||||||
return `/admin/${workspaceId}/members/${newProjectId}`;
|
return `/admin/${workspaceId}/members/${newProjectId}`;
|
||||||
}
|
}
|
||||||
@ -64,10 +48,6 @@ export default function AdminProjectSidebar(): JSX.Element {
|
|||||||
<button className="p-2">
|
<button className="p-2">
|
||||||
<SquarePen size={16} />
|
<SquarePen size={16} />
|
||||||
</button>
|
</button>
|
||||||
<ProjectCreateModal
|
|
||||||
buttonClass="caption"
|
|
||||||
onSubmit={handleCreateProject}
|
|
||||||
/>
|
|
||||||
</header>
|
</header>
|
||||||
<div className="flex flex-col gap-2 p-4">
|
<div className="flex flex-col gap-2 p-4">
|
||||||
{projects.map((project) => {
|
{projects.map((project) => {
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Link, useParams } from 'react-router-dom';
|
import { Link, useLocation, useParams } from 'react-router-dom';
|
||||||
import useAuthStore from '@/stores/useAuthStore';
|
import useAuthStore from '@/stores/useAuthStore';
|
||||||
import useWorkspaceListQuery from '@/queries/workspaces/useWorkspaceListQuery';
|
import useWorkspaceListQuery from '@/queries/workspaces/useWorkspaceListQuery';
|
||||||
|
|
||||||
export default function WorkspaceNavigation() {
|
export default function WorkspaceNavigation() {
|
||||||
|
const location = useLocation();
|
||||||
|
const isBrowsePage = location.pathname.startsWith('/browse');
|
||||||
|
const isWorkspacePage = location.pathname.startsWith('/workspace');
|
||||||
|
const isReviewPage = location.pathname.startsWith('/review');
|
||||||
|
const isAdminPage = location.pathname.startsWith('/admin');
|
||||||
|
|
||||||
const { workspaceId } = useParams<{ workspaceId: string }>();
|
const { workspaceId } = useParams<{ workspaceId: string }>();
|
||||||
const profile = useAuthStore((state) => state.profile);
|
const profile = useAuthStore((state) => state.profile);
|
||||||
const memberId = profile?.id;
|
const memberId = profile?.id;
|
||||||
@ -21,7 +27,7 @@ export default function WorkspaceNavigation() {
|
|||||||
<nav className="hidden items-center gap-5 md:flex">
|
<nav className="hidden items-center gap-5 md:flex">
|
||||||
<Link
|
<Link
|
||||||
to={activeWorkspaceId ? `/browse/${activeWorkspaceId}` : '/browse'}
|
to={activeWorkspaceId ? `/browse/${activeWorkspaceId}` : '/browse'}
|
||||||
className={cn('text-color-text-default-default', 'font-body-strong', 'text-sm sm:text-base md:text-lg')}
|
className={cn('', isBrowsePage ? 'body-strong' : 'body')}
|
||||||
>
|
>
|
||||||
workspace
|
workspace
|
||||||
</Link>
|
</Link>
|
||||||
@ -29,13 +35,19 @@ export default function WorkspaceNavigation() {
|
|||||||
<>
|
<>
|
||||||
<Link
|
<Link
|
||||||
to={`/workspace/${activeWorkspaceId}`}
|
to={`/workspace/${activeWorkspaceId}`}
|
||||||
className={cn('text-color-text-default-default', 'font-body', 'text-sm sm:text-base md:text-lg')}
|
className={cn('', isWorkspacePage ? 'body-strong' : 'body')}
|
||||||
>
|
>
|
||||||
labeling
|
labeling
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link
|
||||||
|
to={`/review/${activeWorkspaceId}`}
|
||||||
|
className={cn('', isReviewPage ? 'body-strong' : 'body')}
|
||||||
|
>
|
||||||
|
review
|
||||||
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/${activeWorkspaceId}`}
|
to={`/admin/${activeWorkspaceId}`}
|
||||||
className={cn('text-color-text-default-default', 'font-body', 'text-sm sm:text-base md:text-lg')}
|
className={cn('', isAdminPage ? 'body-strong' : 'body')}
|
||||||
>
|
>
|
||||||
admin
|
admin
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
|||||||
import MemberAddForm, { MemberAddFormValues } from './MemberAddForm';
|
import MemberAddForm, { MemberAddFormValues } from './MemberAddForm';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialogCustom';
|
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialogCustom';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Plus } from 'lucide-react';
|
|
||||||
import useAddProjectMemberQuery from '@/queries/projects/useAddProjectMemberQuery';
|
import useAddProjectMemberQuery from '@/queries/projects/useAddProjectMemberQuery';
|
||||||
import { ProjectMemberRequest } from '@/types';
|
import { ProjectMemberRequest } from '@/types';
|
||||||
|
|
||||||
@ -42,12 +41,11 @@ export default function MemberAddModal({ projectId, buttonClass = '' }: MemberAd
|
|||||||
className={`${buttonClass}`}
|
className={`${buttonClass}`}
|
||||||
onClick={handleOpen}
|
onClick={handleOpen}
|
||||||
>
|
>
|
||||||
<Plus size={16} />
|
<span>프로젝트에 새 멤버 초대</span>
|
||||||
<span>프로젝트 멤버 초대하기</span>
|
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogHeader title="새 멤버 초대" />
|
<DialogHeader title="프로젝트에 새 멤버 초대" />
|
||||||
<MemberAddForm onSubmit={handleMemberAdd} />
|
<MemberAddForm onSubmit={handleMemberAdd} />
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
57
frontend/src/components/ReviewLayout/index.tsx
Normal file
57
frontend/src/components/ReviewLayout/index.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { Link, Outlet, useParams } from 'react-router-dom';
|
||||||
|
import Header from '../Header';
|
||||||
|
import useAuthStore from '@/stores/useAuthStore';
|
||||||
|
import useWorkspaceQuery from '@/queries/workspaces/useWorkspaceQuery';
|
||||||
|
import useProjectListQuery from '@/queries/projects/useProjectListQuery';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
import { ProjectResponse } from '@/types';
|
||||||
|
|
||||||
|
export default function ReviewLayout() {
|
||||||
|
const { workspaceId, projectId } = useParams<{ workspaceId: string; projectId?: string }>();
|
||||||
|
const profile = useAuthStore((state) => state.profile);
|
||||||
|
const memberId = profile?.id || 0;
|
||||||
|
|
||||||
|
const { data: workspaceData } = useWorkspaceQuery(Number(workspaceId), memberId);
|
||||||
|
const workspaceTitle = workspaceData?.title || `Workspace-${workspaceId}`;
|
||||||
|
|
||||||
|
const { data: projects } = useProjectListQuery(Number(workspaceId), memberId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Header className="fixed left-0 top-0 w-full" />
|
||||||
|
|
||||||
|
<div className="flex min-h-screen flex-col justify-between">
|
||||||
|
<div className="mt-16 flex flex-1">
|
||||||
|
<div className="flex w-[280px] flex-col border-r border-gray-200 bg-gray-100 p-2">
|
||||||
|
<div className="flex items-center justify-center gap-5 p-2">
|
||||||
|
<Link
|
||||||
|
to={`/review/${workspaceId}`}
|
||||||
|
className="heading w-full overflow-hidden text-ellipsis whitespace-nowrap"
|
||||||
|
>
|
||||||
|
{workspaceTitle}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
{projects.map((project: ProjectResponse) => (
|
||||||
|
<Link
|
||||||
|
key={project.id}
|
||||||
|
to={`/review/${workspaceId}/${project.id}`}
|
||||||
|
className={cn(
|
||||||
|
'cursor-pointer rounded-lg p-3 hover:bg-gray-200',
|
||||||
|
projectId === String(project.id) ? 'body-strong bg-gray-300' : 'body'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{project.title}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex w-[calc(100%-280px)] flex-col gap-24">
|
||||||
|
<main className="h-full grow overflow-y-auto">
|
||||||
|
<Outlet />
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -42,7 +42,7 @@ export default function ReviewItem({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/${workspaceId}/reviews/${projectId}/${reviewId}`}
|
to={`/review/${workspaceId}/${projectId}/${reviewId}`}
|
||||||
className="block hover:bg-gray-100"
|
className="block hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
<div className="flex h-[100px] w-full items-center justify-between border-b-[0.67px] border-[#ececef] bg-[#fbfafd] p-4">
|
<div className="flex h-[100px] w-full items-center justify-between border-b-[0.67px] border-[#ececef] bg-[#fbfafd] p-4">
|
||||||
|
@ -6,6 +6,7 @@ import WorkSpaceCreateModal from '../WorkSpaceCreateModal';
|
|||||||
import { WorkspaceRequest, WorkspaceResponse } from '@/types';
|
import { WorkspaceRequest, WorkspaceResponse } from '@/types';
|
||||||
import useWorkspaceListQuery from '@/queries/workspaces/useWorkspaceListQuery';
|
import useWorkspaceListQuery from '@/queries/workspaces/useWorkspaceListQuery';
|
||||||
import useCreateWorkspaceQuery from '@/queries/workspaces/useCreateWorkspaceQuery';
|
import useCreateWorkspaceQuery from '@/queries/workspaces/useCreateWorkspaceQuery';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
export default function WorkspaceBrowseLayout() {
|
export default function WorkspaceBrowseLayout() {
|
||||||
const { profile } = useAuthStore();
|
const { profile } = useAuthStore();
|
||||||
@ -33,19 +34,22 @@ export default function WorkspaceBrowseLayout() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header className="fixed left-0 top-0 w-full" />
|
<Header className="fixed left-0 top-0 w-full" />
|
||||||
|
|
||||||
<div className="flex min-h-screen flex-col justify-between">
|
<div className="flex min-h-screen flex-col justify-between">
|
||||||
<div className="mt-16 flex flex-1">
|
<div className="mt-16 flex flex-1">
|
||||||
<div className="flex w-[280px] flex-col gap-4 border-r border-gray-200 bg-gray-100 px-6 py-4">
|
<div className="flex w-[280px] flex-col border-r border-gray-200 bg-gray-100 p-2">
|
||||||
<div className="flex items-center justify-center gap-5">
|
<div className="flex items-center justify-center gap-5 p-2">
|
||||||
<h1 className="heading mr-2.5 w-full">내 워크스페이스</h1>
|
<h1 className="heading mr-2.5 w-full overflow-hidden text-ellipsis whitespace-nowrap">내 워크스페이스</h1>
|
||||||
<WorkSpaceCreateModal onSubmit={handleCreateWorkspace} />
|
<WorkSpaceCreateModal onSubmit={handleCreateWorkspace} />
|
||||||
</div>
|
</div>
|
||||||
{workspaces.length > 0 ? (
|
{workspaces.length > 0 ? (
|
||||||
workspaces.map((workspace: WorkspaceResponse) => (
|
workspaces.map((workspace: WorkspaceResponse) => (
|
||||||
<NavLink
|
<NavLink
|
||||||
to={`/browse/${workspace.id}`}
|
|
||||||
key={workspace.id}
|
key={workspace.id}
|
||||||
className={({ isActive }) => (isActive ? 'body-strong' : 'body') + ' cursor-pointer'}
|
to={`/browse/${workspace.id}`}
|
||||||
|
className={({ isActive }) =>
|
||||||
|
cn('cursor-pointer rounded-lg p-3 hover:bg-gray-200', isActive ? 'body-strong bg-gray-300' : 'body')
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{workspace.title}
|
{workspace.title}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
|||||||
import MemberAddForm, { MemberAddFormValues } from './MemberAddForm';
|
import MemberAddForm, { MemberAddFormValues } from './MemberAddForm';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialogCustom';
|
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialogCustom';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Plus } from 'lucide-react';
|
|
||||||
import useAddWorkspaceMemberQuery from '@/queries/workspaces/useAddWorkspaceMemberQuery';
|
import useAddWorkspaceMemberQuery from '@/queries/workspaces/useAddWorkspaceMemberQuery';
|
||||||
|
|
||||||
interface WorkspaceMemberAddModalProps {
|
interface WorkspaceMemberAddModalProps {
|
||||||
@ -42,12 +41,11 @@ export default function WorkspaceMemberAddModal({
|
|||||||
className={`${buttonClass}`}
|
className={`${buttonClass}`}
|
||||||
onClick={handleOpen}
|
onClick={handleOpen}
|
||||||
>
|
>
|
||||||
<Plus size={16} />
|
<span>워크스페이스에 새 멤버 초대</span>
|
||||||
<span>워크스페이스 멤버 초대하기</span>
|
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogHeader title="새 워크스페이스 멤버 초대" />
|
<DialogHeader title="워크스페이스에 새 멤버 초대" />
|
||||||
<MemberAddForm onSubmit={handleSubmit} />
|
<MemberAddForm onSubmit={handleSubmit} />
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -39,7 +39,7 @@ export default function useReviewRequest() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
navigate(`/admin/${workspaceId}/reviews`);
|
navigate(`/review/${workspaceId}`);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -7,7 +7,7 @@ export default function AdminIndex() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (workspaceId) {
|
if (workspaceId) {
|
||||||
navigate(`/admin/${workspaceId}/reviews`);
|
navigate(`/admin/${workspaceId}/members`);
|
||||||
}
|
}
|
||||||
}, [navigate, workspaceId]);
|
}, [navigate, workspaceId]);
|
||||||
|
|
||||||
|
@ -63,12 +63,13 @@ export default function ProjectReviewList() {
|
|||||||
<header className="sticky top-0 z-10 flex h-[57px] items-center gap-1 border-b bg-white px-4">
|
<header className="sticky top-0 z-10 flex h-[57px] items-center gap-1 border-b bg-white px-4">
|
||||||
<h1 className="text-xl font-semibold">프로젝트 리뷰</h1>
|
<h1 className="text-xl font-semibold">프로젝트 리뷰</h1>
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/${workspaceId}/reviews/request`}
|
to={`/review/${workspaceId}/request`}
|
||||||
className="ml-auto"
|
className="ml-auto"
|
||||||
>
|
>
|
||||||
<Button variant="blue">리뷰 요청</Button>
|
<Button variant="blue">리뷰 요청</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<ReviewList
|
<ReviewList
|
||||||
key={`${sortValue}-${activeTab}`}
|
key={`${sortValue}-${activeTab}`}
|
||||||
reviews={projectReviews}
|
reviews={projectReviews}
|
||||||
|
@ -153,7 +153,7 @@ export default function ReviewDetail(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-6 flex justify-end gap-2">
|
<div className="mt-6 flex justify-end gap-2">
|
||||||
<Link to={`/admin/${workspaceId}/reviews`}>
|
<Link to={`/review/${workspaceId}`}>
|
||||||
<Button variant="black">목록으로 돌아가기</Button>
|
<Button variant="black">목록으로 돌아가기</Button>
|
||||||
</Link>
|
</Link>
|
||||||
{isAdminOrManager && reviewDetail.reviewStatus !== 'APPROVED' && reviewDetail.reviewStatus !== 'REJECTED' && (
|
{isAdminOrManager && reviewDetail.reviewStatus !== 'APPROVED' && reviewDetail.reviewStatus !== 'REJECTED' && (
|
||||||
|
@ -28,7 +28,7 @@ export default function ReviewRequest(): JSX.Element {
|
|||||||
reviewData,
|
reviewData,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => navigate(`/admin/${workspaceId}/reviews`),
|
onSuccess: () => navigate(`/review/${workspaceId}`),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -63,7 +63,7 @@ export default function WorkspaceReviewList() {
|
|||||||
<header className="sticky top-0 z-10 flex h-[57px] items-center gap-1 border-b bg-white px-4">
|
<header className="sticky top-0 z-10 flex h-[57px] items-center gap-1 border-b bg-white px-4">
|
||||||
<h1 className="text-xl font-semibold">워크스페이스 리뷰</h1>
|
<h1 className="text-xl font-semibold">워크스페이스 리뷰</h1>
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/${workspaceId}/reviews/request`}
|
to={`/review/${workspaceId}/request`}
|
||||||
className="ml-auto"
|
className="ml-auto"
|
||||||
>
|
>
|
||||||
<Button variant="blue">리뷰 요청</Button>
|
<Button variant="blue">리뷰 요청</Button>
|
||||||
@ -80,9 +80,7 @@ export default function WorkspaceReviewList() {
|
|||||||
setSortValue={setSortValue}
|
setSortValue={setSortValue}
|
||||||
workspaceId={Number(workspaceId)}
|
workspaceId={Number(workspaceId)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{isFetchingNextPage}
|
{isFetchingNextPage}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={loadMoreRef}
|
ref={loadMoreRef}
|
||||||
className="h-1"
|
className="h-1"
|
||||||
|
@ -20,11 +20,13 @@ import NotFound from '@/pages/NotFound';
|
|||||||
import ReviewRequest from '@/pages/ReviewRequest';
|
import ReviewRequest from '@/pages/ReviewRequest';
|
||||||
import ModelIndex from '@/pages/ModelIndex';
|
import ModelIndex from '@/pages/ModelIndex';
|
||||||
import ModelDetail from '@/pages/ModelDetail';
|
import ModelDetail from '@/pages/ModelDetail';
|
||||||
|
import ReviewLayout from '@/components/ReviewLayout';
|
||||||
|
|
||||||
export const webPath = {
|
export const webPath = {
|
||||||
home: () => '/',
|
home: () => '/',
|
||||||
browse: () => '/browse',
|
browse: () => '/browse',
|
||||||
workspace: () => '/workspace',
|
workspace: () => '/workspace',
|
||||||
|
review: () => '/review',
|
||||||
admin: () => `/admin`,
|
admin: () => `/admin`,
|
||||||
oauthCallback: () => '/redirect/oauth2',
|
oauthCallback: () => '/redirect/oauth2',
|
||||||
};
|
};
|
||||||
@ -80,6 +82,32 @@ const router = createBrowserRouter([
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: `${webPath.review()}/:workspaceId`,
|
||||||
|
element: (
|
||||||
|
<Suspense fallback={<div></div>}>
|
||||||
|
<ReviewLayout />
|
||||||
|
</Suspense>
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <WorkspaceReviewList />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'request',
|
||||||
|
element: <ReviewRequest />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':projectId',
|
||||||
|
element: <ProjectReviewList />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':projectId/:reviewId',
|
||||||
|
element: <ReviewDetail />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: `${webPath.admin()}/:workspaceId`,
|
path: `${webPath.admin()}/:workspaceId`,
|
||||||
element: (
|
element: (
|
||||||
@ -92,27 +120,6 @@ const router = createBrowserRouter([
|
|||||||
index: true,
|
index: true,
|
||||||
element: <AdminIndex />,
|
element: <AdminIndex />,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'reviews',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <WorkspaceReviewList />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'request',
|
|
||||||
element: <ReviewRequest />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ':projectId',
|
|
||||||
element: <ProjectReviewList />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ':projectId/:reviewId',
|
|
||||||
element: <ReviewDetail />,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'members',
|
path: 'members',
|
||||||
children: [
|
children: [
|
||||||
|
Loading…
Reference in New Issue
Block a user