generated from ttipo/project-base
feat(frontend): 설정(비밀번호 · 부재중 응답) · 메일함 관리 · 스팸 신고 · 원문 내려받기 화면
- 설정 메뉴를 계정 · 메일 묶음으로, 비밀번호 바꾸기(칸 아래 오류 · 30초 한도)와 부재중 자동 응답(기간 · 미리 보기 · 나가기 확인),
메일함 패널의 부재중 안내(1분마다 다시 계산)
- 메일함 패널의 내 메일함 묶음 · ⋯ 메뉴(보이는 영역 안에 열기) · 대화상자(만들기 · 이름 바꾸기 · 지우기), 목록 머리 비우기
— 확인한 그 메일함만, 휴지통 비우기와 메일함 지우기는 함께 돌리지 않는다
- 오래 걸리는 처리의 진행 알림("…하는 중 · 600 / 1,234통" → 결과), 세션이 바뀌면 멈추고 늦게 온 응답은 쓰지 않는다
- 읽기 화면 · 여러 통 도구 줄의 스팸 신고 / 스팸 아님 + 되돌리기, ⋯ › 원문 내려받기 (.eml)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
import { documentTitle } from '@/shared/utils/document-title'
|
||||
import { MAIL_SEARCH_MESSAGE_ROUTE, MAIL_SEARCH_ROUTE } from '@/shared/utils/mail-list-source'
|
||||
import { toSafeRedirect } from '@/shared/utils/redirect'
|
||||
import { useAuthStore } from '@/stores/auth.store'
|
||||
import { routes } from './routes'
|
||||
|
||||
declare module 'vue-router' {
|
||||
interface RouteMeta {
|
||||
@@ -17,70 +17,6 @@ declare module 'vue-router' {
|
||||
}
|
||||
}
|
||||
|
||||
// 목록·본문 라우트가 같은 컴포넌트를 쓰도록 한 번만 정의한다 (메일을 바꿔도 화면을 다시 만들지 않는다)
|
||||
const MailboxPage = () => import('@/pages/mail/MailboxPage.vue')
|
||||
|
||||
// 코드 스플리팅 — 모든 페이지 컴포넌트는 lazy import 처리
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: { name: 'mail' },
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('@/pages/LoginPage.vue'),
|
||||
meta: { guestOnly: true, title: '로그인' },
|
||||
},
|
||||
{
|
||||
path: '/mail',
|
||||
component: () => import('@/pages/mail/MailLayout.vue'),
|
||||
meta: { requiresAuth: true, title: '메일' },
|
||||
children: [
|
||||
// /mail → 메일함을 불러온 뒤 받은편지함으로 (MailboxPage 가 이동시킨다)
|
||||
{ path: '', name: 'mail', component: MailboxPage },
|
||||
{
|
||||
path: 'compose',
|
||||
name: 'mail-compose',
|
||||
component: () => import('@/pages/mail/ComposePage.vue'),
|
||||
meta: { title: '메일 쓰기' },
|
||||
},
|
||||
// 검색 결과 /mail/search?q=…&in=<메일함 id | all> · 결과에서 연 메일 /mail/search/<메일 id>?q=…&in=… (계약 2절 "검색")
|
||||
// 고정 경로라 :mailboxId 보다 앞에 둔다 — 같은 화면(MailboxPage)이 목록 출처만 바꿔 그린다
|
||||
{ path: 'search', name: MAIL_SEARCH_ROUTE, component: MailboxPage, meta: { title: '메일 검색' } },
|
||||
{
|
||||
path: 'search/:messageId',
|
||||
name: MAIL_SEARCH_MESSAGE_ROUTE,
|
||||
component: MailboxPage,
|
||||
meta: { title: '메일 검색' },
|
||||
},
|
||||
{ path: ':mailboxId', name: 'mail-mailbox', component: MailboxPage },
|
||||
{ path: ':mailboxId/:messageId', name: 'mail-message', component: MailboxPage },
|
||||
],
|
||||
},
|
||||
{
|
||||
// 설정 — 왼쪽 메뉴(메일 › 서명) + 하위 화면. /settings 는 첫 메뉴로 바꿔 끼운다 (앱 레일의 "설정")
|
||||
path: '/settings',
|
||||
component: () => import('@/pages/settings/SettingsLayout.vue'),
|
||||
meta: { requiresAuth: true, title: '설정' },
|
||||
children: [
|
||||
{ path: '', name: 'settings', redirect: { name: 'settings-mail-signature' } },
|
||||
{
|
||||
path: 'mail/signature',
|
||||
name: 'settings-mail-signature',
|
||||
component: () => import('@/pages/settings/MailSignaturePage.vue'),
|
||||
meta: { title: '메일 서명' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'not-found',
|
||||
component: () => import('@/pages/NotFoundPage.vue'),
|
||||
meta: { title: '페이지를 찾을 수 없음' },
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes,
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
import { SETTINGS_ROUTES } from '@/shared/constants/settings-menu'
|
||||
import { MAIL_SEARCH_MESSAGE_ROUTE, MAIL_SEARCH_ROUTE } from '@/shared/utils/mail-list-source'
|
||||
|
||||
// 앱의 라우트 표 — 라우터(index.ts)와 라우트 테스트가 함께 쓴다 (이 파일은 라우터를 만들지 않는다)
|
||||
|
||||
// 목록·본문 라우트가 같은 컴포넌트를 쓰도록 한 번만 정의한다 (메일을 바꿔도 화면을 다시 만들지 않는다)
|
||||
const MailboxPage = () => import('@/pages/mail/MailboxPage.vue')
|
||||
|
||||
// 코드 스플리팅 — 모든 페이지 컴포넌트는 lazy import 처리
|
||||
export const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: { name: 'mail' },
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('@/pages/LoginPage.vue'),
|
||||
meta: { guestOnly: true, title: '로그인' },
|
||||
},
|
||||
{
|
||||
path: '/mail',
|
||||
component: () => import('@/pages/mail/MailLayout.vue'),
|
||||
meta: { requiresAuth: true, title: '메일' },
|
||||
children: [
|
||||
// /mail → 메일함을 불러온 뒤 받은편지함으로 (MailboxPage 가 이동시킨다)
|
||||
{ path: '', name: 'mail', component: MailboxPage },
|
||||
{
|
||||
path: 'compose',
|
||||
name: 'mail-compose',
|
||||
component: () => import('@/pages/mail/ComposePage.vue'),
|
||||
meta: { title: '메일 쓰기' },
|
||||
},
|
||||
// 검색 결과 /mail/search?q=…&in=<메일함 id | all> · 결과에서 연 메일 /mail/search/<메일 id>?q=…&in=… (계약 2절 "검색")
|
||||
// 고정 경로라 :mailboxId 보다 앞에 둔다 — 같은 화면(MailboxPage)이 목록 출처만 바꿔 그린다
|
||||
{ path: 'search', name: MAIL_SEARCH_ROUTE, component: MailboxPage, meta: { title: '메일 검색' } },
|
||||
{
|
||||
path: 'search/:messageId',
|
||||
name: MAIL_SEARCH_MESSAGE_ROUTE,
|
||||
component: MailboxPage,
|
||||
meta: { title: '메일 검색' },
|
||||
},
|
||||
{ path: ':mailboxId', name: 'mail-mailbox', component: MailboxPage },
|
||||
{ path: ':mailboxId/:messageId', name: 'mail-message', component: MailboxPage },
|
||||
],
|
||||
},
|
||||
{
|
||||
// 설정 — 왼쪽 메뉴(계정 › 비밀번호 / 메일 › 서명 · 부재중 자동 응답) + 하위 화면.
|
||||
// /settings 는 첫 메뉴(계정 › 비밀번호)로 바꿔 끼운다 (앱 레일의 "설정")
|
||||
path: '/settings',
|
||||
component: () => import('@/pages/settings/SettingsLayout.vue'),
|
||||
meta: { requiresAuth: true, title: '설정' },
|
||||
children: [
|
||||
{ path: '', name: 'settings', redirect: { name: SETTINGS_ROUTES.password } },
|
||||
{
|
||||
path: 'account/password',
|
||||
name: SETTINGS_ROUTES.password,
|
||||
component: () => import('@/pages/settings/AccountPasswordPage.vue'),
|
||||
meta: { title: '비밀번호' },
|
||||
},
|
||||
{
|
||||
path: 'mail/signature',
|
||||
name: SETTINGS_ROUTES.signature,
|
||||
component: () => import('@/pages/settings/MailSignaturePage.vue'),
|
||||
meta: { title: '메일 서명' },
|
||||
},
|
||||
{
|
||||
path: 'mail/vacation',
|
||||
name: SETTINGS_ROUTES.vacation,
|
||||
component: () => import('@/pages/settings/MailVacationPage.vue'),
|
||||
meta: { title: '부재중 자동 응답' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'not-found',
|
||||
component: () => import('@/pages/NotFoundPage.vue'),
|
||||
meta: { title: '페이지를 찾을 수 없음' },
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user