import { computed } from 'vue' export function useAdminUsers({ api, auth, users, userQuery, userSort, userSortDirection, userAvatarInputs, modalTargetUser, modalPasswordDraft, modalRoleNextAdmin, modalUserDraftEmail, modalUserDraftNickname, modalUserDraftIsAdmin, userEditModalOpen, userPasswordModalOpen, userDeleteModalOpen, userRoleModalOpen, resetMessages, refreshUsers, success, error, }) { function setUserAvatarInput(userId, el) { if (!userId) return if (!el) { delete userAvatarInputs.value[userId] return } userAvatarInputs.value[userId] = el } const canManageModalRole = computed(() => { if (!auth.user?.isPrimaryAdmin) return false if (!modalTargetUser.value) return false return !modalTargetUser.value.isPrimaryAdmin }) const isUserEditDirty = computed(() => { if (!modalTargetUser.value) return false return ( modalUserDraftEmail.value.trim() !== (modalTargetUser.value.email || '') || modalUserDraftNickname.value.trim() !== (modalTargetUser.value.nickname || '') || !!modalUserDraftIsAdmin.value !== !!modalTargetUser.value.isAdmin ) }) function roleLabelOf(user) { if (user?.isPrimaryAdmin) return '최고 관리자' if (user?.isAdmin) return '운영자' return '일반 회원' } function openUserAvatarPicker(user) { userAvatarInputs.value[user?.id]?.click() } async function uploadUserAvatar(user, file, { remove = false } = {}) { resetMessages() if (!user?.id) return try { user.isAvatarBusy = true const data = await api.updateAdminUserAvatar(user.id, { file, removeAvatar: remove }) const updated = data.user users.value = users.value.map((entry) => entry.id === updated.id ? { ...entry, ...updated, isAvatarBusy: false, } : entry ) if (modalTargetUser.value?.id === updated.id) { modalTargetUser.value = { ...modalTargetUser.value, ...updated } } if (updated.id === auth.user?.id) await auth.refresh() await refreshUsers() success.value = remove ? '회원 썸네일을 삭제했어요.' : '회원 썸네일을 업데이트했어요.' } catch (e) { error.value = remove ? '회원 썸네일 삭제에 실패했어요.' : '회원 썸네일 변경에 실패했어요.' } finally { const target = users.value.find((entry) => entry.id === user.id) if (target) target.isAvatarBusy = false } } async function onUserAvatarChange(user, event) { const file = event.target.files && event.target.files[0] ? event.target.files[0] : null event.target.value = '' if (!file) return await uploadUserAvatar(user, file) } async function removeUserAvatar(user) { if (!user?.avatarSrc) return await uploadUserAvatar(user, null, { remove: true }) } function openUserEditModal(user) { resetMessages() modalTargetUser.value = user ? { ...user } : null modalUserDraftEmail.value = user?.email || '' modalUserDraftNickname.value = user?.nickname || '' modalUserDraftIsAdmin.value = !!user?.isAdmin userEditModalOpen.value = true } function closeUserEditModal() { userEditModalOpen.value = false modalTargetUser.value = null modalUserDraftEmail.value = '' modalUserDraftNickname.value = '' modalUserDraftIsAdmin.value = false } async function saveUserEdit() { resetMessages() if (!modalTargetUser.value?.id) return try { const data = await api.updateAdminUser(modalTargetUser.value.id, { email: modalUserDraftEmail.value.trim(), nickname: modalUserDraftNickname.value.trim(), isAdmin: !!modalUserDraftIsAdmin.value, }) const updated = data.user users.value = users.value.map((entry) => entry.id === updated.id ? { ...entry, ...updated, isAvatarBusy: entry.isAvatarBusy || false, } : entry ) if (updated.id === auth.user?.id) await auth.refresh() closeUserEditModal() await refreshUsers() success.value = '회원 정보를 저장했어요.' } catch (e) { error.value = '회원 정보 저장에 실패했어요.' } } function openUserPasswordModal(user) { resetMessages() modalTargetUser.value = user ? { ...user } : null modalPasswordDraft.value = '' userPasswordModalOpen.value = true } function closeUserPasswordModal() { userPasswordModalOpen.value = false modalTargetUser.value = null modalPasswordDraft.value = '' } function userDisplayName(user) { return user?.nickname || user?.email?.split('@')[0] || '알 수 없음' } async function confirmUserPasswordReset() { resetMessages() if (!modalTargetUser.value?.id) return const password = modalPasswordDraft.value.trim() if (!password) { error.value = '초기화할 비밀번호를 입력해주세요.' return } try { await api.updateAdminUserPassword(modalTargetUser.value.id, { password }) success.value = `${userDisplayName(modalTargetUser.value)} 계정 비밀번호를 초기화했어요.` closeUserPasswordModal() } catch (e) { error.value = '비밀번호 초기화에 실패했어요.' } } function openUserDeleteModal(user) { resetMessages() modalTargetUser.value = user ? { ...user } : null userDeleteModalOpen.value = true } function closeUserDeleteModal() { userDeleteModalOpen.value = false modalTargetUser.value = null } async function confirmUserDelete() { resetMessages() if (!modalTargetUser.value?.id) return try { const deletingSelf = modalTargetUser.value.id === auth.user?.id const deletedName = userDisplayName(modalTargetUser.value) await api.deleteAdminUser(modalTargetUser.value.id) users.value = users.value.filter((entry) => entry.id !== modalTargetUser.value.id) closeUserDeleteModal() success.value = `${deletedName} 계정을 삭제했어요.` if (deletingSelf) await auth.refresh() } catch (e) { error.value = '회원 삭제에 실패했어요.' } } function openUserRoleModal(user, nextIsAdmin = !modalUserDraftIsAdmin.value) { resetMessages() modalTargetUser.value = user ? { ...user } : null modalRoleNextAdmin.value = !!nextIsAdmin userRoleModalOpen.value = true } function closeUserRoleModal() { userRoleModalOpen.value = false if (!userEditModalOpen.value) modalTargetUser.value = null modalRoleNextAdmin.value = false } function confirmUserRoleDraft() { if (!modalTargetUser.value?.id) return modalUserDraftIsAdmin.value = modalRoleNextAdmin.value const targetLabel = modalRoleNextAdmin.value ? '운영자 권한을 저장 대기 상태로 반영했어요.' : '운영자 권한 해제를 저장 대기 상태로 반영했어요.' closeUserRoleModal() success.value = targetLabel } function submitUserFilters() { refreshUsers({ q: userQuery.value, sort: userSort.value, direction: userSortDirection.value, }) } return { setUserAvatarInput, canManageModalRole, isUserEditDirty, roleLabelOf, openUserAvatarPicker, onUserAvatarChange, removeUserAvatar, openUserEditModal, closeUserEditModal, saveUserEdit, openUserPasswordModal, closeUserPasswordModal, confirmUserPasswordReset, openUserDeleteModal, closeUserDeleteModal, confirmUserDelete, openUserRoleModal, closeUserRoleModal, confirmUserRoleDraft, submitUserFilters, userDisplayName, } }