162 lines
4.8 KiB
JavaScript
162 lines
4.8 KiB
JavaScript
// public/assets/account.js
|
|
/* English comments: account profile + preferences */
|
|
|
|
(function () {
|
|
const state = {
|
|
profile: null,
|
|
ui: null,
|
|
};
|
|
let avatarUrl = null;
|
|
|
|
function qs(id) {
|
|
return window.UI?.qs ? window.UI.qs(id) : document.getElementById(id);
|
|
}
|
|
|
|
function setStatus(text) {
|
|
const hint = qs('accountPasswordHint');
|
|
if (hint) hint.textContent = text || '';
|
|
}
|
|
|
|
function setAvatarBlob(blob) {
|
|
const avatar = qs('accountAvatar');
|
|
if (!avatar || !blob) return;
|
|
if (avatarUrl) {
|
|
URL.revokeObjectURL(avatarUrl);
|
|
}
|
|
avatarUrl = URL.createObjectURL(blob);
|
|
avatar.src = avatarUrl;
|
|
}
|
|
|
|
async function fetchAvatar() {
|
|
const token = window.Auth?.getAccessToken?.();
|
|
if (!token) return;
|
|
const res = await fetch('/api/account/avatar', {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
});
|
|
if (!res.ok) return;
|
|
const blob = await res.blob();
|
|
setAvatarBlob(blob);
|
|
}
|
|
|
|
function applyProfile(profile) {
|
|
state.profile = profile || {};
|
|
if (qs('accountNickname')) qs('accountNickname').value = state.profile.nickname || '';
|
|
if (qs('accountEmail')) qs('accountEmail').value = state.profile.email || '';
|
|
if (state.profile.avatar_present) {
|
|
fetchAvatar().catch(() => {});
|
|
}
|
|
}
|
|
|
|
function applyUi(ui) {
|
|
state.ui = ui || {};
|
|
if (qs('accountLanguage')) qs('accountLanguage').value = state.ui.language || 'en';
|
|
if (qs('accountTheme')) qs('accountTheme').value = state.ui.theme || 'dark';
|
|
if (qs('accountTableMode')) qs('accountTableMode').value = state.ui.table_mode || 'pagination';
|
|
if (qs('accountTableSize')) qs('accountTableSize').value = String(state.ui.table_page_size || 50);
|
|
}
|
|
|
|
async function loadAccount() {
|
|
const res = await window.Api.request('/api/account', { method: 'GET' });
|
|
const data = res?.data || res || {};
|
|
applyProfile(data.profile || {});
|
|
applyUi(data.ui || {});
|
|
if (window.UserPrefs?.load) {
|
|
await window.UserPrefs.load();
|
|
}
|
|
}
|
|
|
|
async function saveProfile() {
|
|
const nickname = (qs('accountNickname')?.value || '').trim();
|
|
const email = (qs('accountEmail')?.value || '').trim();
|
|
const ui = {
|
|
language: qs('accountLanguage')?.value || 'en',
|
|
theme: qs('accountTheme')?.value || 'dark',
|
|
table_mode: qs('accountTableMode')?.value || 'pagination',
|
|
table_page_size: Number(qs('accountTableSize')?.value || 50),
|
|
};
|
|
await window.Api.request('/api/account', {
|
|
method: 'POST',
|
|
body: { nickname, ui },
|
|
});
|
|
if (window.UserPrefs?.setUi) {
|
|
Object.keys(ui).forEach((key) => window.UserPrefs.setUi(key, ui[key]));
|
|
}
|
|
if (email && email !== state.profile?.email) {
|
|
await window.Api.request('/api/account/email', {
|
|
method: 'POST',
|
|
body: { email },
|
|
});
|
|
}
|
|
if (ui.theme && window.UI?.setTheme) {
|
|
window.UI.setTheme(ui.theme);
|
|
}
|
|
if (ui.language && ui.language !== (window.APP_LANG || 'en')) {
|
|
localStorage.setItem('scmedia_lang', ui.language);
|
|
}
|
|
}
|
|
|
|
async function uploadAvatar() {
|
|
const file = qs('avatarFile')?.files?.[0];
|
|
if (!file) return;
|
|
if (file.size > 5 * 1024 * 1024) {
|
|
alert('File too large (max 5MB)');
|
|
return;
|
|
}
|
|
const form = new FormData();
|
|
form.append('avatar', file);
|
|
await window.Api.request('/api/account/avatar', {
|
|
method: 'POST',
|
|
body: form,
|
|
headers: {},
|
|
});
|
|
await fetchAvatar();
|
|
}
|
|
|
|
async function changePassword() {
|
|
const current = qs('accountPasswordCurrent')?.value || '';
|
|
const next = qs('accountPasswordNew')?.value || '';
|
|
const confirm = qs('accountPasswordConfirm')?.value || '';
|
|
if (!current || !next) {
|
|
setStatus('Missing password');
|
|
return;
|
|
}
|
|
if (next !== confirm) {
|
|
setStatus('Passwords do not match');
|
|
return;
|
|
}
|
|
setStatus('Saving…');
|
|
await window.Api.request('/api/account/password', {
|
|
method: 'POST',
|
|
body: { current, next },
|
|
});
|
|
setStatus('Saved');
|
|
qs('accountPasswordCurrent').value = '';
|
|
qs('accountPasswordNew').value = '';
|
|
qs('accountPasswordConfirm').value = '';
|
|
if (window.Auth?.logout) {
|
|
window.Auth.logout();
|
|
return;
|
|
}
|
|
if (window.Auth?.clearTokens) {
|
|
window.Auth.clearTokens();
|
|
}
|
|
window.location.href = '/login';
|
|
}
|
|
|
|
function init() {
|
|
if (window.Auth?.requireAuth) {
|
|
window.Auth.requireAuth();
|
|
}
|
|
window.UI?.initHeader?.();
|
|
window.UI?.initThemeToggle?.();
|
|
window.UI?.bindThemePreference?.();
|
|
loadAccount().catch(() => {});
|
|
|
|
qs('btnAccountSave')?.addEventListener('click', () => saveProfile().catch((e) => alert(e.message)));
|
|
qs('btnAvatarUpload')?.addEventListener('click', () => uploadAvatar().catch((e) => alert(e.message)));
|
|
qs('btnPasswordChange')?.addEventListener('click', () => changePassword().catch((e) => setStatus(e.message)));
|
|
}
|
|
|
|
init();
|
|
})();
|