- user-modal.js: 삭제/복원/비밀번호 초기화 알림 개선 - context-menu.js: 테넌트 전환/사용자 삭제 알림 개선 - 시스템 일관성을 위해 SweetAlert2 토스트 사용
227 lines
7.8 KiB
JavaScript
227 lines
7.8 KiB
JavaScript
/**
|
|
* 사용자 정보 모달
|
|
* 사용자 상세 정보를 팝업으로 표시
|
|
*/
|
|
|
|
const UserModal = {
|
|
modalElement: null,
|
|
currentUserId: null,
|
|
|
|
init() {
|
|
this.modalElement = document.getElementById('user-modal');
|
|
if (!this.modalElement) return;
|
|
|
|
// ESC 키로 모달 닫기
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && this.isOpen()) {
|
|
this.close();
|
|
}
|
|
});
|
|
|
|
// 배경 클릭 시 모달 닫기
|
|
this.modalElement.addEventListener('click', (e) => {
|
|
if (e.target === this.modalElement) {
|
|
this.close();
|
|
}
|
|
});
|
|
},
|
|
|
|
isOpen() {
|
|
return this.modalElement && !this.modalElement.classList.contains('hidden');
|
|
},
|
|
|
|
async open(userId) {
|
|
if (!this.modalElement) {
|
|
console.error('User modal element not found');
|
|
return;
|
|
}
|
|
|
|
this.currentUserId = userId;
|
|
|
|
// 모달 표시
|
|
this.modalElement.classList.remove('hidden');
|
|
document.body.style.overflow = 'hidden';
|
|
|
|
// 로딩 표시
|
|
this.showLoading();
|
|
|
|
// 사용자 정보 로드
|
|
await this.loadUserInfo();
|
|
},
|
|
|
|
close() {
|
|
if (this.modalElement) {
|
|
this.modalElement.classList.add('hidden');
|
|
document.body.style.overflow = '';
|
|
}
|
|
this.currentUserId = null;
|
|
},
|
|
|
|
showLoading() {
|
|
const content = document.getElementById('user-modal-content');
|
|
if (content) {
|
|
content.innerHTML = `
|
|
<div class="flex items-center justify-center h-64">
|
|
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
|
|
</div>
|
|
`;
|
|
}
|
|
},
|
|
|
|
async loadUserInfo() {
|
|
try {
|
|
const response = await fetch(`/api/admin/users/${this.currentUserId}/modal`, {
|
|
headers: {
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.html) {
|
|
const content = document.getElementById('user-modal-content');
|
|
if (content) {
|
|
content.innerHTML = data.html;
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load user info:', error);
|
|
this.showError('사용자 정보를 불러오는데 실패했습니다.');
|
|
}
|
|
},
|
|
|
|
showError(message) {
|
|
const content = document.getElementById('user-modal-content');
|
|
if (content) {
|
|
content.innerHTML = `
|
|
<div class="flex flex-col items-center justify-center h-64 text-red-500">
|
|
<svg class="w-12 h-12 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
</svg>
|
|
<p>${message}</p>
|
|
<button onclick="UserModal.close()" class="mt-4 px-4 py-2 bg-gray-200 rounded hover:bg-gray-300">
|
|
닫기
|
|
</button>
|
|
</div>
|
|
`;
|
|
}
|
|
},
|
|
|
|
// 수정 페이지로 이동
|
|
goToEdit() {
|
|
if (this.currentUserId) {
|
|
window.location.href = `/users/${this.currentUserId}/edit`;
|
|
}
|
|
},
|
|
|
|
// 삭제 실행
|
|
async deleteUser() {
|
|
if (!this.currentUserId) return;
|
|
|
|
const userName = document.getElementById('user-modal-name')?.textContent || '이 사용자';
|
|
|
|
if (confirm(`"${userName}"을(를) 삭제하시겠습니까?`)) {
|
|
try {
|
|
const response = await fetch(`/api/admin/users/${this.currentUserId}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
this.close();
|
|
showToast(data.message || '사용자가 삭제되었습니다.', 'success');
|
|
// 테이블 새로고침
|
|
if (typeof htmx !== 'undefined') {
|
|
htmx.trigger('#user-table', 'filterSubmit');
|
|
}
|
|
} else {
|
|
showToast(data.message || '삭제에 실패했습니다.', 'error');
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to delete user:', error);
|
|
showToast('삭제에 실패했습니다.', 'error');
|
|
}
|
|
}
|
|
},
|
|
|
|
// 복원 실행
|
|
async restoreUser() {
|
|
if (!this.currentUserId) return;
|
|
|
|
const userName = document.getElementById('user-modal-name')?.textContent || '이 사용자';
|
|
|
|
if (confirm(`"${userName}"을(를) 복원하시겠습니까?`)) {
|
|
try {
|
|
const response = await fetch(`/api/admin/users/${this.currentUserId}/restore`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
showToast(data.message || '사용자가 복원되었습니다.', 'success');
|
|
// 모달 내용 새로고침
|
|
await this.loadUserInfo();
|
|
// 테이블 새로고침
|
|
if (typeof htmx !== 'undefined') {
|
|
htmx.trigger('#user-table', 'filterSubmit');
|
|
}
|
|
} else {
|
|
showToast(data.message || '복원에 실패했습니다.', 'error');
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to restore user:', error);
|
|
showToast('복원에 실패했습니다.', 'error');
|
|
}
|
|
}
|
|
},
|
|
|
|
// 비밀번호 초기화 실행
|
|
async resetPassword() {
|
|
if (!this.currentUserId) return;
|
|
|
|
const userName = document.getElementById('user-modal-name')?.textContent || '이 사용자';
|
|
|
|
if (!confirm(`"${userName}"의 비밀번호를 초기화하시겠습니까?\n\n임시 비밀번호가 생성되어 사용자 이메일로 발송됩니다.`)) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(`/api/admin/users/${this.currentUserId}/reset-password`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json'
|
|
}
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
showToast(data.message || '비밀번호가 초기화되었습니다.', 'success');
|
|
} else {
|
|
showToast(data.message || '비밀번호 초기화에 실패했습니다.', 'error');
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to reset password:', error);
|
|
showToast('비밀번호 초기화에 실패했습니다.', 'error');
|
|
}
|
|
}
|
|
};
|
|
|
|
// DOM 로드 시 초기화
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
UserModal.init();
|
|
});
|