릴리스: v1.4.3 사용자 노출 용어 정리 3차
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-04-02 v1.4.3
|
||||
- 용어 전환은 메뉴 타이틀만 바꾸는 것으로 끝나지 않고, 관리자 작업 중 반복해서 보게 되는 토스트와 확인창까지 맞춰야 실제 체감 일관성이 살아난다고 판단했다.
|
||||
|
||||
## 2026-04-02 v1.4.2
|
||||
- 용어 정리를 시작한 뒤에는 일부 화면만 바꾸는 것보다, 관리자 모달과 확인 메시지처럼 실제 운영 중 많이 보는 문구도 함께 맞춰 주는 편이 체감 일관성이 더 높다고 판단했다.
|
||||
|
||||
|
||||
28
docs/todo.md
28
docs/todo.md
@@ -1,11 +1,11 @@
|
||||
# 할 일 및 이슈
|
||||
|
||||
## 단기 확인
|
||||
- 관리자 화면까지 포함한 사용자 노출 `게임` 문구를 2차로 정리했으므로, 실제 운영 흐름에서 뜨는 확인창/토스트/선택 모달까지 표현이 자연스러운지 한 번 더 QA한다.
|
||||
- 관리자 화면까지 포함한 사용자 노출 `게임` 문구를 3차까지 정리했으므로, 실제 운영 흐름에서 뜨는 확인창/토스트/선택 모달까지 표현이 자연스러운지 한 번 더 QA한다.
|
||||
- 왼쪽 사이드 메뉴와 각 화면 타이틀을 한글 기준으로 맞췄으므로, 홈/나의 티어표/즐겨찾기/설정 진입 시 실제 체감이 자연스럽고 중복 표현이 어색하지 않은지 한 번 더 QA한다.
|
||||
- 용어 정리 1차는 사용자 노출 문구만 `주제 / 템플릿`으로 바꿨으므로, 홈/주제 화면/관리자 템플릿 관리에서 어색하게 남은 `게임` 문구가 없는지 한 번 더 QA한다.
|
||||
- 사용자 노출 용어는 `주제 / 템플릿` 기준으로 계속 걷어내고 있으므로, 홈/주제 화면/관리자 템플릿 관리에서 어색하게 남은 `게임` 문구가 없는지 한 번 더 QA한다.
|
||||
- 내부 모델명은 아직 `game`을 유지하므로, 다음 단계에서는 문서와 보조 화면 문구를 더 정리할지, 아니면 내부 리네이밍 계획을 따로 잡을지 결정한다.
|
||||
- 게임 목록과 티어표 카드 썸네일은 기본 이미지 드래그를 막았으므로, 데스크톱 브라우저에서 클릭/드래그 시 원본 이미지 프리뷰가 더 이상 뜨지 않는지 한 번 더 QA한다.
|
||||
- 주제 목록과 티어표 카드 썸네일은 기본 이미지 드래그를 막았으므로, 데스크톱 브라우저에서 클릭/드래그 시 원본 이미지 프리뷰가 더 이상 뜨지 않는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 활성 배경은 공용 인디케이터가 이동하는 방식으로 바뀌었으므로, 홈/내 티어표/즐겨찾기/설정 전환과 레일 접힘 상태 양쪽에서 위치 보정이 자연스러운지 한 번 더 QA한다.
|
||||
- 로그인 화면 상단 토글은 이동형 인디케이터로 바뀌었으므로, 데스크톱과 모바일에서 `로그인 / 회원가입` 전환 애니메이션이 어색하지 않고 포커스/클릭 상태도 자연스러운지 한 번 더 QA한다.
|
||||
- 관리자 카드 설명 줄임은 `line-clamp` 표준 속성까지 함께 선언했으므로, 실제 브라우저별 표시 차이가 없는지 한 번 더 QA한다.
|
||||
@@ -21,21 +21,21 @@
|
||||
- 관리자 템플릿 요청 카드는 썸네일 클릭이 새창 열기 역할로 바뀌었으므로, 썸네일 클릭과 `확인하기` 액션이 서로 헷갈리지 않는지 한 번 더 QA한다.
|
||||
- 티어표 만들기 화면의 `공유하기`는 저장된 티어표에서만 노출되므로, 저장 직후/수정 중/복사본/읽기 전용 상태 각각에서 노출 조건과 클립보드 복사가 자연스러운지 한 번 더 QA한다.
|
||||
- 우측 카피라이트는 이제 공통 오른쪽 레일 footer이므로, 관리자 화면뿐 아니라 홈/프로필 등 오른쪽 사이드가 보이는 화면에서도 같은 최하단 위치에 유지되는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 축소 상태의 하단 액션 아이콘은 홈과 게임 허브에서 서로 다른 아이콘을 쓰도록 나눴으므로, 실제로 두 문맥이 한눈에 구분되는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 축소 상태 최하단의 `티어표 만들기` 아이콘 버튼은 새로 추가했으므로, 홈/게임 허브에서 실제로 같은 위치 감각으로 동작하는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 축소 상태의 하단 액션 아이콘은 홈과 주제 화면에서 서로 다른 아이콘을 쓰도록 나눴으므로, 실제로 두 문맥이 한눈에 구분되는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 축소 상태 최하단의 `티어표 만들기` 아이콘 버튼은 새로 추가했으므로, 홈/주제 화면에서 실제로 같은 위치 감각으로 동작하는지 한 번 더 QA한다.
|
||||
- 관리자 우측 카피라이트 문구는 사이드바 내부 최하단으로 다시 옮겼으므로, 실제 관리자 화면에서 스크롤/창 크기 변화에도 계속 보이는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 축소 상태는 아이콘 줄 높이를 50px 기준으로 통일했으므로, 실제 데스크톱에서 아바타/검색/메뉴 아이콘이 시각적으로 같은 리듬으로 보이는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 검색은 이제 항상 게임 검색으로 홈으로 이동하므로, 홈이 아닌 화면에서 사이드 검색 후 게임 목록 결과로 자연스럽게 이동하는지 한 번 더 QA한다.
|
||||
- 왼쪽 레일 검색은 이제 항상 주제 템플릿 검색으로 홈으로 이동하므로, 홈이 아닌 화면에서 사이드 검색 후 주제 목록 결과로 자연스럽게 이동하는지 한 번 더 QA한다.
|
||||
- 앱 왼쪽 사이드 레일은 접힘 상태 레이아웃을 다시 손봤으므로, 데스크톱에서 접기/펼치기 반복 시 아바타 영역 높이, 아이콘 중앙 정렬, 검색 버튼 간격, 네비게이션 히트 영역이 모두 자연스러운지 한 번 더 QA한다.
|
||||
- 관리자 우측 사이드바 하단 카피라이트 링크는 새 창 외부 링크로 바꿨으므로, 실제 클릭 시 `zenn.town` 연결과 hover 대비가 자연스러운지 한 번 더 QA한다.
|
||||
- 관리자 아이템 상세 모달은 공통 패딩 예외 처리를 다시 넣었으므로, 대형 상세 모달과 일반 게임 선택 모달이 각각 기대한 크기로 보이는지 한 번 더 QA한다.
|
||||
- 아이템 관리 모달의 공용 게임 선택기에서는 이미 연결된 게임이 비활성화되므로, 실제 운영 데이터에서 중복 연결 방지와 `이미 추가됨` 표시가 기대대로 읽히는지 한 번 더 QA한다.
|
||||
- 공용 게임 선택 모달을 아이템 관리 모달에도 붙였으므로, 관리자 `게임 관리 / 전체 티어표 관리 / 아이템 관리` 세 흐름에서 같은 검색/선택 UX가 자연스럽게 느껴지는지 한 번 더 QA한다.
|
||||
- 관리자 `/admin/games?gameId=...` 직접 진입과 새로고침에서 선택 게임이 정상 복원되고 콘솔 오류가 없는지 한 번 더 QA한다.
|
||||
- 공용 `게임 선택` 검색 모달은 새로 붙였으므로, 게임 관리 선택/전체 티어표 관리 필터 양쪽에서 검색어 입력, 선택, 해제, 뒤로가기 흐름을 한 번 더 QA한다.
|
||||
- 관리자 `전체 티어표 관리`의 게임 필터와 관리 모달은 새로 붙였으므로, 실제 운영 데이터에서 필터 전환 후 공개/비공개 집계, 제목 수정, 비공개 전환, 삭제 흐름이 자연스럽게 이어지는지 한 번 더 QA한다.
|
||||
- 관리자 게임 관리 상단의 `전체 / 공개 / 비공개` 티어표 수치와 전체 티어표 관리 상단 집계가 실제 운영 데이터와 맞는지, 공개 전환 직후 숫자가 자연스럽게 갱신되는지 한 번 더 QA한다.
|
||||
- 관리자 아이템 상세 모달은 왼쪽 선택 카드와 오른쪽 상세 본문으로 다시 정리했으므로, 데스크톱/모바일에서 긴 게임 목록과 긴 참조 목록이 각각 자연스럽게 스크롤되는지 한 번 더 QA한다.
|
||||
- 관리자 아이템 상세 모달은 공통 패딩 예외 처리를 다시 넣었으므로, 대형 상세 모달과 일반 템플릿 선택 모달이 각각 기대한 크기로 보이는지 한 번 더 QA한다.
|
||||
- 아이템 관리 모달의 공용 템플릿 선택기에서는 이미 연결된 템플릿이 비활성화되므로, 실제 운영 데이터에서 중복 연결 방지와 `이미 추가됨` 표시가 기대대로 읽히는지 한 번 더 QA한다.
|
||||
- 공용 템플릿 선택 모달을 아이템 관리 모달에도 붙였으므로, 관리자 `템플릿 관리 / 전체 티어표 관리 / 아이템 관리` 세 흐름에서 같은 검색/선택 UX가 자연스럽게 느껴지는지 한 번 더 QA한다.
|
||||
- 관리자 `/admin/games?gameId=...` 직접 진입과 새로고침에서 선택 템플릿이 정상 복원되고 콘솔 오류가 없는지 한 번 더 QA한다.
|
||||
- 공용 `템플릿 선택` 검색 모달은 새로 붙였으므로, 템플릿 관리 선택/전체 티어표 관리 필터 양쪽에서 검색어 입력, 선택, 해제, 뒤로가기 흐름을 한 번 더 QA한다.
|
||||
- 관리자 `전체 티어표 관리`의 템플릿 필터와 관리 모달은 새로 붙였으므로, 실제 운영 데이터에서 필터 전환 후 공개/비공개 집계, 제목 수정, 비공개 전환, 삭제 흐름이 자연스럽게 이어지는지 한 번 더 QA한다.
|
||||
- 관리자 템플릿 관리 상단의 `전체 / 공개 / 비공개` 티어표 수치와 전체 티어표 관리 상단 집계가 실제 운영 데이터와 맞는지, 공개 전환 직후 숫자가 자연스럽게 갱신되는지 한 번 더 QA한다.
|
||||
- 관리자 아이템 상세 모달은 왼쪽 선택 카드와 오른쪽 상세 본문으로 다시 정리했으므로, 데스크톱/모바일에서 긴 템플릿 목록과 긴 참조 목록이 각각 자연스럽게 스크롤되는지 한 번 더 QA한다.
|
||||
- 관리자 계정으로 `/admin/...`을 직접 새로고침했을 때 홈으로 튕기지 않고 그대로 유지되는지, 실제 세션이 살아 있는 브라우저와 만료된 브라우저 각각에서 한 번 더 QA한다.
|
||||
- 티어표 만들기 화면의 보드 드롭존은 점선/높이/중앙 정렬로 존재감이 커졌으므로, 데스크톱과 모바일에서 파일 선택 버튼과 안내 문구 밀도를 한 번 더 QA한다.
|
||||
- 관리자 썸네일 드롭존과 기본 아이템 추가 드롭존은 에디터 드롭존과 시각 문법을 맞췄으므로, 라이트모드와 좁은 화면에서 아이콘 대비와 배경 밝기가 과하지 않은지 한 번 더 QA한다.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# 업데이트 로그
|
||||
|
||||
## 2026-04-02 v1.4.3
|
||||
- 관리자 토스트, 확인창, 요청 처리 안내처럼 실제로 자주 보이는 운영 문구까지 `주제 / 템플릿` 기준으로 한 번 더 정리해, 화면 제목뿐 아니라 작업 피드백도 더 일관되게 맞췄다.
|
||||
|
||||
## 2026-04-02 v1.4.2
|
||||
- 관리자 화면과 보조 모달에 남아 있던 사용자 노출 `게임` 문구를 추가로 걷어내고, `템플릿 / 주제` 기준 표현으로 더 통일했다.
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ export function useAdminCustomItems({
|
||||
async function promoteCustomItem(item) {
|
||||
resetMessages()
|
||||
if (!customItemModalTargetGameId.value) {
|
||||
error.value = '추가할 게임을 먼저 선택해주세요.'
|
||||
error.value = '추가할 템플릿을 먼저 선택해주세요.'
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ export function useAdminFeaturedGames({
|
||||
resetMessages()
|
||||
if (!gameId || featuredGameIds.value.includes(gameId)) return
|
||||
if (featuredGameIds.value.length >= 50) {
|
||||
error.value = '상단 고정 게임은 최대 50개까지만 설정할 수 있어요.'
|
||||
error.value = '상단 고정 템플릿은 최대 50개까지만 설정할 수 있어요.'
|
||||
return
|
||||
}
|
||||
featuredGameIds.value = [...featuredGameIds.value, gameId]
|
||||
@@ -76,9 +76,9 @@ export function useAdminFeaturedGames({
|
||||
.filter((game) => game.displayRank != null)
|
||||
.sort((a, b) => a.displayRank - b.displayRank)
|
||||
.map((game) => game.id)
|
||||
success.value = '홈 화면 게임 순서를 저장했어요.'
|
||||
success.value = '홈 화면 템플릿 순서를 저장했어요.'
|
||||
} catch (e) {
|
||||
error.value = '게임 순서 저장에 실패했어요.'
|
||||
error.value = '템플릿 순서 저장에 실패했어요.'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ export function useAdminGameManager({
|
||||
await syncGameItemSortable()
|
||||
} catch (e) {
|
||||
selectedGame.value = null
|
||||
error.value = '게임 정보를 불러오지 못했어요.'
|
||||
error.value = '템플릿 정보를 불러오지 못했어요.'
|
||||
} finally {
|
||||
isGameLoading.value = false
|
||||
}
|
||||
@@ -196,9 +196,9 @@ export function useAdminGameManager({
|
||||
const sourceRequest = templateRequests.value.find((entry) => entry.id === activeTemplateRequest.value.id) || activeTemplateRequest.value
|
||||
mergeRequestItemsIntoDrafts(sourceRequest)
|
||||
}
|
||||
success.value = '게임이 생성됐어요. 이어서 썸네일과 기본 아이템을 관리할 수 있어요.'
|
||||
success.value = '템플릿이 생성됐어요. 이어서 썸네일과 기본 아이템을 관리할 수 있어요.'
|
||||
} catch (e) {
|
||||
error.value = '게임 생성 실패(관리자 권한/중복 ID 확인)'
|
||||
error.value = '템플릿 생성 실패(관리자 권한/중복 ID 확인)'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ export function useAdminGameManager({
|
||||
const draftGameId = (activeTemplateRequest.value?.draftGameId || '').trim()
|
||||
const draftGameName = (activeTemplateRequest.value?.draftGameName || '').trim()
|
||||
if (!draftGameId || !draftGameName) {
|
||||
error.value = '먼저 신규 템플릿의 게임 이름과 게임 ID를 저장해주세요.'
|
||||
error.value = '먼저 신규 템플릿의 이름과 템플릿 ID를 저장해주세요.'
|
||||
return
|
||||
}
|
||||
await createGame({
|
||||
@@ -269,7 +269,7 @@ export function useAdminGameManager({
|
||||
}
|
||||
|
||||
if (!selectedGameId.value) {
|
||||
error.value = '게임을 먼저 선택해주세요.'
|
||||
error.value = '템플릿을 먼저 선택해주세요.'
|
||||
return
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ export function useAdminGameManager({
|
||||
|
||||
resetUploadState()
|
||||
await loadGame()
|
||||
success.value = `게임 기본 아이템 ${uploadCount}개 추가를 완료했어요.`
|
||||
success.value = `템플릿 기본 아이템 ${uploadCount}개 추가를 완료했어요.`
|
||||
} catch (e) {
|
||||
const apiError = e?.data?.error || ''
|
||||
if (apiError === 'no_items_selected') {
|
||||
@@ -320,11 +320,11 @@ export function useAdminGameManager({
|
||||
}
|
||||
if (apiError === 'promote_items_failed') {
|
||||
const detail = e?.data?.detail ? ` (${e.data.detail})` : ''
|
||||
error.value = `요청 아이템을 게임 기본 아이템으로 옮기지 못했어요.${detail}`
|
||||
error.value = `요청 아이템을 템플릿 기본 아이템으로 옮기지 못했어요.${detail}`
|
||||
return
|
||||
}
|
||||
if (apiError === 'game_not_found') {
|
||||
error.value = '선택한 게임을 찾지 못했어요.'
|
||||
error.value = '선택한 템플릿을 찾지 못했어요.'
|
||||
return
|
||||
}
|
||||
error.value = '아이템 추가에 실패했어요.'
|
||||
|
||||
@@ -41,8 +41,8 @@ export function useAdminTemplateRequests({
|
||||
}
|
||||
|
||||
function templateRequestReviewHint(request) {
|
||||
if (request.type === 'create') return '게임 생성 후 필요한 아이템만 골라 추가하고, 끝나면 여기서 처리 완료하세요.'
|
||||
return '확인하기를 누르면 게임 관리 화면에 요청 아이템이 임시 추가되어 필요한 것만 선별 저장할 수 있어요.'
|
||||
if (request.type === 'create') return '템플릿 생성 후 필요한 아이템만 골라 추가하고, 끝나면 여기서 처리 완료하세요.'
|
||||
return '확인하기를 누르면 템플릿 관리 화면에 요청 아이템이 임시 추가되어 필요한 것만 선별 저장할 수 있어요.'
|
||||
}
|
||||
|
||||
async function startTemplateRequestReview(request) {
|
||||
@@ -77,7 +77,7 @@ export function useAdminTemplateRequests({
|
||||
if (nextGameId) await selectAdminGame(nextGameId)
|
||||
mergeRequestItemsIntoDrafts(syncedRequest)
|
||||
}
|
||||
success.value = '요청 아이템을 게임 관리 화면으로 가져왔어요. 필요한 항목만 골라서 추가해 주세요.'
|
||||
success.value = '요청 아이템을 템플릿 관리 화면으로 가져왔어요. 필요한 항목만 골라서 추가해 주세요.'
|
||||
} catch (e) {
|
||||
error.value = '요청 확인 단계로 이동하지 못했어요.'
|
||||
} finally {
|
||||
|
||||
@@ -1647,7 +1647,7 @@ function userAvatarFallback(user) {
|
||||
<section class="wrap adminUiScope">
|
||||
<!-- <h2 class="title">관리자</h2> -->
|
||||
<div class="card">
|
||||
<!-- <div class="desc">기능이 많아진 만큼 관리 영역을 게임, 아이템, 회원 관리로 나눠서 정리합니다.</div> -->
|
||||
<!-- <div class="desc">기능이 많아진 만큼 관리 영역을 템플릿, 아이템, 회원 관리로 나눠서 정리합니다.</div> -->
|
||||
<div v-if="!auth.user" class="warn">로그인이 필요해요.</div>
|
||||
<div v-else-if="!isAdmin" class="warn">이 계정은 관리자 권한이 없어요.</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user