From 65796a0893afab79b79e881ac57405b67765b504 Mon Sep 17 00:00:00 2001 From: ttipo Date: Tue, 30 Jun 2026 20:41:59 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=93=9C=EB=9D=BC=EC=9D=B4=EB=B8=8C=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EB=B0=B0=EC=A7=80=EB=A5=BC=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=EC=9E=90=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=95=ED=99=95=ED=9E=88=20=ED=91=9C=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kind(4종) 대신 확장자로 라벨 산출 — 엑셀 XLS, 파워포인트 PPT, CSV/JSON/TXT, 영상·오디오 등 구분 + 색상 추가 Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/src/pages/relay/DrivePage.vue | 18 +++++++++++++++--- frontend/src/shared/utils/format.ts | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/relay/DrivePage.vue b/frontend/src/pages/relay/DrivePage.vue index 08ae8af..43ffad9 100644 --- a/frontend/src/pages/relay/DrivePage.vue +++ b/frontend/src/pages/relay/DrivePage.vue @@ -9,7 +9,7 @@ import EmptyState from '@/components/common/EmptyState.vue' import DriveNameModal from '@/components/drive/DriveNameModal.vue' import { useDriveStore } from '@/stores/drive.store' import { useDialog } from '@/composables/useDialog' -import { fileBadge, formatBytes, relativeTimeKo } from '@/shared/utils/format' +import { fileBadgeOf, formatBytes, relativeTimeKo } from '@/shared/utils/format' import { DRIVE_ACCEPT, DRIVE_MAX_FILE_SIZE, @@ -409,8 +409,8 @@ watch( > {{ fileBadge(f.kind).label }} + :class="fileBadgeOf(f.name).cls" + >{{ fileBadgeOf(f.name).label }} {{ f.name }} {{ formatBytes(f.size) }} · {{ relativeTimeKo(f.updatedAt) }} @@ -681,6 +681,18 @@ watch( .dr-badge.fi-doc { background: #3d8bf2; } +.dr-badge.fi-xls { + background: #1f9d57; +} +.dr-badge.fi-ppt { + background: #e0823d; +} +.dr-badge.fi-txt { + background: #5b6470; +} +.dr-badge.fi-media { + background: #c0469d; +} .dr-main { min-width: 0; display: flex; diff --git a/frontend/src/shared/utils/format.ts b/frontend/src/shared/utils/format.ts index 323c0d8..6f8ab46 100644 --- a/frontend/src/shared/utils/format.ts +++ b/frontend/src/shared/utils/format.ts @@ -82,6 +82,31 @@ export function fileBadge(kind: FileKind): { label: string; cls: string } { return map[kind] } +/** + * 확장자 기준 세분화 배지(라벨/색상) — 4종 kind 보다 정확히 표기. + * 예: 엑셀 → XLS, 파워포인트 → PPT, 워드 → DOC. (드라이브 파일 행 등) + */ +export function fileBadgeOf(name: string): { label: string; cls: string } { + const ext = name.split('.').pop()?.toLowerCase() ?? '' + if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp'].includes(ext)) + return { label: 'IMG', cls: 'fi-img' } + if (ext === 'pdf') return { label: 'PDF', cls: 'fi-pdf' } + if (['xls', 'xlsx'].includes(ext)) return { label: 'XLS', cls: 'fi-xls' } + if (['doc', 'docx'].includes(ext)) return { label: 'DOC', cls: 'fi-doc' } + if (['ppt', 'pptx'].includes(ext)) return { label: 'PPT', cls: 'fi-ppt' } + if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) + return { label: 'ZIP', cls: 'fi-zip' } + if (ext === 'csv') return { label: 'CSV', cls: 'fi-txt' } + if (ext === 'json') return { label: 'JSON', cls: 'fi-txt' } + if (['txt', 'md'].includes(ext)) + return { label: ext.toUpperCase(), cls: 'fi-txt' } + if (['mp4', 'webm', 'mov', 'avi', 'mkv'].includes(ext)) + return { label: 'VID', cls: 'fi-media' } + if (['mp3', 'wav', 'ogg', 'flac', 'm4a'].includes(ext)) + return { label: 'AUD', cls: 'fi-media' } + return { label: 'FILE', cls: 'fi-doc' } +} + /** 바이트 수를 사람이 읽기 쉬운 단위로 (예: 19293798 → "18.4 MB") */ export function formatBytes(bytes: number): string { if (!Number.isFinite(bytes) || bytes <= 0) return '0 B'