2026-01-16 16:44:16 +00:00
|
|
|
export function renderLogin(onLogin) {
|
|
|
|
|
const loginContainer = document.createElement('div');
|
|
|
|
|
loginContainer.className = 'login-container';
|
|
|
|
|
|
|
|
|
|
loginContainer.innerHTML = `
|
|
|
|
|
<div class="login-card">
|
2026-02-06 22:00:04 +00:00
|
|
|
<div class="login-logo">
|
|
|
|
|
<div class="login-logo-icon">
|
|
|
|
|
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><line x1="10" y1="9" x2="8" y2="9"/></svg>
|
|
|
|
|
</div>
|
|
|
|
|
<h1 class="login-brand">Doli App</h1>
|
|
|
|
|
<p class="login-subtitle">Panel de facturación · Dolibarr</p>
|
|
|
|
|
</div>
|
2026-01-16 16:44:16 +00:00
|
|
|
<form id="login-form">
|
|
|
|
|
<div class="form-group">
|
2026-02-06 22:00:04 +00:00
|
|
|
<label for="identifier">
|
|
|
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align: -2px; margin-right: 4px;"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
|
|
|
|
Usuario o email
|
|
|
|
|
</label>
|
|
|
|
|
<input type="text" id="identifier" name="identifier" required autocomplete="username" placeholder="Introduce tu usuario">
|
2026-01-16 16:44:16 +00:00
|
|
|
</div>
|
|
|
|
|
<div class="form-group">
|
2026-02-06 22:00:04 +00:00
|
|
|
<label for="password">
|
|
|
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align: -2px; margin-right: 4px;"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
|
|
|
|
Contraseña
|
|
|
|
|
</label>
|
|
|
|
|
<input type="password" id="password" name="password" required autocomplete="current-password" placeholder="Introduce tu contraseña">
|
2026-01-16 16:44:16 +00:00
|
|
|
</div>
|
2026-02-06 22:00:04 +00:00
|
|
|
<button type="submit" class="login-button" id="login-btn">
|
|
|
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align: -3px; margin-right: 6px;" class="login-icon"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" y1="12" x2="3" y2="12"/></svg>
|
|
|
|
|
<span class="login-btn-text">Iniciar Sesión</span>
|
|
|
|
|
</button>
|
2026-01-16 16:44:16 +00:00
|
|
|
</form>
|
|
|
|
|
<p id="login-error" class="login-error"></p>
|
|
|
|
|
</div>
|
|
|
|
|
`;
|
|
|
|
|
|
2026-02-06 22:00:04 +00:00
|
|
|
const form = loginContainer.querySelector('#login-form');
|
|
|
|
|
const loginBtn = loginContainer.querySelector('#login-btn');
|
|
|
|
|
const loginIcon = loginBtn.querySelector('.login-icon');
|
|
|
|
|
const loginBtnText = loginBtn.querySelector('.login-btn-text');
|
|
|
|
|
|
|
|
|
|
form.addEventListener('submit', async (e) => {
|
2026-01-16 16:44:16 +00:00
|
|
|
e.preventDefault();
|
2026-02-06 22:00:04 +00:00
|
|
|
|
|
|
|
|
// Disable form while loading
|
|
|
|
|
const inputs = form.querySelectorAll('input');
|
|
|
|
|
loginBtn.disabled = true;
|
|
|
|
|
inputs.forEach(i => i.disabled = true);
|
|
|
|
|
loginIcon.style.display = 'none';
|
|
|
|
|
loginBtnText.textContent = 'Iniciando sesión...';
|
|
|
|
|
|
|
|
|
|
// Add spinner
|
|
|
|
|
const spinner = document.createElement('span');
|
|
|
|
|
spinner.className = 'spinner';
|
|
|
|
|
loginBtn.insertBefore(spinner, loginBtnText);
|
|
|
|
|
|
2026-01-16 18:06:00 +00:00
|
|
|
const email = loginContainer.querySelector('#identifier').value;
|
2026-01-16 16:44:16 +00:00
|
|
|
const password = loginContainer.querySelector('#password').value;
|
2026-02-06 22:00:04 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await onLogin(email, password);
|
|
|
|
|
} finally {
|
|
|
|
|
// Re-enable form
|
|
|
|
|
loginBtn.disabled = false;
|
|
|
|
|
inputs.forEach(i => i.disabled = false);
|
|
|
|
|
spinner.remove();
|
|
|
|
|
loginIcon.style.display = '';
|
|
|
|
|
loginBtnText.textContent = 'Iniciar Sesión';
|
|
|
|
|
}
|
2026-01-16 16:44:16 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return loginContainer;
|
|
|
|
|
}
|