import { apiPostUrlEncoded, getStoredMobileConfig } from '../api.js'; import { getUsageTrialState } from '../auth.js'; export async function renderLogin(root, onLoggedIn) { if (typeof root.__loginCountdownCleanup === 'function') { root.__loginCountdownCleanup(); } const cfg = getStoredMobileConfig(); const logoUrl = cfg.logo_url || '/insuite-logo.svg'; const appName = cfg.app_name || 'Insuite Technicien'; const trialState = getUsageTrialState(); const trialExpired = trialState.expired; const loginBgStyle = cfg.login_bg_url ? `style="background-image:url('${escapeAttr(cfg.login_bg_url)}');background-size:cover;background-position:center"` : ''; root.innerHTML = `
Android ready

${escapeAttr(appName)}

Connexion sécurisée à la fiche terrain mobile, pensée pour le travail terrain et la validation rapide.

Accès limité ${trialExpired ? 'Délai dépassé' : 'Compte à rebours 2 semaines'}
-- j -- h -- min -- s
`; const errBox = root.querySelector('#errBox'); const okBox = root.querySelector('#okBox'); const form = root.querySelector('#loginForm'); const trialTimer = root.querySelector('#trialTimer'); const trialMeta = root.querySelector('#trialMeta'); const trialStateLabel = root.querySelector('#trialStateLabel'); const trialProgressBar = root.querySelector('#trialProgressBar'); const renderTrialState = () => { const state = getUsageTrialState(); const total = state.totalDurationMs || 1; const elapsedRatio = Math.min(1, Math.max(0, (total - state.remainingMs) / total)); if (trialProgressBar) { trialProgressBar.style.width = `${Math.round((1 - elapsedRatio) * 100)}%`; } if (state.expired) { trialStateLabel.textContent = 'Délai dépassé'; trialTimer.textContent = '00 j 00 h 00 min 00 s'; trialMeta.textContent = 'La période de 14 jours est terminée. La connexion est désormais bloquée.'; return true; } const totalSeconds = Math.floor(state.remainingMs / 1000); const days = Math.floor(totalSeconds / 86400); const hours = Math.floor((totalSeconds % 86400) / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; const formatPart = (value, suffix) => `${String(value).padStart(2, '0')} ${suffix}`; trialStateLabel.textContent = 'Compte à rebours 2 semaines'; trialTimer.textContent = [ formatPart(days, 'j'), formatPart(hours, 'h'), formatPart(minutes, 'min'), formatPart(seconds, 's') ].join(' '); trialMeta.textContent = `Expiration prévue le ${new Date(state.expiresAt).toLocaleString('fr-FR')}.`; return false; }; let countdownHandle = window.setInterval(() => { const expired = renderTrialState(); if (expired) { window.clearInterval(countdownHandle); location.hash = '#/login'; renderLogin(root, onLoggedIn); } }, 1000); root.__loginCountdownCleanup = () => { window.clearInterval(countdownHandle); }; renderTrialState(); if (trialExpired) { errBox.textContent = 'La période autorisée de 14 jours est expirée. La connexion est bloquée.'; errBox.style.display = 'block'; } form.addEventListener('submit', async (e) => { e.preventDefault(); errBox.style.display = 'none'; okBox.style.display = 'none'; const currentTrialState = getUsageTrialState(); if (currentTrialState.expired) { errBox.textContent = 'La période autorisée de 14 jours est expirée. La connexion est bloquée.'; errBox.style.display = 'block'; renderTrialState(); return; } const fd = new FormData(form); const email = String(fd.get('email') || '').trim(); const password = String(fd.get('password') || ''); try { const res = await apiPostUrlEncoded('/api/mobile/login', { email, password }); if (!res?.ok || !res?.token) { errBox.textContent = 'Connexion impossible.'; errBox.style.display = 'block'; return; } okBox.textContent = 'Connexion établie.'; okBox.style.display = 'block'; root.__loginCountdownCleanup?.(); onLoggedIn(res.token); } catch (err) { const msg = err?.data?.error === 'requires_2fa' ? '2FA requis (non supporté dans l’app pour le moment).' : err?.data?.error === 'needs_license' ? 'L\'utilisateur a besoin d\'une licence pour l\'utilisation.' : (err?.status ? 'Identifiants invalides ou accès refusé.' : 'Connexion au serveur impossible. Vérifiez le réseau de la tablette.'); errBox.textContent = msg; errBox.style.display = 'block'; } }); } function escapeAttr(value) { return String(value ?? '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); }