feat: 프론트엔드 프로젝트 우선 구조 재구성 (Phase 2-a)
- 데이터 계층 신설: types/project·useProject·project.store (프로젝트 CRUD·페이지네이션) - useTask/useMember/useActivity 경로를 /projects/:projectId/... 로 전환 - task·my-task·activity 타입/스토어 repoId/repoName → projectId/projectName - 알림 store 라우팅·문구 프로젝트화, 활동 타입 repo.linked/unlinked·project.* 반영 - 라우팅 /projects/... 전면 교체, / → /projects 리다이렉트 - 페이지 rename Repo*→Project* (List/Create/Detail/Settings/Members/Activity) - ProjectCreatePage: Gitea 저장소 폼 → 단순 프로젝트 생성 폼으로 재작성 - RepoHeader→ProjectHeader, RepoTabs→ProjectTabs, AppShell 네비 프로젝트화 - 죽은 파일 삭제: repo.store·useRepo·GiteaRepoBar Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import { useAuthStore } from '@/stores/auth.store'
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/repos',
|
||||
redirect: '/projects',
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
@@ -20,63 +20,63 @@ const routes: RouteRecordRaw[] = [
|
||||
meta: { requiresAuth: false },
|
||||
},
|
||||
{
|
||||
path: '/repos',
|
||||
name: 'repo-list',
|
||||
component: () => import('@/pages/relay/RepoListPage.vue'),
|
||||
path: '/projects',
|
||||
name: 'project-list',
|
||||
component: () => import('@/pages/relay/ProjectListPage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
// 정적 경로 '/repos/new' 는 동적 '/repos/:repoId' 보다 먼저 선언해 우선 매칭되게 한다
|
||||
path: '/repos/new',
|
||||
name: 'repo-create',
|
||||
component: () => import('@/pages/relay/RepoCreatePage.vue'),
|
||||
// 정적 '/projects/new' 는 동적 '/projects/:projectId' 보다 먼저 선언
|
||||
path: '/projects/new',
|
||||
name: 'project-create',
|
||||
component: () => import('@/pages/relay/ProjectCreatePage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/repos/:repoId',
|
||||
name: 'repo-detail',
|
||||
component: () => import('@/pages/relay/RepoDetailPage.vue'),
|
||||
path: '/projects/:projectId',
|
||||
name: 'project-detail',
|
||||
component: () => import('@/pages/relay/ProjectDetailPage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/repos/:repoId/members',
|
||||
name: 'repo-members',
|
||||
component: () => import('@/pages/relay/RepoMembersPage.vue'),
|
||||
path: '/projects/:projectId/members',
|
||||
name: 'project-members',
|
||||
component: () => import('@/pages/relay/ProjectMembersPage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/repos/:repoId/activity',
|
||||
name: 'repo-activity',
|
||||
component: () => import('@/pages/relay/RepoActivityPage.vue'),
|
||||
path: '/projects/:projectId/activity',
|
||||
name: 'project-activity',
|
||||
component: () => import('@/pages/relay/ProjectActivityPage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/repos/:repoId/settings',
|
||||
name: 'repo-settings',
|
||||
component: () => import('@/pages/relay/RepoSettingsPage.vue'),
|
||||
path: '/projects/:projectId/settings',
|
||||
name: 'project-settings',
|
||||
component: () => import('@/pages/relay/ProjectSettingsPage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/repos/:repoId/tasks/new',
|
||||
path: '/projects/:projectId/tasks/new',
|
||||
name: 'task-create',
|
||||
component: () => import('@/pages/relay/TaskCreatePage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
// 업무 수정 — 생성 폼(TaskCreatePage)을 편집 모드로 재사용
|
||||
path: '/repos/:repoId/tasks/:taskId/edit',
|
||||
path: '/projects/:projectId/tasks/:taskId/edit',
|
||||
name: 'task-edit',
|
||||
component: () => import('@/pages/relay/TaskCreatePage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/repos/:repoId/tasks/:taskId',
|
||||
path: '/projects/:projectId/tasks/:taskId',
|
||||
name: 'task-detail',
|
||||
component: () => import('@/pages/relay/TaskDetailPage.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
// '내 업무' — 담당/지시 저장소 횡단 집계
|
||||
// '내 업무' — 담당/지시 프로젝트 횡단 집계
|
||||
path: '/tasks',
|
||||
name: 'my-tasks',
|
||||
component: () => import('@/pages/relay/MyTasksPage.vue'),
|
||||
@@ -103,14 +103,18 @@ router.beforeEach(async (to) => {
|
||||
await authStore.bootstrap()
|
||||
}
|
||||
|
||||
// 보호 라우트인데 미로그인 → 로그인 페이지로 (로그인 후에는 항상 저장소 목록으로 진입)
|
||||
// 보호 라우트인데 미로그인 → 로그인 페이지로 (로그인 후에는 항상 프로젝트 목록으로 진입)
|
||||
if (to.meta.requiresAuth && !authStore.isLoggedIn) {
|
||||
return { name: 'login' }
|
||||
}
|
||||
|
||||
// 이미 로그인 상태에서 로그인/회원가입 진입 → 저장소 목록으로
|
||||
if (!to.meta.requiresAuth && authStore.isLoggedIn && (to.name === 'login' || to.name === 'signup')) {
|
||||
return { path: '/repos' }
|
||||
// 이미 로그인 상태에서 로그인/회원가입 진입 → 프로젝트 목록으로
|
||||
if (
|
||||
!to.meta.requiresAuth &&
|
||||
authStore.isLoggedIn &&
|
||||
(to.name === 'login' || to.name === 'signup')
|
||||
) {
|
||||
return { path: '/projects' }
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user