7077fff3b3
- Convert all remaining static \$modelLabel/\$pluralModelLabel to getter methods with __() (AppointmentResource, WorkOrderResource, MasterResource, ServiceTemplateResource, LaborResource, and 33 others) - Safe blade wrap v2 (37 files, 201 wraps): fixed the regex to not match `->`, `=>`, `!<` — previous aggressive pass broke @if directives - Bulk-translate lowercase model-label keys (programări, fișe lucru, tehnicieni, șabloane servicii, norme-ore, etc.) — these were the RO strings appearing in page titles/breadcrumbs - Add human RU/EN for mechanic-kpi (Mecanic/Lucrări/Norma ore/etc.) and calendar-board words Tests 306 green. Blade compiles cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
103 lines
6.1 KiB
PHP
103 lines
6.1 KiB
PHP
<x-filament-panels::page>
|
|
<style>
|
|
.vs-card { background: #fff; border: 1px solid #e5e7eb; border-radius: 10px; padding: 20px; margin-bottom: 16px; }
|
|
.dark .vs-card { background: #1f2937; border-color: #374151; }
|
|
.vs-input {
|
|
width: 100%; padding: 12px 16px; border: 1px solid #e5e7eb; border-radius: 8px;
|
|
font-family: monospace; font-size: 16px; letter-spacing: 1px; text-transform: uppercase;
|
|
}
|
|
.dark .vs-input { background: #111827; border-color: #374151; color: #f9fafb; }
|
|
.vs-btn {
|
|
padding: 10px 24px; background: #3b82f6; color: #fff; border: none;
|
|
border-radius: 8px; font-weight: 500; cursor: pointer; margin-top: 12px;
|
|
}
|
|
.vs-btn:hover { background: #2563eb; }
|
|
.vs-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
|
.vs-stat-l { font-size: 11px; color: #6b7280; text-transform: uppercase; letter-spacing: .5px; }
|
|
.vs-stat-v { font-size: 16px; font-weight: 600; margin-top: 4px; }
|
|
.vs-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
|
|
.vs-tbl th, .vs-tbl td { padding: 8px; text-align: left; border-bottom: 1px solid #f3f4f6; }
|
|
.vs-tbl th { background: #f9fafb; font-weight: 600; color: #6b7280; font-size: 12px; }
|
|
</style>
|
|
|
|
<div class="vs-card">
|
|
<h2 style="font-size:16px;font-weight:600;margin-bottom:12px;">{{ __('🔎 Decode VIN') }}</h2>
|
|
<form wire:submit="decode" style="display:flex;gap:12px;flex-wrap:wrap;">
|
|
<input type="text" wire:model="vin" class="vs-input" placeholder="{{ __('WBAFE81070CY34521') }}" maxlength="17" style="flex:1;min-width:300px;">
|
|
<button type="submit" class="vs-btn">{{ __('Decodează') }}</button>
|
|
</form>
|
|
</div>
|
|
|
|
@if ($decoded)
|
|
<div class="vs-card">
|
|
@if ($decoded['valid'])
|
|
<h3 style="font-size:14px;font-weight:600;margin-bottom:16px;">{{ __('✅ VIN decodificat') }}</h3>
|
|
<div class="vs-grid">
|
|
<div><div class="vs-stat-l">{{ __('Producător') }}</div><div class="vs-stat-v">{{ $decoded['manufacturer'] }}</div></div>
|
|
<div><div class="vs-stat-l">{{ __('Țară') }}</div><div class="vs-stat-v">{{ $decoded['country'] }}</div></div>
|
|
<div><div class="vs-stat-l">An model (estimat)</div><div class="vs-stat-v">{{ $decoded['year'] ?? '—' }}</div></div>
|
|
<div><div class="vs-stat-l">WMI</div><div class="vs-stat-v" style="font-family:monospace;">{{ $decoded['wmi'] }}</div></div>
|
|
<div><div class="vs-stat-l">{{ __('Serial') }}</div><div class="vs-stat-v" style="font-family:monospace;font-size:12px;">{{ $decoded['serial'] }}</div></div>
|
|
</div>
|
|
@else
|
|
<div style="color:#dc2626;">⚠ {{ $decoded['error'] ?? 'WMI necunoscut — producătorul nu e în baza de date locală.' }}</div>
|
|
@endif
|
|
</div>
|
|
|
|
@php $matches = $this->vehicleMatches(); @endphp
|
|
@if ($matches->isNotEmpty())
|
|
<div class="vs-card">
|
|
<h3 style="font-size:14px;font-weight:600;margin-bottom:12px;">{{ __('🚗 Mașini cu acest VIN în CRM') }}</h3>
|
|
<table class="vs-tbl">
|
|
<thead><tr><th>VIN</th><th>{{ __('Marca/Model') }}</th><th>{{ __('Plate') }}</th><th>{{ __('Client') }}</th><th>{{ __('Km') }}</th></tr></thead>
|
|
<tbody>
|
|
@foreach ($matches as $v)
|
|
<tr>
|
|
<td style="font-family:monospace;font-size:11px;">{{ $v->vin }}</td>
|
|
<td>{{ $v->make }} {{ $v->model }} {{ $v->year }}</td>
|
|
<td>{{ $v->plate ?? '—' }}</td>
|
|
<td>{{ $v->client?->name ?? '—' }}</td>
|
|
<td>{{ number_format($v->mileage, 0, '.', ' ') }}</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
@endif
|
|
|
|
<div class="vs-card">
|
|
<h2 style="font-size:16px;font-weight:600;margin-bottom:12px;">{{ __('📦 Caută piesă în catalog') }}</h2>
|
|
<input type="text" wire:model.live.debounce.300ms="partsQuery" class="vs-input"
|
|
placeholder="{{ __('Nume, cod articol, brand...') }}" style="font-size:14px;text-transform:none;font-family:inherit;">
|
|
|
|
@php $parts = $this->partsResults(); @endphp
|
|
@if ($partsQuery)
|
|
<div style="margin-top:16px;">
|
|
@if ($parts->isEmpty())
|
|
<div style="color:#9ca3af;text-align:center;padding:20px;">Niciun rezultat pentru „{{ $partsQuery }}"</div>
|
|
@else
|
|
<table class="vs-tbl">
|
|
<thead><tr><th>{{ __('Denumire') }}</th><th>{{ __('Cod') }}</th><th>{{ __('Brand') }}</th><th>{{ __('Stoc') }}</th><th>{{ __('Preț') }}</th></tr></thead>
|
|
<tbody>
|
|
@foreach ($parts as $p)
|
|
<tr>
|
|
<td>
|
|
<a href="{{ route('filament.tenant.resources.parts.edit', ['record' => $p->id]) }}" style="color:inherit;">{{ $p->name }}</a>
|
|
</td>
|
|
<td style="font-family:monospace;font-size:11px;">{{ $p->article ?? '—' }}</td>
|
|
<td>{{ $p->brand ?? '—' }}</td>
|
|
<td style="color: {{ $p->qty <= 0 ? '#dc2626' : ($p->qty <= $p->min_qty ? '#d97706' : '#059669') }};">
|
|
{{ $p->qty }} {{ $p->unit }}
|
|
</td>
|
|
<td>{{ number_format($p->sell_price, 2, '.', ' ') }} MDL</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-filament-panels::page>
|