feat: Implement client authentication and pre-fill functionality

- Added AuthController for client login and token management.
- Introduced AuthGate for handling authentication state and login UI.
- Updated API to support fetching client data for pre-filling forms.
- Modified App.vue to pre-fill client information if logged in.
- Enhanced client model to include username and password fields.
- Created migration for adding username and password to clients table.
- Added utility for generating secure usernames and passwords.
- Updated frontend to handle client tokens for pre-filling checkout forms.
- Removed old CSS file and updated HTML references to new assets.
- Added StatsOverview widget for displaying client and quote statistics.
- Improved error handling and user feedback in the login process.
This commit is contained in:
2026-08-24 17:24:46 +02:00
parent 1c40ef6601
commit d6a9978167
23 changed files with 666 additions and 54 deletions
+13 -9
View File
@@ -12,6 +12,8 @@ import './price_calculator.js';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
import Configurator from './configurator.js';
import AuthGate from './auth_gate.js';
import { API_BASE as PREVENTIVI_API_BASE } from './api_base.js';
window.$ = $;
@@ -20,13 +22,6 @@ window.OrbitControls = OrbitControls; // Used by APP Scripts.
window.GLTFLoader = GLTFLoader; // Used by APP Scripts.
// --- Integrazione backend preventivi ---
// Base URL dell'API Laravel: impostata in build (import.meta.env.VITE_PREVENTIVI_API_BASE, da
// .env/.env.production — vedi root del repo), sovrascrivibile a runtime con window.PREVENTIVI_API_BASE
// senza dover rebuildare (es. per un hotfix). Nessuna delle due impostata → fallback dev locale.
const PREVENTIVI_API_BASE =
(typeof window.PREVENTIVI_API_BASE === 'string' && window.PREVENTIVI_API_BASE) ||
import.meta.env.VITE_PREVENTIVI_API_BASE ||
'http://localhost:8000/api';
const CART_TOKEN_KEY = 'kreios_cart_token';
// URL dell'app cliente (checkout): richiesto all'API invece di essere indovinato, perché la
@@ -59,7 +54,14 @@ window.mostraLinkPreventivo = (token, count) => {
// diverse in dev/prod): lo passiamo qui come parametro, così il link "torna al configuratore"
// nella pagina di conferma può essere generato dinamicamente invece di essere hardcoded.
const ritorno = encodeURIComponent(window.location.href);
link.href = `${appClienteUrl}/?token=${encodeURIComponent(token)}&ritorno=${ritorno}`;
let href = `${appClienteUrl}/?token=${encodeURIComponent(token)}&ritorno=${ritorno}`;
// Se il cliente è loggato nel configuratore, passiamo il suo token anche al checkout
// così può precompilare l'anagrafica già salvata (vedi AuthGate.getToken()).
const clienteToken = AuthGate.getToken();
if (clienteToken) {
href += `&cliente_token=${encodeURIComponent(clienteToken)}`;
}
link.href = href;
link.textContent = count > 0 ? `Vai al preventivo (${count})` : 'Vai al preventivo';
link.classList.remove('d-none');
};
@@ -256,12 +258,14 @@ const start = async () => {
});
window.generaImagine = async () => {
playerOff.viewFrontSide(0.6);
playerOff.render();
$('#canvas-offscreen').removeClass('d-none');
const canvas = $('#canvas-offscreen canvas')[0];
const dataUrl = await canvas.toDataURL('image/png');
$('#canvas-offscreen').addClass('d-none');
playerOff.viewFrontSide();
return dataUrl;
const a = document.createElement('a');
a.href = dataUrl;
@@ -437,4 +441,4 @@ const start = async () => {
}
start();
AuthGate.ensure().then(start);