dudi/public/js/auth.js

128 lines
5.6 KiB
JavaScript
Raw Normal View History

2026-05-08 09:42:08 +00:00
import { api, loadGoals } from './api.js';
import { tr } from './i18n.js';
import { state } from './state.js';
import { tpl, showSheet, closeOv, showToast, updateHeader } from './ui.js';
import { render } from './render.js';
export function showLogin(err) {
const c = tpl('tpl-login');
if (err) { const e = c.querySelector('.login-err'); e.textContent = err; e.style.display = ''; }
showSheet(c, false);
const email = c.querySelector('.lf-email'), pass = c.querySelector('.lf-pass'), sub = c.querySelector('.lf-sub');
setTimeout(() => email.focus(), 50);
email.onkeydown = e => { if (e.key === 'Enter') pass.focus(); };
pass.onkeydown = e => { if (e.key === 'Enter') sub.click(); };
c.querySelector('.lf-fgt').onclick = () => showForgotPassword();
sub.onclick = () => {
const ev = email.value.trim(), pv = pass.value;
if (!ev || !pv) {
const errEl = c.querySelector('.login-err');
errEl.textContent = tr('loginErrEmpty'); errEl.style.display = '';
return;
}
sub.disabled = true; sub.textContent = '…';
api('POST', 'login', { email: ev, password: pv })
.then(() => loadGoals())
.then(g => { state.goals = g; closeOv(); render(); })
.catch(err => {
sub.disabled = false; sub.textContent = tr('loginBtn');
showLogin(err.status === 401 ? tr('loginErrWrong') : err.status === 429 ? tr('loginErrRate') : tr('loginErrConn'));
});
};
}
export function showForgotPassword() {
const c = tpl('tpl-forgot-pw');
showSheet(c, false);
const email = c.querySelector('.fp-email'), errEl = c.querySelector('.login-err'), sub = c.querySelector('.fp-sub');
setTimeout(() => email.focus(), 50);
c.querySelector('.fp-back').onclick = () => showLogin();
sub.onclick = () => {
const ev = email.value.trim(); if (!ev) return;
sub.disabled = true; sub.textContent = '…';
api('POST', 'reset-request', { email: ev })
.then(() => {
const conf = tpl('tpl-email-sent');
conf.querySelector('.es-ok').onclick = () => showLogin();
showSheet(conf, false);
})
.catch(err => {
sub.disabled = false; sub.textContent = tr('sendLink');
errEl.textContent = err.message || 'Fehler'; errEl.style.display = '';
});
};
}
export function showResetPassword(selector, token) {
const c = tpl('tpl-reset-pw');
showSheet(c, false);
const pass = c.querySelector('.rp-pass'), errEl = c.querySelector('.login-err'), sub = c.querySelector('.rp-sub');
setTimeout(() => pass.focus(), 50);
sub.onclick = () => {
const pv = pass.value; if (!pv) return;
sub.disabled = true; sub.textContent = '…';
api('POST', 'reset-password', { selector, token, password: pv })
.then(() => {
const conf = tpl('tpl-pw-changed');
conf.querySelector('.pc-ok').onclick = () => showLogin();
showSheet(conf, false);
})
.catch(err => {
sub.disabled = false; sub.textContent = tr('setPw');
errEl.textContent = err.message || 'Fehler'; errEl.style.display = '';
});
};
}
export function showChangePassword() {
const c = tpl('tpl-change-pw');
showSheet(c, true);
const oldP = c.querySelector('.cp-old'), newP = c.querySelector('.cp-new'), newP2 = c.querySelector('.cp-new2');
const errEl = c.querySelector('.login-err'), sub = c.querySelector('.cp-sub');
setTimeout(() => oldP.focus(), 50);
c.querySelector('.cp-can').onclick = closeOv;
sub.onclick = () => {
const o = oldP.value, n = newP.value, n2 = newP2.value;
if (!o || !n || !n2) return;
if (n !== n2) { errEl.textContent = tr('errPwMismatch'); errEl.style.display = ''; return; }
sub.disabled = true; sub.textContent = '…';
api('POST', 'change-password', { old_password: o, new_password: n })
.then(() => { showToast(tr('pwChanged')); closeOv(); })
.catch(err => {
sub.disabled = false; sub.textContent = tr('changePwBtn');
errEl.textContent = err.message || 'Fehler'; errEl.style.display = '';
});
};
}
export function showRegister(token) {
const c = tpl('tpl-register');
showSheet(c, false);
const nameInp = c.querySelector('.rg-name'), email = c.querySelector('.rg-email');
const pass = c.querySelector('.rg-pass'), pass2 = c.querySelector('.rg-pass2');
const errEl = c.querySelector('.login-err'), sub = c.querySelector('.rg-sub');
setTimeout(() => nameInp.focus(), 50);
nameInp.onkeydown = e => { if (e.key === 'Enter') email.focus(); };
email.onkeydown = e => { if (e.key === 'Enter') pass.focus(); };
pass.onkeydown = e => { if (e.key === 'Enter') pass2.focus(); };
pass2.onkeydown = e => { if (e.key === 'Enter') sub.click(); };
const checkMatch = () => {
if (pass2.value && pass.value !== pass2.value) { errEl.textContent = tr('errPwMismatch2'); errEl.style.display = ''; }
else errEl.style.display = 'none';
};
pass.oninput = checkMatch; pass2.oninput = checkMatch;
sub.onclick = () => {
const nv = nameInp.value.trim(), ev = email.value.trim(), pv = pass.value;
if (!nv || !ev || !pv) { errEl.textContent = tr('errFillAll'); errEl.style.display = ''; return; }
if (pv !== pass2.value) { errEl.textContent = tr('errPwMismatch2'); errEl.style.display = ''; return; }
sub.disabled = true; sub.textContent = '…';
api('POST', 'register', { name: nv, email: ev, password: pv, token })
.then(r => { state.userName = r.name || ''; return loadGoals(); })
.then(g => { state.goals = g; closeOv(); updateHeader(); render(); })
.catch(err => {
sub.disabled = false; sub.textContent = tr('registerBtn');
errEl.textContent = err.message || 'Fehler'; errEl.style.display = '';
});
};
}