Files
autocrm/resources/views/filament/central/resources/company/view.blade.php
T
Vasyka 7077fff3b3 feat(i18n): convert 38 hardcoded static labels + safe blade wrap + 226 keys
- 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>
2026-07-15 06:17:10 +00:00

240 lines
12 KiB
PHP

<x-filament-panels::page>
<style>
.cv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.cv-card {
background: #fff; border: 1px solid #e5e7eb; border-radius: 10px;
padding: 16px; position: relative;
}
.dark .cv-card { background: #1f2937; border-color: #374151; }
.cv-card .label { font-size: 11px; color: #9ca3af; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 4px; }
.cv-card .value { font-size: 22px; font-weight: 700; }
.cv-card .sub { font-size: 12px; color: #6b7280; margin-top: 2px; }
.cv-card.warn { border-color: #f59e0b; background: #fffbeb; }
.dark .cv-card.warn { background: #78350f30; }
.cv-card.danger { border-color: #ef4444; background: #fef2f2; }
.dark .cv-card.danger { background: #7f1d1d30; }
.cv-card.success { border-color: #10b981; background: #ecfdf5; }
.dark .cv-card.success { background: #064e3b30; }
.cv-section { margin-top: 24px; }
.cv-section-title { font-size: 14px; font-weight: 600; color: #6b7280; margin-bottom: 12px; text-transform: uppercase; letter-spacing: .5px; }
.cv-table { width: 100%; border-collapse: collapse; font-size: 13px; background: #fff; border-radius: 8px; overflow: hidden; border: 1px solid #e5e7eb; }
.dark .cv-table { background: #1f2937; border-color: #374151; }
.cv-table th, .cv-table td { padding: 8px 12px; text-align: left; border-bottom: 1px solid #f3f4f6; }
.dark .cv-table th, .dark .cv-table td { border-color: #374151; }
.cv-table th { font-size: 11px; font-weight: 600; color: #9ca3af; text-transform: uppercase; }
.cv-badge { display: inline-block; padding: 3px 8px; border-radius: 12px; font-size: 11px; font-weight: 600; }
.cv-badge-success { background: #dcfce7; color: #166534; }
.cv-badge-warning { background: #fef3c7; color: #92400e; }
.cv-badge-danger { background: #fee2e2; color: #991b1b; }
.cv-badge-gray { background: #f3f4f6; color: #4b5563; }
.dark .cv-badge-success { background: #14532d; color: #86efac; }
.dark .cv-badge-warning { background: #78350f; color: #fde68a; }
.dark .cv-badge-danger { background: #7f1d1d; color: #fca5a5; }
.dark .cv-badge-gray { background: #374151; color: #d1d5db; }
.cv-header {
display: flex; gap: 16px; align-items: center;
background: linear-gradient(135deg, #eff6ff, #dbeafe);
padding: 20px; border-radius: 12px; border: 1px solid #bfdbfe;
margin-bottom: 20px;
}
.dark .cv-header { background: linear-gradient(135deg, #1e3a8a40, #1e40af30); border-color: #1e3a8a; }
.cv-header img { max-height: 64px; max-width: 80px; border-radius: 8px; background: #fff; padding: 4px; }
.cv-header h2 { font-size: 22px; font-weight: 700; }
.cv-header .sub { font-size: 13px; color: #4b5563; }
.dark .cv-header .sub { color: #9ca3af; }
</style>
@php
$stats = $this->getStats();
$daysLeft = $this->getDaysUntilExpiry();
$statusColors = [
'active' => 'success',
'trial' => 'warning',
'suspended' => 'danger',
'expired' => 'danger',
'archived' => 'gray',
];
$statusLabel = match ($this->record->status) {
'active' => 'Activ',
'trial' => 'Trial',
'suspended' => 'Suspendat',
'expired' => 'Expirat',
'archived' => 'Arhivat',
default => $this->record->status,
};
@endphp
{{-- HEADER --}}
<div class="cv-header">
@if ($this->record->getLogoUrl())
<img src="{{ $this->record->getLogoUrl() }}" alt="logo">
@endif
<div style="flex:1;">
<h2>{{ $this->record->display_name ?? $this->record->name }}</h2>
<div class="sub">
<a href="{{ $this->record->url() }}" target="_blank" style="color:inherit;text-decoration:underline;">{{ $this->record->slug }}.service.mir.md</a>
@if ($this->record->city) · {{ $this->record->city }} @endif
@if ($this->record->phone) · {{ $this->record->phone }} @endif
@if ($this->record->email) · {{ $this->record->email }} @endif
</div>
<div style="margin-top:8px;display:flex;gap:6px;align-items:center;flex-wrap:wrap;">
<span class="cv-badge cv-badge-{{ $statusColors[$this->record->status] ?? 'gray' }}">
{{ $statusLabel }}
</span>
@if ($this->record->plan)
<span class="cv-badge cv-badge-gray">📦 {{ $this->record->plan->name }}</span>
@else
<span class="cv-badge cv-badge-warning">{{ __('⚠ Fără plan') }}</span>
@endif
@if ($daysLeft !== null)
@if ($daysLeft < 0)
<span class="cv-badge cv-badge-danger">Expirat acum {{ abs($daysLeft) }} zile</span>
@elseif ($daysLeft < 7)
<span class="cv-badge cv-badge-warning">Expiră în {{ $daysLeft }} zile</span>
@else
<span class="cv-badge cv-badge-success">{{ $daysLeft }} zile rămase</span>
@endif
@endif
</div>
</div>
</div>
{{-- STATS GRID --}}
<div class="cv-section">
<div class="cv-section-title">{{ __('📊 Activitate live') }}</div>
<div class="cv-grid">
<div class="cv-card">
<div class="label">{{ __('Useri') }}</div>
<div class="value">{{ $stats['users'] }}</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Clienți') }}</div>
<div class="value">{{ $stats['clients'] }}</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Mașini') }}</div>
<div class="value">{{ $stats['vehicles'] }}</div>
</div>
<div class="cv-card {{ $stats['work_orders_open'] > 0 ? 'warn' : '' }}">
<div class="label">{{ __('Fișe lucru') }}</div>
<div class="value">{{ $stats['work_orders'] }}</div>
<div class="sub">{{ $stats['work_orders_open'] }} deschise</div>
</div>
<div class="cv-card {{ $stats['parts_low_stock'] > 0 ? 'warn' : '' }}">
<div class="label">{{ __('Piese în stoc') }}</div>
<div class="value">{{ $stats['parts'] }}</div>
@if ($stats['parts_low_stock'])
<div class="sub"> {{ $stats['parts_low_stock'] }} sub minim</div>
@endif
</div>
<div class="cv-card success">
<div class="label">{{ __('Venit luna curentă') }}</div>
<div class="value">{{ number_format($stats['revenue_this_month'], 0, ',', ' ') }}</div>
<div class="sub">{{ $this->record->settings['currency'] ?? 'MDL' }}</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Venit luna trecută') }}</div>
<div class="value">{{ number_format($stats['revenue_last_month'], 0, ',', ' ') }}</div>
<div class="sub">{{ $this->record->settings['currency'] ?? 'MDL' }}</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Storage media') }}</div>
<div class="value">{{ $stats['storage_mb'] }}</div>
<div class="sub">{{ __('MB folosiți') }}</div>
</div>
<div class="cv-card {{ $stats['last_login'] && \Carbon\Carbon::parse($stats['last_login'])->diffInDays() > 14 ? 'danger' : '' }}">
<div class="label">{{ __('Ultima logare') }}</div>
<div class="value" style="font-size:14px;">
{{ $stats['last_login'] ? \Carbon\Carbon::parse($stats['last_login'])->diffForHumans() : 'Niciodată' }}
</div>
@if ($stats['last_login'] && \Carbon\Carbon::parse($stats['last_login'])->diffInDays() > 14)
<div class="sub">{{ __('⚠ Posibil churn') }}</div>
@endif
</div>
</div>
</div>
{{-- SUBSCRIPTIONS --}}
<div class="cv-section">
<div class="cv-section-title">{{ __('💳 Istoric abonamente') }}</div>
@if ($this->record->subscriptions->isEmpty())
<div style="padding:32px;text-align:center;color:#9ca3af;font-size:13px;border:1px dashed #e5e7eb;border-radius:8px;">
{{ __('Niciun abonament emis. Folosește „Generează factură" de sus.') }}
</div>
@else
<table class="cv-table">
<thead>
<tr>
<th>{{ __('Factură') }}</th>
<th>{{ __('Plan') }}</th>
<th>{{ __('Perioadă') }}</th>
<th>{{ __('Sumă') }}</th>
<th>{{ __('Status') }}</th>
<th>{{ __('Plătit') }}</th>
</tr>
</thead>
<tbody>
@foreach ($this->record->subscriptions as $s)
<tr>
<td><b>{{ $s->invoice_number ?? '—' }}</b></td>
<td>{{ $s->plan?->name ?? '—' }}</td>
<td>{{ $s->period_start?->format('d.m.Y') }} {{ $s->period_end?->format('d.m.Y') }}</td>
<td><b>{{ number_format($s->amount, 2) }} {{ $s->currency }}</b></td>
<td>
<span class="cv-badge cv-badge-{{ match($s->status){'paid'=>'success','overdue'=>'danger','pending'=>'warning',default=>'gray'} }}">
{{ \App\Models\Central\Subscription::STATUSES[$s->status] ?? $s->status }}
</span>
</td>
<td>{{ $s->paid_at?->format('d.m.Y') ?? '—' }}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
</div>
{{-- CONFIG --}}
<div class="cv-section">
<div class="cv-section-title">{{ __('⚙ Configurare tenant') }}</div>
<div class="cv-grid" style="grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));">
<div class="cv-card">
<div class="label">{{ __('Limbă') }}</div>
<div class="value" style="font-size:14px;">
{{ ['ro' => 'Română', 'ru' => 'Русский', 'en' => 'English'][$this->record->settings['language'] ?? 'ro'] ?? '—' }}
</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Monedă') }}</div>
<div class="value" style="font-size:14px;">{{ $this->record->settings['currency'] ?? 'MDL' }}</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Tarif normo-oră') }}</div>
<div class="value" style="font-size:14px;">{{ $this->record->settings['labor_rate'] ?? '—' }}</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Onboarded') }}</div>
<div class="value" style="font-size:14px;">
{{ ! empty($this->record->settings['onboarded_at']) ? '✓ Da' : '✗ Nu' }}
</div>
</div>
<div class="cv-card">
<div class="label">{{ __('Theme color') }}</div>
<div class="value" style="display:flex;align-items:center;gap:6px;font-size:14px;">
<span style="display:inline-block;width:18px;height:18px;border-radius:3px;background:{{ $this->record->settings['theme_color'] ?? '#3B82F6' }};"></span>
{{ $this->record->settings['theme_color'] ?? '#3B82F6' }}
</div>
</div>
<div class="cv-card">
<div class="label">{{ __('AI provider') }}</div>
<div class="value" style="font-size:14px;">
{{ $this->record->settings['ai']['default_provider'] ?? 'neconfigurat' }}
</div>
</div>
</div>
</div>
</x-filament-panels::page>