fix(media): 회원 썸네일을 관리자 미디어 폴더에서 다시 노출

회원 썸네일 경로 필터를 제거해 관리자 미디어의 회원/썸네일 카테고리에서 업로드 결과를 확인할 수 있게 하고, 설정 프로필 썸네일 UI 개편 및 문서 버전 업데이트를 함께 반영한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-11 17:40:32 +09:00
parent 080f76799a
commit b18aca4dcc
7 changed files with 63 additions and 53 deletions

View File

@@ -247,42 +247,54 @@ onMounted(loadProfile)
<section class="rounded-[10px] border border-[var(--site-line)] bg-[var(--site-bg)] p-4">
<h2 class="text-sm font-semibold">프로필</h2>
<div class="mt-3 flex flex-col gap-4">
<div class="settings-profile-avatar-card flex items-center gap-4 rounded-[12px] border border-[var(--site-line)] bg-[var(--site-panel)] p-3">
<div class="settings-profile-avatar-frame relative h-20 w-20 shrink-0 overflow-hidden rounded-full border border-[var(--site-line)] bg-[var(--site-bg)]">
<img
<div class="settings-profile-account flex flex-col gap-3 rounded-[12px] border border-[var(--site-line)] bg-[var(--site-panel)] p-3 md:flex-row md:items-center md:gap-4">
<div class="relative w-fit shrink-0">
<button
type="button"
class="group relative h-24 w-24 overflow-hidden rounded-full border border-[var(--site-line)] bg-[var(--site-bg)]"
:disabled="uploadingAvatar || removingAvatar"
@click="openAvatarFilePicker"
>
<img
v-if="profileForm.avatarUrl"
:src="profileForm.avatarUrl"
alt="프로필 썸네일"
class="h-full w-full object-cover"
>
<span
v-else
class="grid h-full w-full place-items-center text-2xl font-semibold site-muted"
>
{{ (profileForm.username || profileForm.email || '@').slice(0, 1).toUpperCase() }}
</span>
<span class="pointer-events-none absolute inset-0 grid place-items-center bg-black/45 text-[11px] font-medium text-white opacity-0 transition-opacity duration-200 group-hover:opacity-100">
{{ profileForm.avatarUrl ? '이미지 변경' : '썸네일 등록' }}
</span>
</button>
<button
v-if="profileForm.avatarUrl"
:src="profileForm.avatarUrl"
alt="프로필 썸네일"
class="h-full w-full object-cover"
type="button"
class="absolute right-0 top-0 grid h-6 w-6 -translate-y-1/3 translate-x-1/3 place-items-center rounded-full border border-[var(--site-line)] bg-[var(--site-panel-strong)] text-xs site-muted transition-opacity hover:opacity-80 disabled:opacity-50"
:disabled="removingAvatar"
@click.stop="removeAvatar"
>
<span
v-else
class="grid h-full w-full place-items-center text-sm font-semibold site-muted"
>
{{ (profileForm.username || profileForm.email || '@').slice(0, 1).toUpperCase() }}
</span>
{{ removingAvatar ? '...' : 'X' }}
</button>
</div>
<div class="flex flex-col gap-2">
<p class="text-xs site-muted">
프로필 이미지
</p>
<div class="flex flex-wrap items-center gap-2">
<button
type="button"
class="rounded-[10px] border border-[var(--site-line)] px-3 py-1.5 text-xs transition-opacity hover:opacity-80 disabled:opacity-60"
:disabled="uploadingAvatar"
@click="openAvatarFilePicker"
<div class="flex min-w-0 flex-1 flex-col gap-2">
<div class="rounded-[12px] border border-[var(--site-line)] bg-[var(--site-bg)] px-3 py-2.5">
<p class="text-[11px] site-muted">닉네임</p>
<input
v-model="profileForm.username"
type="text"
class="mt-1 h-7 w-full border-none bg-transparent p-0 text-sm font-semibold outline-none focus-visible:ring-0"
>
{{ uploadingAvatar ? '업로드 중...' : '이미지 변경' }}
</button>
<button
type="button"
class="rounded-[10px] border border-[var(--site-line)] px-3 py-1.5 text-xs site-muted transition-opacity hover:opacity-80 disabled:opacity-60"
:disabled="removingAvatar || !profileForm.avatarUrl"
@click="removeAvatar"
>
{{ removingAvatar ? '제거 중...' : '이미지 제거' }}
</button>
</div>
<div class="rounded-[12px] border border-[var(--site-line)] bg-[var(--site-bg)] px-3 py-2.5">
<p class="text-[11px] site-muted">ID (이메일)</p>
<p class="mt-1 truncate text-sm font-semibold">
{{ profileForm.email }}
</p>
</div>
</div>
</div>
@@ -294,22 +306,9 @@ onMounted(loadProfile)
:disabled="uploadingAvatar"
@change="uploadAvatar"
>
<label class="text-xs site-muted">이메일</label>
<input
v-model="profileForm.email"
type="text"
disabled
class="h-10 rounded-[8px] border border-[var(--site-line)] bg-[var(--site-panel)] px-3 text-sm"
>
<label class="text-xs site-muted">닉네임</label>
<input
v-model="profileForm.username"
type="text"
class="h-10 rounded-[8px] border border-[var(--site-line)] bg-transparent px-3 text-sm outline-none focus-visible:border-[var(--site-accent)]"
>
<button
type="button"
class="site-accent-button mt-1 w-fit rounded-[10px] px-3 py-1.5 text-xs font-semibold disabled:opacity-60"
class="site-accent-button w-fit rounded-[10px] px-3 py-1.5 text-xs font-semibold disabled:opacity-60"
:disabled="savingProfile"
@click="saveProfile"
>
@@ -320,7 +319,7 @@ onMounted(loadProfile)
</p>
</div>
</section>
<section class="rounded-[10px] border border-[var(--site-line)] bg-[var(--site-bg)] p-4">
<h2 class="text-sm font-semibold">비밀번호 변경</h2>
<div class="mt-3 flex flex-col gap-3">