Files
autocrm/routes/web.php
T
Vasyka 4b3201ca1c Batch 2: Workload heatmap + Site PSauto + VIN search
═══ Workload heatmap (Încărcare STO) ═══
- /app/workload custom Page (group Analiză)
- Săptămână (Lu-Du) × posturi → matrice ore programate
- Heatmap colorat: verde→galben→roșu pe ratio capacity (10h/zi)
- Navigare săpt anterior/curent/următor
- Programări fără pod → row '— fără pod —' separat

═══ Site PSauto (landing public) ═══
- / pe tenant subdomain → resources/views/site/landing.blade.php
- Hero cu logo + nume + slogan; gradient theme color
- Servicii (din settings.services) — grid card-uri
- Locație/contact + program lucru standardizat
- Mărci suportate (din settings.cars)
- CTA: phone + email
- Footer cu tenant name + powered by AutoCRM

═══ VIN search ═══
- VinDecoder service: WMI hardcoded (24 producători EU/Asia/USA)
  + year codes (2001-2026) — pure offline, fără API extern
- /app/vin-search Page (group Depozit) cu:
  • Input VIN cu uppercase + monospace
  • Decode → producător/țară/an/serial
  • Match VIN-uri din baza Vehicles
  • Search piese din catalog (live debounce 300ms)
- Rezultatele linkează la editor Vehicle/Part

Total tenant routes: 102.
2026-05-07 17:16:09 +00:00

79 lines
3.2 KiB
PHP

<?php
use App\Tenancy\TenantManager;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
// On a tenant subdomain → public landing page.
$tenant = app(TenantManager::class)->current();
if ($tenant) {
return view('site.landing', [
'name' => $tenant->display_name ?? $tenant->name,
'city' => $tenant->city,
'phone' => $tenant->phone,
'email' => $tenant->email,
'themeColor' => $tenant->settings['theme_color'] ?? '#3B82F6',
'services' => (array) ($tenant->settings['services'] ?? []),
'cars' => (array) ($tenant->settings['cars'] ?? []),
'logoUrl' => $tenant->getLogoUrl(),
'faviconUrl' => $tenant->getFaviconUrl(),
]);
}
// On the central domain → redirect to admin.
return redirect('/admin');
});
// PWA — manifest dinamic per tenant.
Route::get('/manifest.json', function (Request $request) {
$tenant = app(TenantManager::class)->current();
$name = $tenant?->display_name ?? $tenant?->name ?? 'AutoCRM';
$themeColor = $tenant?->settings['theme_color'] ?? '#3B82F6';
$shortName = $tenant?->slug ?? 'autocrm';
return response()->json([
'name' => $name,
'short_name' => mb_substr($shortName, 0, 12),
'description' => 'CRM autoservice — ' . $name,
'start_url' => '/app',
'display' => 'standalone',
'orientation' => 'any',
'background_color' => '#ffffff',
'theme_color' => $themeColor,
'lang' => $tenant?->settings['language'] ?? 'ro',
'icons' => [
['src' => '/pwa/icon-192.png', 'sizes' => '192x192', 'type' => 'image/png'],
['src' => '/pwa/icon-512.png', 'sizes' => '512x512', 'type' => 'image/png'],
['src' => '/pwa/icon-maskable.png', 'sizes' => '512x512', 'type' => 'image/png', 'purpose' => 'maskable'],
],
])->header('Cache-Control', 'public, max-age=3600');
});
// Service worker stub — minimal cache for shell.
Route::get('/sw.js', function () {
return response(<<<'JS'
const CACHE = 'autocrm-shell-v1';
const SHELL = ['/manifest.json'];
self.addEventListener('install', e => {
e.waitUntil(caches.open(CACHE).then(c => c.addAll(SHELL)));
});
self.addEventListener('activate', e => {
e.waitUntil(caches.keys().then(keys =>
Promise.all(keys.filter(k => k !== CACHE).map(k => caches.delete(k)))
));
});
self.addEventListener('fetch', e => {
const u = new URL(e.request.url);
if (e.request.method !== 'GET') return;
// network-first for app routes; cache-first for static
if (u.pathname.startsWith('/build/') || u.pathname.startsWith('/pwa/')) {
e.respondWith(caches.match(e.request).then(m => m || fetch(e.request).then(r => {
const copy = r.clone();
caches.open(CACHE).then(c => c.put(e.request, copy));
return r;
})));
}
});
JS, 200, ['Content-Type' => 'application/javascript', 'Cache-Control' => 'public, max-age=3600']);
});