v0.1.18 - 설정 화면과 기간형 D-DAY 관리 추가
This commit is contained in:
171
src/components/SettingsDashboard.vue
Normal file
171
src/components/SettingsDashboard.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
profileForm: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
passwordForm: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
profileBusy: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
passwordBusy: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
profileMessage: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
passwordMessage: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:profile-field',
|
||||
'update:password-field',
|
||||
'submit:profile',
|
||||
'submit:password',
|
||||
])
|
||||
|
||||
const initials = computed(() =>
|
||||
`${props.user.nickname?.slice(0, 1) ?? ''}${props.user.email?.slice(0, 1) ?? ''}`.toUpperCase(),
|
||||
)
|
||||
|
||||
function updateProfileField(field, event) {
|
||||
emit('update:profile-field', {
|
||||
field,
|
||||
value: event.target.value,
|
||||
})
|
||||
}
|
||||
|
||||
function updatePasswordField(field, event) {
|
||||
emit('update:password-field', {
|
||||
field,
|
||||
value: event.target.value,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="grid gap-6 xl:grid-cols-[360px_minmax(0,1fr)]">
|
||||
<aside class="rounded-[28px] border border-white/60 bg-white/70 p-6">
|
||||
<p class="text-[11px] font-bold uppercase tracking-[0.28em] text-stone-500">Settings</p>
|
||||
<div class="mt-6 flex items-center gap-4">
|
||||
<div class="flex h-20 w-20 items-center justify-center rounded-full bg-stone-900 text-2xl font-bold tracking-[0.04em] text-white">
|
||||
{{ initials || 'U' }}
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xl font-semibold tracking-[-0.04em] text-stone-900">{{ user.nickname }}</p>
|
||||
<p class="mt-1 text-sm font-semibold text-stone-500">{{ user.email }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6 space-y-3 rounded-[24px] border border-stone-200 bg-[#fbf7f0] p-4">
|
||||
<p class="text-[10px] font-bold tracking-[0.18em] text-stone-500">PROFILE NOTE</p>
|
||||
<p class="text-sm font-semibold leading-6 text-stone-700">
|
||||
썸네일 이미지는 다음 단계에서 붙이는 편이 자연스럽습니다. 이번 단계에서는 계정 정보 수정과 비밀번호 변경 흐름을 먼저 안정화합니다.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="grid gap-6">
|
||||
<form class="rounded-[28px] border border-white/60 bg-white/75 p-6" @submit.prevent="emit('submit:profile')">
|
||||
<p class="text-[11px] font-bold uppercase tracking-[0.24em] text-stone-500">Account Profile</p>
|
||||
<div class="mt-5 grid gap-4 md:grid-cols-2">
|
||||
<div class="space-y-2">
|
||||
<label class="text-[11px] font-bold tracking-[0.16em] text-stone-600">닉네임</label>
|
||||
<input
|
||||
:value="profileForm.nickname"
|
||||
type="text"
|
||||
class="w-full rounded-2xl border border-stone-300 bg-white px-4 py-3 text-sm font-semibold text-stone-800 outline-none transition focus:border-stone-500"
|
||||
@input="updateProfileField('nickname', $event)"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-[11px] font-bold tracking-[0.16em] text-stone-600">이메일</label>
|
||||
<input
|
||||
:value="profileForm.email"
|
||||
type="email"
|
||||
class="w-full rounded-2xl border border-stone-300 bg-white px-4 py-3 text-sm font-semibold text-stone-800 outline-none transition focus:border-stone-500"
|
||||
@input="updateProfileField('email', $event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p
|
||||
v-if="profileMessage"
|
||||
class="mt-4 rounded-2xl border border-stone-300 bg-white/80 px-4 py-3 text-sm font-semibold leading-6 text-stone-700"
|
||||
>
|
||||
{{ profileMessage }}
|
||||
</p>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="mt-5 rounded-full bg-stone-900 px-5 py-3 text-xs font-bold tracking-[0.18em] text-white transition hover:bg-stone-700 disabled:cursor-not-allowed disabled:bg-stone-400"
|
||||
:disabled="profileBusy"
|
||||
>
|
||||
{{ profileBusy ? '저장 중...' : '프로필 저장' }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<form class="rounded-[28px] border border-white/60 bg-white/75 p-6" @submit.prevent="emit('submit:password')">
|
||||
<p class="text-[11px] font-bold uppercase tracking-[0.24em] text-stone-500">Password</p>
|
||||
<div class="mt-5 grid gap-4 md:grid-cols-2">
|
||||
<div class="space-y-2 md:col-span-2">
|
||||
<label class="text-[11px] font-bold tracking-[0.16em] text-stone-600">현재 비밀번호</label>
|
||||
<input
|
||||
:value="passwordForm.currentPassword"
|
||||
type="password"
|
||||
class="w-full rounded-2xl border border-stone-300 bg-white px-4 py-3 text-sm font-semibold text-stone-800 outline-none transition focus:border-stone-500"
|
||||
@input="updatePasswordField('currentPassword', $event)"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-[11px] font-bold tracking-[0.16em] text-stone-600">새 비밀번호</label>
|
||||
<input
|
||||
:value="passwordForm.newPassword"
|
||||
type="password"
|
||||
class="w-full rounded-2xl border border-stone-300 bg-white px-4 py-3 text-sm font-semibold text-stone-800 outline-none transition focus:border-stone-500"
|
||||
@input="updatePasswordField('newPassword', $event)"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-[11px] font-bold tracking-[0.16em] text-stone-600">새 비밀번호 확인</label>
|
||||
<input
|
||||
:value="passwordForm.confirmPassword"
|
||||
type="password"
|
||||
class="w-full rounded-2xl border border-stone-300 bg-white px-4 py-3 text-sm font-semibold text-stone-800 outline-none transition focus:border-stone-500"
|
||||
@input="updatePasswordField('confirmPassword', $event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p
|
||||
v-if="passwordMessage"
|
||||
class="mt-4 rounded-2xl border border-stone-300 bg-white/80 px-4 py-3 text-sm font-semibold leading-6 text-stone-700"
|
||||
>
|
||||
{{ passwordMessage }}
|
||||
</p>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="mt-5 rounded-full border border-stone-900 px-5 py-3 text-xs font-bold tracking-[0.18em] text-stone-900 transition hover:bg-stone-900 hover:text-white disabled:cursor-not-allowed disabled:border-stone-300 disabled:text-stone-400"
|
||||
:disabled="passwordBusy"
|
||||
>
|
||||
{{ passwordBusy ? '변경 중...' : '비밀번호 변경' }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user