Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ed08d1e34 | |||
| a733c97991 |
@@ -1,5 +1,11 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-04-02 v1.4.5
|
||||
- 내부 리네이밍은 한 번에 API와 DB까지 건드리기보다, 홈·주제 화면·에디터처럼 영향 범위가 비교적 명확한 프런트 핵심 흐름부터 `game` 의존 이름을 줄여 나가는 편이 더 안전하다고 판단했다.
|
||||
|
||||
## 2026-04-02 v1.4.4
|
||||
- 용어 정리 마무리 단계에서는 눈에 잘 띄는 영어 헤더를 그대로 두기보다, 홈과 관리자처럼 진입 빈도가 높은 화면의 상단 라벨까지 한국어로 맞춰야 전체 제품 인상이 더 자연스럽다고 판단했다.
|
||||
|
||||
## 2026-04-02 v1.4.3
|
||||
- 용어 전환은 메뉴 타이틀만 바꾸는 것으로 끝나지 않고, 관리자 작업 중 반복해서 보게 되는 토스트와 확인창까지 맞춰야 실제 체감 일관성이 살아난다고 판단했다.
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# 할 일 및 이슈
|
||||
|
||||
## 단기 확인
|
||||
- 내부 리네이밍 1단계로 홈/주제 화면/에디터/App 셸의 로컬 상태명은 먼저 정리했으므로, 다음 단계에서는 관리자 내부 `selectedGame / selectedGameId / games` 묶음을 같은 기준으로 옮긴다.
|
||||
- 화면/문서 층의 용어 정리는 거의 마무리됐으므로, 다음 단계에서는 내부 `gameId / games` 모델을 정말 `topic / template` 쪽으로 옮길지 범위를 먼저 정리한다.
|
||||
- 관리자 화면까지 포함한 사용자 노출 `게임` 문구를 3차까지 정리했으므로, 실제 운영 흐름에서 뜨는 확인창/토스트/선택 모달까지 표현이 자연스러운지 한 번 더 QA한다.
|
||||
- 왼쪽 사이드 메뉴와 각 화면 타이틀을 한글 기준으로 맞췄으므로, 홈/나의 티어표/즐겨찾기/설정 진입 시 실제 체감이 자연스럽고 중복 표현이 어색하지 않은지 한 번 더 QA한다.
|
||||
- 사용자 노출 용어는 `주제 / 템플릿` 기준으로 계속 걷어내고 있으므로, 홈/주제 화면/관리자 템플릿 관리에서 어색하게 남은 `게임` 문구가 없는지 한 번 더 QA한다.
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# 업데이트 로그
|
||||
|
||||
## 2026-04-02 v1.4.5
|
||||
- 내부 리네이밍 1단계를 시작해 홈, 주제 화면, 티어표 편집기, 앱 셸에서 `games / gameId / gameName` 중심의 로컬 상태명을 `templates / topicId / templateId / templateName` 계열로 먼저 정리했다.
|
||||
- 경로와 API는 그대로 둔 채 프런트 내부에서 자주 읽는 상태명부터 바꿔, 이후 `/games` 라우트와 관리자 상태를 손볼 때 의미 충돌이 덜 나도록 기반을 만들었다.
|
||||
|
||||
## 2026-04-02 v1.4.4
|
||||
- 홈 화면 `Topic Library`와 일부 영어 헤더를 `주제 선택 / 티어표 / 관리자 작업실 / 티어표 만들기 / 작업 공간`으로 정리해, 화면 타이틀과 상단 레이블까지 한국어 기준으로 거의 통일했다.
|
||||
|
||||
## 2026-04-02 v1.4.3
|
||||
- 관리자 토스트, 확인창, 요청 처리 안내처럼 실제로 자주 보이는 운영 문구까지 `주제 / 템플릿` 기준으로 한 번 더 정리해, 화면 제목뿐 아니라 작업 피드백도 더 일관되게 맞췄다.
|
||||
|
||||
|
||||
@@ -134,8 +134,8 @@ const isGuideNextDisabled = computed(() => guideStepIndex.value >= guideSteps.le
|
||||
const isLightTheme = computed(() => themeMode.value === 'light')
|
||||
const themeToggleLabel = computed(() => (isLightTheme.value ? '다크 모드' : '라이트 모드'))
|
||||
const showSettingsThemePanel = computed(() => false && route.name === 'profile')
|
||||
const showGameHubViewToggle = computed(() => route.name === 'gameHub')
|
||||
const gameHubViewMode = computed(() => (route.query.view === 'list' ? 'list' : 'grid'))
|
||||
const showTopicViewToggle = computed(() => route.name === 'gameHub')
|
||||
const topicViewMode = computed(() => (route.query.view === 'list' ? 'list' : 'grid'))
|
||||
const leftBottomPrimaryAction = computed(() => {
|
||||
if (!authReady.value) return null
|
||||
if (route.name === 'home' && auth.user) {
|
||||
@@ -176,7 +176,7 @@ const routeMeta = computed(() => {
|
||||
}
|
||||
if (route.name === 'editEditor' || route.name === 'newEditor') {
|
||||
return {
|
||||
title: 'Deck Builder',
|
||||
title: '티어표 만들기',
|
||||
subtitle: '티어표 편집 및 공유',
|
||||
contextTitle: '편집 패널',
|
||||
contextText: '현재 편집 옵션은 중앙 화면 안에 유지되어 있습니다. 다음 단계에서 우측 패널로 정리해갈게요.',
|
||||
@@ -186,7 +186,7 @@ const routeMeta = computed(() => {
|
||||
}
|
||||
if (isAdminRoute.value) {
|
||||
return {
|
||||
title: 'Admin Workspace',
|
||||
title: '관리자 작업실',
|
||||
subtitle: '템플릿·아이템·회원 관리',
|
||||
contextTitle: '운영 노트',
|
||||
contextText: '관리자 화면은 기능이 많아 우선 공통 셸 톤을 맞췄고, 세부 패널은 다음 단계에서 시안 방식으로 더 세밀하게 나눌 예정입니다.',
|
||||
@@ -237,7 +237,7 @@ const routeMeta = computed(() => {
|
||||
return {
|
||||
title: 'Tier Maker',
|
||||
subtitle: '주제 템플릿으로 만드는 티어표',
|
||||
contextTitle: 'Workspace',
|
||||
contextTitle: '작업 공간',
|
||||
contextText: '현재 화면에 맞는 도구와 안내를 여기에 배치할 수 있습니다.',
|
||||
actionLabel: '홈으로',
|
||||
action: () => router.push('/'),
|
||||
@@ -344,7 +344,7 @@ function toggleRightRail() {
|
||||
}
|
||||
}
|
||||
|
||||
function setGameHubViewMode(mode) {
|
||||
function setTopicViewMode(mode) {
|
||||
if (route.name !== 'gameHub') return
|
||||
const nextQuery = { ...route.query }
|
||||
if (mode === 'list') nextQuery.view = 'list'
|
||||
@@ -499,11 +499,11 @@ function submitGlobalSearch() {
|
||||
<span class="workspaceHead__brandTitle">Tier Maker</span>
|
||||
</div>
|
||||
<div class="workspaceHead__actions">
|
||||
<div v-if="showGameHubViewToggle" class="viewToggle" role="group" aria-label="티어표 보기 방식">
|
||||
<button class="ghostIcon ghostIcon--iconOnly" :class="{ 'ghostIcon--active': gameHubViewMode === 'grid' }" type="button" aria-label="그리드 보기" @click="setGameHubViewMode('grid')">
|
||||
<div v-if="showTopicViewToggle" class="viewToggle" role="group" aria-label="티어표 보기 방식">
|
||||
<button class="ghostIcon ghostIcon--iconOnly" :class="{ 'ghostIcon--active': topicViewMode === 'grid' }" type="button" aria-label="그리드 보기" @click="setTopicViewMode('grid')">
|
||||
<SvgIcon :src="iconGridView" :size="24" />
|
||||
</button>
|
||||
<button class="ghostIcon ghostIcon--iconOnly" :class="{ 'ghostIcon--active': gameHubViewMode === 'list' }" type="button" aria-label="리스트 보기" @click="setGameHubViewMode('list')">
|
||||
<button class="ghostIcon ghostIcon--iconOnly" :class="{ 'ghostIcon--active': topicViewMode === 'list' }" type="button" aria-label="리스트 보기" @click="setTopicViewMode('list')">
|
||||
<SvgIcon :src="iconLists" :size="24" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1655,7 +1655,7 @@ function userAvatarFallback(user) {
|
||||
<div class="adminWorkspace">
|
||||
<div class="adminMain">
|
||||
<header class="adminHero">
|
||||
<div class="adminHero__eyebrow">Admin Workspace</div>
|
||||
<div class="adminHero__eyebrow">관리자 작업실</div>
|
||||
<h2 class="adminHero__title">{{ activeTabTitle }}</h2>
|
||||
<p class="adminHero__desc">{{ activeTabDescription }}</p>
|
||||
<div class="adminHero__stats">
|
||||
|
||||
@@ -9,9 +9,8 @@ const route = useRoute()
|
||||
const router = useRouter()
|
||||
const auth = useAuthStore()
|
||||
|
||||
const gameId = computed(() => route.params.gameId)
|
||||
|
||||
const gameName = ref('')
|
||||
const topicId = computed(() => route.params.gameId)
|
||||
const topicName = ref('')
|
||||
const tierLists = ref([])
|
||||
const error = ref('')
|
||||
const query = ref('')
|
||||
@@ -55,10 +54,10 @@ onMounted(async () => {
|
||||
async function loadTierLists() {
|
||||
try {
|
||||
const [gameRes, listRes] = await Promise.all([
|
||||
api.getGame(gameId.value),
|
||||
api.searchPublicTierLists(gameId.value, query.value),
|
||||
api.getGame(topicId.value),
|
||||
api.searchPublicTierLists(topicId.value, query.value),
|
||||
])
|
||||
gameName.value = gameRes.game?.name || gameId.value
|
||||
topicName.value = gameRes.game?.name || topicId.value
|
||||
brokenThumbnailIds.value = {}
|
||||
tierLists.value = listRes.tierLists || []
|
||||
} catch (e) {
|
||||
@@ -68,14 +67,14 @@ async function loadTierLists() {
|
||||
|
||||
function createNew() {
|
||||
if (!auth.user) {
|
||||
router.push(`/login?redirect=/editor/${gameId.value}/new`)
|
||||
router.push(`/login?redirect=/editor/${topicId.value}/new`)
|
||||
return
|
||||
}
|
||||
router.push(`/editor/${gameId.value}/new`)
|
||||
router.push(`/editor/${topicId.value}/new`)
|
||||
}
|
||||
|
||||
function openTierList(id) {
|
||||
router.push(`/editor/${gameId.value}/${id}`)
|
||||
router.push(`/editor/${topicId.value}/${id}`)
|
||||
}
|
||||
|
||||
function submitSearch() {
|
||||
@@ -87,7 +86,7 @@ function submitSearch() {
|
||||
<section class="dashboardHero">
|
||||
<div class="dashboardHero__left">
|
||||
<div class="dashboardHero__eyebrow">Collection</div>
|
||||
<h2 class="dashboardHero__title">{{ gameName || gameId }}</h2>
|
||||
<h2 class="dashboardHero__title">{{ topicName || topicId }}</h2>
|
||||
<p class="dashboardHero__desc">이 주제의 공개 티어표를 탐색하고, 바로 새 보드를 만들어 같은 흐름으로 이어갈 수 있어요.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -11,12 +11,12 @@ const route = useRoute()
|
||||
const router = useRouter()
|
||||
const auth = useAuthStore()
|
||||
|
||||
const items = ref([])
|
||||
const templateRecords = ref([])
|
||||
const error = ref('')
|
||||
const loadingFavoriteId = ref('')
|
||||
const query = computed(() => (typeof route.query.q === 'string' ? route.query.q.trim().toLowerCase() : ''))
|
||||
const games = computed(() => {
|
||||
const filtered = items.value
|
||||
const templates = computed(() => {
|
||||
const filtered = templateRecords.value
|
||||
.filter((item) => item.id !== 'freeform')
|
||||
.filter((item) => {
|
||||
if (!query.value) return true
|
||||
@@ -33,34 +33,34 @@ const games = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
async function loadGames() {
|
||||
async function loadTemplates() {
|
||||
try {
|
||||
const data = await api.listGames()
|
||||
items.value = data.games || []
|
||||
templateRecords.value = data.games || []
|
||||
} catch (e) {
|
||||
error.value = '백엔드에 연결할 수 없어요. backend 서버가 실행 중인지 확인해주세요.'
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(loadGames)
|
||||
watch(() => auth.user?.id, loadGames)
|
||||
onMounted(loadTemplates)
|
||||
watch(() => auth.user?.id, loadTemplates)
|
||||
|
||||
function goGame(gameId) {
|
||||
router.push(`/games/${gameId}`)
|
||||
function openTopic(templateId) {
|
||||
router.push(`/games/${templateId}`)
|
||||
}
|
||||
|
||||
async function toggleFavorite(game, event) {
|
||||
async function toggleFavorite(template, event) {
|
||||
event?.stopPropagation()
|
||||
if (!auth.user) {
|
||||
router.push(`/login?redirect=${encodeURIComponent(route.fullPath || '/')}`)
|
||||
return
|
||||
}
|
||||
if (!game?.id || loadingFavoriteId.value === game.id) return
|
||||
if (!template?.id || loadingFavoriteId.value === template.id) return
|
||||
|
||||
try {
|
||||
loadingFavoriteId.value = game.id
|
||||
const res = game.isFavorited ? await api.unfavoriteGame(game.id) : await api.favoriteGame(game.id)
|
||||
items.value = items.value.map((entry) => (entry.id === game.id ? { ...entry, ...res.game } : entry))
|
||||
loadingFavoriteId.value = template.id
|
||||
const res = template.isFavorited ? await api.unfavoriteGame(template.id) : await api.favoriteGame(template.id)
|
||||
templateRecords.value = templateRecords.value.map((entry) => (entry.id === template.id ? { ...entry, ...res.game } : entry))
|
||||
} catch (e) {
|
||||
error.value = '즐겨찾기 변경에 실패했어요.'
|
||||
} finally {
|
||||
@@ -68,41 +68,41 @@ async function toggleFavorite(game, event) {
|
||||
}
|
||||
}
|
||||
|
||||
function thumbUrl(g) {
|
||||
return g.thumbnailSrc ? toApiUrl(g.thumbnailSrc) : ''
|
||||
function templateThumbUrl(template) {
|
||||
return template.thumbnailSrc ? toApiUrl(template.thumbnailSrc) : ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="pageHead">
|
||||
<div class="pageHead__main">
|
||||
<div class="pageHead__eyebrow">Workspace</div>
|
||||
<h1 class="pageHead__title">Topic Library</h1>
|
||||
<div class="pageHead__eyebrow">Topic</div>
|
||||
<h1 class="pageHead__title">주제 선택</h1>
|
||||
<p class="pageHead__desc">자주 쓰는 주제 템플릿을 빠르게 고르고, 필요하면 바로 커스텀 티어표를 시작할 수 있어요.</p>
|
||||
<p v-if="query" class="pageHead__searchState">"{{ query }}"에 맞는 주제 템플릿만 보고 있어요.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div v-if="error" class="error">{{ error }}</div>
|
||||
<TransitionGroup v-if="games.length" name="libraryCard" tag="section" class="libraryGrid">
|
||||
<article v-for="g in games" :key="g.id" class="libraryCard">
|
||||
<TransitionGroup v-if="templates.length" name="libraryCard" tag="section" class="libraryGrid">
|
||||
<article v-for="template in templates" :key="template.id" class="libraryCard">
|
||||
<button
|
||||
class="libraryCard__favorite"
|
||||
type="button"
|
||||
:class="{ 'libraryCard__favorite--active': g.isFavorited }"
|
||||
:disabled="loadingFavoriteId === g.id"
|
||||
@click.stop="toggleFavorite(g, $event)"
|
||||
:class="{ 'libraryCard__favorite--active': template.isFavorited }"
|
||||
:disabled="loadingFavoriteId === template.id"
|
||||
@click.stop="toggleFavorite(template, $event)"
|
||||
>
|
||||
<SvgIcon class="libraryCard__favoriteIcon" :src="kidStarIcon" :size="18" />
|
||||
</button>
|
||||
<button class="libraryCard__main" type="button" @click="goGame(g.id)">
|
||||
<button class="libraryCard__main" type="button" @click="openTopic(template.id)">
|
||||
<div class="libraryCard__thumbWrap">
|
||||
<img v-if="thumbUrl(g)" class="libraryCard__thumb" :src="thumbUrl(g)" :alt="g.name" draggable="false" />
|
||||
<img v-if="templateThumbUrl(template)" class="libraryCard__thumb" :src="templateThumbUrl(template)" :alt="template.name" draggable="false" />
|
||||
<div v-else class="libraryCard__thumbFallback">대표 썸네일</div>
|
||||
</div>
|
||||
<div class="libraryCard__body">
|
||||
<div class="libraryCard__title">{{ g.name }}</div>
|
||||
<div class="libraryCard__meta">{{ g.id }}</div>
|
||||
<div class="libraryCard__title">{{ template.name }}</div>
|
||||
<div class="libraryCard__meta">{{ template.id }}</div>
|
||||
</div>
|
||||
</button>
|
||||
</article>
|
||||
|
||||
@@ -68,7 +68,7 @@ function openList(t) {
|
||||
<template>
|
||||
<section class="pageHead">
|
||||
<div class="pageHead__main">
|
||||
<div class="pageHead__eyebrow">Library</div>
|
||||
<div class="pageHead__eyebrow">Tier Lists</div>
|
||||
<h2 class="pageHead__title">나의 티어표</h2>
|
||||
<div class="pageHead__desc">직접 저장한 티어표를 같은 카드 레이아웃으로 다시 열고 정리할 수 있어요.</div>
|
||||
</div>
|
||||
|
||||
@@ -19,10 +19,10 @@ const auth = useAuthStore()
|
||||
const toast = useToast()
|
||||
const globalRightRailOpen = inject('rightRailOpen', ref(true))
|
||||
const localRightRailTarget = inject('localRightRailTarget', '#local-right-rail-root')
|
||||
const gameId = computed(() => route.params.gameId)
|
||||
const templateId = computed(() => route.params.gameId)
|
||||
const tierListId = computed(() => route.params.tierListId)
|
||||
const previewMode = computed(() => route.query.preview === '1')
|
||||
const gameName = ref('')
|
||||
const templateName = ref('')
|
||||
|
||||
const columns = ref([{ id: 'col-1', name: '' }])
|
||||
const groups = ref([
|
||||
@@ -123,19 +123,19 @@ const copiedFromLabel = computed(() => {
|
||||
const customItems = computed(() => getOrderedItems().filter((item) => item?.origin === 'custom'))
|
||||
const hasSavedTierList = computed(() => !!(persistedTierListId.value || (tierListId.value && tierListId.value !== 'new')))
|
||||
const canRequestTemplateCreate = computed(
|
||||
() => canEdit.value && hasSavedTierList.value && gameId.value === 'freeform' && customItems.value.length > 0
|
||||
() => canEdit.value && hasSavedTierList.value && templateId.value === 'freeform' && customItems.value.length > 0
|
||||
)
|
||||
const canRequestTemplateUpdate = computed(
|
||||
() => canEdit.value && hasSavedTierList.value && gameId.value !== 'freeform' && customItems.value.length > 0
|
||||
() => canEdit.value && hasSavedTierList.value && templateId.value !== 'freeform' && customItems.value.length > 0
|
||||
)
|
||||
const canSubmitTemplateCreateRequest = computed(() => !!templateRequestDraftTitle.value.trim() && !!templateRequestDraftDescription.value.trim())
|
||||
const canSubmitTemplateUpdateRequest = computed(() => !!templateRequestDraftTitle.value.trim() && !!templateRequestDraftDescription.value.trim())
|
||||
const templateRequestTargetLabel = computed(() => (gameId.value === 'freeform' ? '새로운 템플릿' : (gameName.value || gameId.value || '선택한 주제')))
|
||||
const templateRequestTargetLabel = computed(() => (templateId.value === 'freeform' ? '새로운 템플릿' : (templateName.value || templateId.value || '선택한 주제')))
|
||||
const shareTierListUrl = computed(() => {
|
||||
const savedTierListId = persistedTierListId.value || (tierListId.value && tierListId.value !== 'new' ? tierListId.value : '')
|
||||
if (!savedTierListId) return ''
|
||||
if (typeof window === 'undefined') return `/editor/${gameId.value}/${savedTierListId}?preview=1`
|
||||
return new URL(`/editor/${gameId.value}/${savedTierListId}?preview=1`, window.location.origin).toString()
|
||||
if (typeof window === 'undefined') return `/editor/${templateId.value}/${savedTierListId}?preview=1`
|
||||
return new URL(`/editor/${templateId.value}/${savedTierListId}?preview=1`, window.location.origin).toString()
|
||||
})
|
||||
|
||||
watch(error, (message) => {
|
||||
@@ -672,7 +672,7 @@ function buildPayload(existingId) {
|
||||
const finalTitle = effectiveTitle.value
|
||||
return {
|
||||
id: existingId || undefined,
|
||||
gameId: gameId.value,
|
||||
gameId: templateId.value,
|
||||
title: finalTitle,
|
||||
thumbnailSrc: thumbnailSrc.value || '',
|
||||
description: (description.value || '').trim(),
|
||||
@@ -697,7 +697,7 @@ async function persistTierList({ showModal = false } = {}) {
|
||||
persistedTierListId.value = savedTierListId || ''
|
||||
title.value = res.tierList?.title || payload.title
|
||||
if (tierListId.value === 'new' && res.tierList?.id) {
|
||||
await router.replace(`/editor/${gameId.value}/${res.tierList.id}`)
|
||||
await router.replace(`/editor/${templateId.value}/${res.tierList.id}`)
|
||||
}
|
||||
updatedAt.value = Number(res.tierList?.updatedAt || Date.now())
|
||||
authorName.value = res.tierList?.authorName || effectiveAuthorName.value
|
||||
@@ -793,7 +793,7 @@ async function confirmDeleteTierList() {
|
||||
await api.deleteTierList(currentTierListId)
|
||||
closeDeleteModal()
|
||||
toast.success('티어표를 삭제했어요.')
|
||||
router.push(gameId.value === 'freeform' ? '/me' : `/games/${gameId.value}`)
|
||||
router.push(templateId.value === 'freeform' ? '/me' : `/games/${templateId.value}`)
|
||||
} catch (e) {
|
||||
error.value = '티어표 삭제에 실패했어요.'
|
||||
} finally {
|
||||
@@ -808,7 +808,7 @@ async function duplicateCurrentTierList() {
|
||||
const duplicatedId = data.tierList?.id
|
||||
if (!duplicatedId) throw new Error('duplicate_failed')
|
||||
toast.success('티어표를 복사해 내 작업으로 가져왔어요.')
|
||||
router.push(`/editor/${gameId.value}/${duplicatedId}`)
|
||||
router.push(`/editor/${templateId.value}/${duplicatedId}`)
|
||||
} catch (e) {
|
||||
error.value = '티어표 복사에 실패했어요.'
|
||||
}
|
||||
@@ -841,7 +841,7 @@ async function requestTemplate(type) {
|
||||
await api.requestTierListTemplate({
|
||||
type,
|
||||
sourceTierListId: sourceId,
|
||||
gameId: gameId.value,
|
||||
gameId: templateId.value,
|
||||
requestTitle: templateRequestDraftTitle.value.trim(),
|
||||
requestDescription: templateRequestDraftDescription.value.trim(),
|
||||
thumbnailSrc: saved.tierList?.thumbnailSrc || thumbnailSrc.value || '',
|
||||
@@ -892,13 +892,13 @@ onMounted(() => {
|
||||
authorAccountName.value = ((auth.user?.email || '').trim().split('@')[0] || '').trim()
|
||||
|
||||
if (isNewTierList.value && !auth.user) {
|
||||
router.replace(`/login?redirect=/editor/${gameId.value}/new`)
|
||||
router.replace(`/login?redirect=/editor/${templateId.value}/new`)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const gameRes = await api.getGame(gameId.value)
|
||||
gameName.value = gameRes.game?.name || gameId.value
|
||||
const gameRes = await api.getGame(templateId.value)
|
||||
templateName.value = gameRes.game?.name || templateId.value
|
||||
const base = (gameRes.items || []).map((img) => ({
|
||||
id: img.id,
|
||||
src: img.src,
|
||||
@@ -1079,7 +1079,7 @@ onUnmounted(() => {
|
||||
<div class="modalCard" role="dialog" aria-modal="true" aria-labelledby="deleteTierListTitle">
|
||||
<div id="deleteTierListTitle" class="modalCard__title">티어표 삭제</div>
|
||||
<div class="modalCard__desc">
|
||||
"{{ title || gameName || '이 티어표' }}"를 삭제할까요? 삭제 후에는 복구할 수 없어요.
|
||||
"{{ title || templateName || '이 티어표' }}"를 삭제할까요? 삭제 후에는 복구할 수 없어요.
|
||||
</div>
|
||||
<div class="modalCard__actions">
|
||||
<button class="btn btn--ghost" @click="closeDeleteModal">취소</button>
|
||||
@@ -1120,7 +1120,7 @@ onUnmounted(() => {
|
||||
<div class="editorMain">
|
||||
<section class="head">
|
||||
<div class="editorMain__headCopy">
|
||||
<div class="editorMain__title">{{ gameName || gameId }}</div>
|
||||
<div class="editorMain__title">{{ templateName || templateId }}</div>
|
||||
<div class="editorMain__subtitle">
|
||||
<template v-if="canEdit">
|
||||
행/열 이름과 순서를 바꾸고 아이템을 드래그해서 배치할 수 있어요.
|
||||
@@ -1131,7 +1131,7 @@ onUnmounted(() => {
|
||||
</div>
|
||||
<div v-if="sourceTierListId" class="editorMain__sourceNote">
|
||||
<span>복사본</span>
|
||||
<button class="editorMain__sourceLink" type="button" @click="router.push(`/editor/${gameId}/${sourceTierListId}`)">{{ copiedFromLabel }}</button>
|
||||
<button class="editorMain__sourceLink" type="button" @click="router.push(`/editor/${templateId}/${sourceTierListId}`)">{{ copiedFromLabel }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user