feat(frontend): 새 메일 확인·메일 검색·여러 통 선택과 처리 화면

- 화면이 보이는 동안 1분마다 바뀐 것을 묻고 목록·메일함 숫자·탭 제목 "(N)" 을 맞춘다 — 늦게 온 응답은 목록 변경 세대로 버린다
- 상단 검색 칸 → /mail/search (범위 전환, 결과 없음 안내에 엔진 한계)
- 표·분할 보기에서 여러 통 고르기와 도구 줄, 이동 메뉴, 휴지통 이동 + 되돌리기, 휴지통에서만 확인 뒤 영구 삭제
- 읽기 화면의 삭제도 DELETE 대신 휴지통 이동 · 확인 뒤 영구 삭제 — 다른 창이 휴지통에 넣은 메일을 확인 없이 지우지 않게
- 되돌리기 알림은 띄운 세션에서만 움직인다 — 메일 id 는 계정마다 겹칠 수 있다
- 메일 스토어를 기능별 setup 모듈로 나눴다 (공개 API 그대로)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 23:56:09 +09:00
parent 090ee361a3
commit 192807f943
83 changed files with 7421 additions and 1157 deletions
+13 -2
View File
@@ -1,7 +1,8 @@
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
import { useAuth } from '@/composables/useAuth'
import { APP_NAME } from '@/shared/constants/brand'
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'
@@ -44,6 +45,15 @@ const routes: RouteRecordRaw[] = [
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 },
],
@@ -92,8 +102,9 @@ router.beforeEach(async (to) => {
return true
})
// 메일 화면에서는 MailLayout(useMailTabTitle)이 받은편지함의 안 읽은 수 "(N) " 를 앞에 다시 붙인다 — 이동이 끝난 뒤에 돈다
router.afterEach((to) => {
document.title = to.meta.title ? `${to.meta.title} · ${APP_NAME}` : APP_NAME
document.title = documentTitle(to.meta.title)
})
export default router