197 lines
7.0 KiB
Vue
197 lines
7.0 KiB
Vue
<script setup>
|
|
const logoInputRef = ref(null)
|
|
|
|
/**
|
|
* 사이트 정보 설정 카드
|
|
* @property {Object} form - 사이트 설정 폼 객체
|
|
* @property {boolean} editing - 편집 모드 여부
|
|
* @property {boolean} saving - 저장 중 여부
|
|
* @property {boolean} uploadingLogo - 로고 업로드 중 여부
|
|
* @property {boolean} hasChanges - 변경 여부
|
|
*/
|
|
defineProps({
|
|
form: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
editing: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
saving: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
uploadingLogo: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
hasChanges: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
})
|
|
|
|
defineEmits(['begin', 'cancel', 'save', 'upload-logo'])
|
|
|
|
/**
|
|
* 로고 파일 선택창을 연다.
|
|
* @returns {void}
|
|
*/
|
|
const openLogoFilePicker = () => {
|
|
logoInputRef.value?.click()
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<section
|
|
id="admin-settings-section-misc"
|
|
class="admin-site-info-settings-card admin-settings-screen__card rounded-xl border border-[#e6e8eb] bg-white p-6 shadow-[0_1px_2px_rgba(15,23,42,0.04)]"
|
|
>
|
|
<div class="flex items-start justify-between gap-4">
|
|
<div class="min-w-0 flex-1">
|
|
<h2 class="text-base font-semibold text-[#15171a] md:text-lg">
|
|
사이트 정보
|
|
</h2>
|
|
<p
|
|
v-if="!editing"
|
|
class="mr-5 mt-1 text-pretty text-sm leading-relaxed text-[#657080]"
|
|
>
|
|
로고, 공개 URL, 푸터 저작권 문구를 관리합니다.
|
|
</p>
|
|
</div>
|
|
<div class="-mr-1 mt-[-5px] flex shrink-0 items-center justify-start gap-2">
|
|
<template v-if="!editing">
|
|
<button
|
|
class="inline-flex h-7 cursor-pointer items-center justify-center rounded px-3 text-sm font-semibold whitespace-nowrap text-[#15171a] transition hover:bg-[#eceff2] hover:text-black"
|
|
type="button"
|
|
@click="$emit('begin')"
|
|
>
|
|
편집
|
|
</button>
|
|
</template>
|
|
<template v-else>
|
|
<button
|
|
class="inline-flex h-7 cursor-pointer items-center justify-center rounded px-3 text-sm font-semibold whitespace-nowrap text-[#5d6673] transition hover:bg-[#eceff2] hover:text-[#15171a]"
|
|
type="button"
|
|
:disabled="saving"
|
|
@click="$emit('cancel')"
|
|
>
|
|
취소
|
|
</button>
|
|
<button
|
|
class="inline-flex h-7 cursor-pointer items-center justify-center rounded px-3 text-sm font-semibold whitespace-nowrap text-[#15171a] transition hover:bg-[#eceff2] hover:text-black disabled:opacity-50"
|
|
type="button"
|
|
:disabled="saving || !hasChanges"
|
|
@click="$emit('save')"
|
|
>
|
|
{{ saving ? '저장 중' : '저장' }}
|
|
</button>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
v-if="!editing"
|
|
class="admin-site-info-settings-card__readonly admin-settings-screen__misc-readonly grid gap-5 pt-5"
|
|
>
|
|
<div class="flex flex-col gap-5 md:flex-row md:items-start">
|
|
<div
|
|
class="admin-settings-screen__logo-preview grid h-16 w-16 shrink-0 place-items-center overflow-hidden rounded-2xl bg-[#f7f8fa]"
|
|
:class="form.logoUrl ? 'border border-[#e6e8eb]' : 'border border-dashed border-[#cfd6df]'"
|
|
>
|
|
<img
|
|
v-if="form.logoUrl"
|
|
class="h-full w-full object-cover"
|
|
:src="form.logoUrl"
|
|
alt="사이트 로고"
|
|
>
|
|
<span v-else class="text-sm font-semibold text-[#8b95a1]">
|
|
미등록
|
|
</span>
|
|
</div>
|
|
<div class="admin-settings-screen__readonly-list grid min-w-0 flex-1 gap-4 text-sm">
|
|
<div class="admin-settings-screen__readonly-row grid gap-1 md:grid-cols-[7.5rem_minmax(0,1fr)] md:items-center md:gap-5">
|
|
<h3 class="text-sm font-normal text-[#3f4650]">
|
|
사이트 URL
|
|
</h3>
|
|
<p class="min-w-0 break-all text-sm font-normal leading-relaxed text-[#15171a]">
|
|
{{ form.siteUrl || '—' }}
|
|
</p>
|
|
</div>
|
|
<div class="admin-settings-screen__readonly-row grid gap-1 md:grid-cols-[7.5rem_minmax(0,1fr)] md:items-center md:gap-5">
|
|
<h3 class="text-sm font-normal text-[#3f4650]">
|
|
저작권 문구
|
|
</h3>
|
|
<p class="min-w-0 whitespace-pre-wrap text-sm font-normal leading-relaxed text-[#15171a]">
|
|
{{ form.copyrightText || '—' }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else class="admin-site-info-settings-card__edit admin-settings-screen__card-body grid gap-6">
|
|
<div class="flex flex-col gap-5 md:flex-row md:items-center md:justify-between">
|
|
<div class="flex items-center gap-4">
|
|
<div class="grid h-20 w-20 shrink-0 place-items-center overflow-hidden rounded-2xl border border-[#e6e8eb] bg-[#f7f8fa]">
|
|
<img
|
|
v-if="form.logoUrl"
|
|
class="h-full w-full object-cover"
|
|
:src="form.logoUrl"
|
|
alt="사이트 로고"
|
|
>
|
|
<span v-else class="text-2xl font-semibold text-[#9aa3ad]">
|
|
{{ form.logoText || '井' }}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-base font-semibold text-[#15171a]">
|
|
로고
|
|
</h3>
|
|
<p class="mt-1 max-w-md text-sm leading-relaxed text-[#657080]">
|
|
1:1 비율 이미지로 등록합니다. 같은 이미지가 공개 로고와 파비콘으로 함께 사용됩니다.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<button
|
|
class="h-10 shrink-0 rounded-md border border-[#dce0e5] bg-white px-4 text-sm font-semibold text-[#15171a] transition-colors hover:bg-[#f3f5f7] disabled:opacity-50"
|
|
type="button"
|
|
:disabled="uploadingLogo"
|
|
@click="openLogoFilePicker"
|
|
>
|
|
{{ uploadingLogo ? '업로드 중' : form.logoUrl ? '로고 변경' : '로고 등록' }}
|
|
</button>
|
|
<input
|
|
ref="logoInputRef"
|
|
class="hidden"
|
|
type="file"
|
|
accept="image/jpeg,image/png,image/webp"
|
|
:disabled="uploadingLogo"
|
|
@change="$emit('upload-logo', $event)"
|
|
>
|
|
</div>
|
|
|
|
<label class="admin-settings-screen__field grid gap-2 text-sm">
|
|
<span class="font-medium text-[#3f4650]">사이트 URL</span>
|
|
<input
|
|
v-model="form.siteUrl"
|
|
class="rounded-md border border-[#dce0e5] bg-white px-3 py-2 text-[#15171a] outline-none focus:border-[#15171a] focus:ring-1 focus:ring-[#15171a]"
|
|
type="url"
|
|
required
|
|
>
|
|
</label>
|
|
|
|
<label class="admin-settings-screen__field grid gap-2 text-sm">
|
|
<span class="font-medium text-[#3f4650]">저작권 문구</span>
|
|
<input
|
|
v-model="form.copyrightText"
|
|
class="rounded-md border border-[#dce0e5] bg-white px-3 py-2 text-[#15171a] outline-none focus:border-[#15171a] focus:ring-1 focus:ring-[#15171a]"
|
|
type="text"
|
|
required
|
|
>
|
|
</label>
|
|
</div>
|
|
</section>
|
|
</template>
|