ICH-Detection-Pipeline / static /js /profile-actions.js
Harshit Ghosh
Add full profile management features (avatar, inline edit, delete account)
3754bec
/**
* Profile Actions - Handle inline editing, modals, and avatar upload
*/
// Avatar Upload
document.getElementById('avatarUpload')?.addEventListener('change', async function(e) {
const file = e.target.files[0];
if (!file) return;
const btn = document.querySelector('.avatar-upload-btn');
const originalHtml = btn.innerHTML;
btn.innerHTML = '<span style="width:14px;height:14px;border:2px solid transparent;border-top-color:#fff;border-radius:50%;animation:spin 1s linear infinite;display:inline-block;"></span>';
btn.disabled = true;
const formData = new FormData();
formData.append('avatar', file);
try {
const response = await fetch('/auth/profile/upload-avatar', {
method: 'POST',
body: formData
});
const data = await response.json();
if (response.ok) {
// Reload to show new avatar everywhere
window.location.reload();
} else {
showProfileMessage(data.error || 'Failed to upload avatar', 'error');
btn.innerHTML = originalHtml;
btn.disabled = false;
}
} catch (err) {
showProfileMessage('Network error occurred', 'error');
btn.innerHTML = originalHtml;
btn.disabled = false;
}
});
// Modals
function openEditModal(field, currentValue) {
document.getElementById('editFieldType').value = field;
document.getElementById('editFieldValue').value = currentValue;
let label = 'New Value';
let title = 'Edit Field';
if (field === 'username') { label = 'New Username'; title = 'Change Username'; }
if (field === 'email') { label = 'New Email Address'; title = 'Change Email'; }
if (field === 'full_name') { label = 'New Full Name'; title = 'Update Name'; }
document.getElementById('editFieldLabel').innerText = label;
document.getElementById('editModalTitle').innerText = title;
document.getElementById('editStep1').style.display = 'block';
document.getElementById('editStep2').style.display = 'none';
document.getElementById('editFieldOtpToken').value = '';
document.getElementById('editFieldOtp').value = '';
document.getElementById('editModal').style.display = 'flex';
}
function closeEditModal() {
document.getElementById('editModal').style.display = 'none';
}
function openDeleteModal() {
document.getElementById('deleteModal').style.display = 'flex';
}
function closeDeleteModal() {
document.getElementById('deleteModal').style.display = 'none';
}
// Edit Form Submission
document.getElementById('editFieldForm')?.addEventListener('submit', async function(e) {
e.preventDefault();
const field = document.getElementById('editFieldType').value;
const value = document.getElementById('editFieldValue').value.trim();
const btn = document.getElementById('btnRequestChange');
if (!value) return;
const originalText = btn.innerText;
btn.innerText = 'Saving...';
btn.disabled = true;
let endpoint = '';
let payload = {};
if (field === 'full_name') {
endpoint = '/auth/profile/update-name';
payload = { full_name: value };
} else if (field === 'username') {
endpoint = '/auth/profile/request-username-change';
payload = { new_username: value };
} else if (field === 'email') {
endpoint = '/auth/profile/request-email-change';
payload = { new_email: value };
}
try {
const res = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await res.json();
if (res.ok) {
if (field === 'full_name') {
document.getElementById('val-full_name').innerText = data.full_name;
closeEditModal();
showProfileMessage('Name updated successfully', 'success');
} else {
// Show OTP step
document.getElementById('editStep1').style.display = 'none';
document.getElementById('editStep2').style.display = 'block';
document.getElementById('editFieldOtpToken').value = data.otp_token;
}
} else {
showProfileMessage(data.error || 'Failed to request change', 'error');
}
} catch (err) {
showProfileMessage('Network error occurred', 'error');
} finally {
btn.innerText = originalText;
btn.disabled = false;
}
});
// Confirm OTP (Username/Email)
document.getElementById('btnConfirmChange')?.addEventListener('click', async function() {
const otp = document.getElementById('editFieldOtp').value.trim();
const token = document.getElementById('editFieldOtpToken').value;
const field = document.getElementById('editFieldType').value;
const btn = this;
if (otp.length !== 6) return;
const originalText = btn.innerText;
btn.innerText = 'Verifying...';
btn.disabled = true;
const purpose = field === 'username' ? 'change_username' : 'change_email';
try {
const res = await fetch('/auth/profile/confirm-change', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ otp: otp, otp_token: token, purpose: purpose })
});
const data = await res.json();
if (res.ok) {
// Reload to reflect changes
window.location.reload();
} else {
showProfileMessage(data.error || 'Failed to verify OTP', 'error');
}
} catch (err) {
showProfileMessage('Network error occurred', 'error');
} finally {
btn.innerText = originalText;
btn.disabled = false;
}
});
function showProfileMessage(msg, type) {
const container = document.getElementById('profileMessage');
if (!container) return;
container.innerHTML = `<div class="alert alert-${type}">${msg}</div>`;
setTimeout(() => { container.innerHTML = ''; }, 5000);
}