diff --git a/components/admin/AdminMemberForm.vue b/components/admin/AdminMemberForm.vue index 082c9bb..85a379e 100644 --- a/components/admin/AdminMemberForm.vue +++ b/components/admin/AdminMemberForm.vue @@ -24,13 +24,22 @@ const passwordModalOpen = ref(false) const deleteModalOpen = ref(false) const isUpdatingPassword = ref(false) const isDeletingMember = ref(false) +const isUpdatingRole = ref(false) const actionMessage = ref('') const actionError = ref('') +const roleOptions = [ + { value: 'owner', label: '소유자' }, + { value: 'admin', label: '관리자' }, + { value: 'vip', label: 'VIP' }, + { value: 'member', label: '멤버' } +] + const form = reactive({ username: '', email: '', avatarUrl: '', + roleCode: 'member', labelsText: '', note: '' }) @@ -53,6 +62,7 @@ const syncMemberForm = () => { form.username = member.username || '' form.email = member.email || '' form.avatarUrl = member.avatarUrl || '' + form.roleCode = member.roleCode || 'member' form.labelsText = Array.isArray(member.labels) ? member.labels.join(', ') : '' form.note = member.note || '' } @@ -77,6 +87,8 @@ const normalizedLabels = computed(() => [...new Set( .filter(Boolean) )]) +const currentRoleLabel = computed(() => roleOptions.find((option) => option.value === form.roleCode)?.label || '멤버') + /** * 회원 저장 요청 본문을 문자열로 직렬화한다. * @returns {string} 직렬화된 회원 입력값 @@ -328,6 +340,40 @@ const updateMemberPassword = async () => { } } +/** + * 관리자 권한으로 회원 등급을 변경한다. + * @returns {Promise} + */ +const updateMemberRole = async () => { + if (isNewMember.value || isUpdatingRole.value) { + return + } + + actionMessage.value = '' + actionError.value = '' + isUpdatingRole.value = true + + try { + const updated = await $fetch(`/admin/api/members/${props.member.id}/role`, { + method: 'PUT', + body: { + role: form.roleCode + } + }) + + emit('saved', { + ...props.member, + ...updated + }) + actionMessage.value = '멤버 등급이 변경되었습니다.' + } catch (error) { + form.roleCode = props.member?.roleCode || 'member' + actionError.value = error?.data?.message || '멤버 등급 변경에 실패했습니다.' + } finally { + isUpdatingRole.value = false + } +} + /** * 관리자 권한으로 회원을 삭제한다. * @returns {Promise} @@ -481,6 +527,7 @@ watch(() => props.member, () => {

{{ pageTitle }}

{{ form.email || '이메일 없음' }}

+

{{ currentRoleLabel }}

@@ -532,6 +579,23 @@ watch(() => props.member, () => { + +