|
|
|
|
@@ -571,7 +571,7 @@ function formatImageJobSourceCategory(category) {
|
|
|
|
|
case 'tierlists':
|
|
|
|
|
return '티어표 썸네일'
|
|
|
|
|
case 'games':
|
|
|
|
|
return '게임/템플릿 이미지'
|
|
|
|
|
return '주제/템플릿 이미지'
|
|
|
|
|
case 'avatars':
|
|
|
|
|
return '프로필 아바타'
|
|
|
|
|
default:
|
|
|
|
|
@@ -599,7 +599,7 @@ function customItemDeleteImpactText(item) {
|
|
|
|
|
if (item.sourceType === 'template') {
|
|
|
|
|
return item.isAssetLibraryItem
|
|
|
|
|
? `"${item.label}" 보관 자산 항목을 정리할까요? 라이브러리 항목만 제거되고, 같은 이미지를 쓰는 다른 참조는 그대로 유지됩니다.`
|
|
|
|
|
: `"${item.label}" 템플릿 항목을 정리할까요? 연결된 템플릿과 같은 게임의 저장된 티어표에서 이 항목이 함께 제거될 수 있어요.`
|
|
|
|
|
: `"${item.label}" 템플릿 항목을 정리할까요? 연결된 템플릿과 같은 주제의 저장된 티어표에서 이 항목이 함께 제거될 수 있어요.`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return `"${item.label}" 사용자 업로드 이미지를 삭제할까요? 현재 항목만 정리됩니다.`
|
|
|
|
|
@@ -703,7 +703,7 @@ async function confirmImageReset() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function cleanupMissingImageReferences() {
|
|
|
|
|
const ok = window.confirm('파일이 실제로 없는 이미지 참조만 정리할까요? 누락된 썸네일은 비워지고, 누락된 게임/커스텀 아이템은 관련 참조와 함께 정리됩니다.')
|
|
|
|
|
const ok = window.confirm('파일이 실제로 없는 이미지 참조만 정리할까요? 누락된 썸네일은 비워지고, 누락된 템플릿/커스텀 아이템은 관련 참조와 함께 정리됩니다.')
|
|
|
|
|
if (!ok) return
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
@@ -714,10 +714,10 @@ async function cleanupMissingImageReferences() {
|
|
|
|
|
success.value =
|
|
|
|
|
`누락 참조를 정리했어요. ` +
|
|
|
|
|
`아바타 ${result.clearedAvatars || 0}건, ` +
|
|
|
|
|
`게임 썸네일 ${result.clearedGameThumbnails || 0}건, ` +
|
|
|
|
|
`템플릿 썸네일 ${result.clearedGameThumbnails || 0}건, ` +
|
|
|
|
|
`티어표 썸네일 ${result.clearedTierListThumbnails || 0}건, ` +
|
|
|
|
|
`요청 썸네일 ${result.clearedTemplateRequestThumbnails || 0}건, ` +
|
|
|
|
|
`게임 아이템 ${result.deletedGameItems || 0}건, ` +
|
|
|
|
|
`템플릿 아이템 ${result.deletedGameItems || 0}건, ` +
|
|
|
|
|
`커스텀 아이템 ${result.deletedCustomItems || 0}건`
|
|
|
|
|
} catch (e) {
|
|
|
|
|
error.value = '누락 이미지 참조 정리에 실패했어요.'
|
|
|
|
|
@@ -1180,10 +1180,10 @@ async function saveGameVisibility() {
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
await refreshGames()
|
|
|
|
|
success.value = data.game?.isPublic ? '게임을 공개 상태로 전환했어요.' : '게임을 비공개 상태로 전환했어요.'
|
|
|
|
|
success.value = data.game?.isPublic ? '템플릿을 공개 상태로 전환했어요.' : '템플릿을 비공개 상태로 전환했어요.'
|
|
|
|
|
return true
|
|
|
|
|
} catch (e) {
|
|
|
|
|
error.value = '게임 공개 상태를 저장하지 못했어요.'
|
|
|
|
|
error.value = '템플릿 공개 상태를 저장하지 못했어요.'
|
|
|
|
|
return false
|
|
|
|
|
} finally {
|
|
|
|
|
gameVisibilitySaving.value = false
|
|
|
|
|
@@ -1225,9 +1225,9 @@ async function removeGameItem(itemId) {
|
|
|
|
|
if (!res.ok) throw new Error('failed')
|
|
|
|
|
|
|
|
|
|
await loadGame()
|
|
|
|
|
success.value = '게임 기본 아이템을 삭제했어요.'
|
|
|
|
|
success.value = '템플릿 기본 아이템을 삭제했어요.'
|
|
|
|
|
} catch (e) {
|
|
|
|
|
error.value = '게임 기본 아이템 삭제에 실패했어요.'
|
|
|
|
|
error.value = '템플릿 기본 아이템 삭제에 실패했어요.'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1258,7 +1258,7 @@ async function removeGame() {
|
|
|
|
|
resetMessages()
|
|
|
|
|
if (!selectedGameId.value || !selectedGame.value?.game) return
|
|
|
|
|
|
|
|
|
|
const ok = window.confirm(`"${selectedGame.value.game.name}" 게임을 삭제할까요? 관련 기본 아이템과 티어표도 함께 삭제됩니다.`)
|
|
|
|
|
const ok = window.confirm(`"${selectedGame.value.game.name}" 템플릿을 삭제할까요? 관련 기본 아이템과 티어표도 함께 삭제됩니다.`)
|
|
|
|
|
if (!ok) return
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
@@ -1273,7 +1273,7 @@ async function removeGame() {
|
|
|
|
|
selectedGame.value = null
|
|
|
|
|
resetUploadState()
|
|
|
|
|
await refreshGames()
|
|
|
|
|
success.value = `${deletedName} 게임을 삭제했어요.`
|
|
|
|
|
success.value = `${deletedName} 템플릿을 삭제했어요.`
|
|
|
|
|
} catch (e) {
|
|
|
|
|
error.value = '템플릿 삭제에 실패했어요.'
|
|
|
|
|
}
|
|
|
|
|
@@ -1950,12 +1950,12 @@ function userAvatarFallback(user) {
|
|
|
|
|
<aside class="customItemModal__pickerPanel">
|
|
|
|
|
<div class="customItemModal__pickerHead">
|
|
|
|
|
<div class="customItemModal__pickerEyebrow">GAME PICKER</div>
|
|
|
|
|
<div class="customItemModal__pickerTitle">템플릿으로 추가할 게임</div>
|
|
|
|
|
<div class="customItemModal__pickerTitle">아이템을 추가할 템플릿</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="adminSelectionCard">
|
|
|
|
|
<div class="adminSelectionCard__label">선택한 템플릿</div>
|
|
|
|
|
<div class="adminSelectionCard__title">{{ customItemTargetGame?.name || '아직 선택하지 않음' }}</div>
|
|
|
|
|
<div class="adminSelectionCard__meta">{{ customItemTargetGame?.id || '게임을 골라 주세요.' }}</div>
|
|
|
|
|
<div class="adminSelectionCard__meta">{{ customItemTargetGame?.id || '템플릿을 골라 주세요.' }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="customItemModal__pickerActions">
|
|
|
|
|
<button class="btn btn--ghost" type="button" @click="openGamePickerModal('custom-item-target')">템플릿 선택</button>
|
|
|
|
|
@@ -1983,11 +1983,11 @@ function userAvatarFallback(user) {
|
|
|
|
|
<div class="customItemModal__metaList">
|
|
|
|
|
<div class="customItemModal__metaRow"><span>파일</span><strong :title="modalTargetCustomItem.src.split('/').pop()">{{ modalTargetCustomItem.src.split('/').pop() }}</strong></div>
|
|
|
|
|
<div class="customItemModal__metaRow"><span>업로더/출처</span><strong :title="modalTargetCustomItem.ownerName">{{ modalTargetCustomItem.ownerName }}</strong></div>
|
|
|
|
|
<div class="customItemModal__metaRow"><span>템플릿 연결</span><strong>{{ visibleLinkedGames.length }}개 게임</strong></div>
|
|
|
|
|
<div class="customItemModal__metaRow"><span>템플릿 연결</span><strong>{{ visibleLinkedGames.length }}개 템플릿</strong></div>
|
|
|
|
|
<div class="customItemModal__metaRow"><span>등록일</span><strong>{{ fmt(modalTargetCustomItem.createdAt) }}</strong></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="customItemModal__linked">
|
|
|
|
|
<span class="customItemModal__label">템플릿에 사용 중인 게임</span>
|
|
|
|
|
<span class="customItemModal__label">이 이미지를 사용하는 템플릿</span>
|
|
|
|
|
<div v-if="visibleLinkedGames.length" class="customItemModal__chips">
|
|
|
|
|
<button v-for="game in visibleLinkedGames" :key="game.id" type="button" class="pill pill--link" @click="jumpToGameAdmin(game.id)">{{ game.name }}</button>
|
|
|
|
|
</div>
|
|
|
|
|
@@ -2012,7 +2012,7 @@ function userAvatarFallback(user) {
|
|
|
|
|
<div>
|
|
|
|
|
<div class="modalCard__title">템플릿 선택</div>
|
|
|
|
|
<div class="modalCard__desc">
|
|
|
|
|
{{ gamePickerMode === 'tierlists-filter' ? '특정 게임의 티어표만 보려면 게임을 선택하세요.' : '관리할 게임을 검색해서 바로 열 수 있어요.' }}
|
|
|
|
|
{{ gamePickerMode === 'tierlists-filter' ? '특정 주제의 티어표만 보려면 템플릿을 선택하세요.' : '관리할 템플릿을 검색해서 바로 열 수 있어요.' }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<button class="btn btn--ghost btn--small" @click="closeGamePickerModal">닫기</button>
|
|
|
|
|
@@ -2029,7 +2029,7 @@ function userAvatarFallback(user) {
|
|
|
|
|
type="button"
|
|
|
|
|
@click="setAdminTierListGameId(''); closeGamePickerModal()"
|
|
|
|
|
>
|
|
|
|
|
모든 게임 보기
|
|
|
|
|
모든 주제 보기
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="gamePickerModalList">
|
|
|
|
|
|