Files
autocrm/app/Filament/Tenant/Resources/WorkOrderResource/Pages/EditWorkOrder.php
T
Vasyka fa8704f8b6 feat(work-orders): new Mitchell1-style dashboard view (Phase 1 — layout + tabs)
Custom Filament Page at /app/work-orders/{id}/dashboard renders a
Mitchell1-inspired 3-column layout:
  - Top bar: WO#, status badge, actions (Edit / Tracking link)
  - Meta header row: creation / opened / ETA / responsible / urgency /
    paid amount (6 cells)
  - Left sidebar (300px): Client card (avatar, phone, email, status
    tag, 3-stat grid: visits/total/debt) + Vehicle card (photo, plate,
    VIN, mileage, engine, gearbox) + Repair history (latest 5 for this
    vehicle, links to dashboards)
  - Middle: tab bar (Lucrări/Piese/Diagnostic/Foto/Documente/Note)
    with Alpine-driven switching. Works & Parts show the tables read-
    only; add/edit still goes through existing EditWorkOrder Filament
    resource. Photos tab shows gallery from spatie/media-library.
  - Right (300px): Finance summary card (works cost, parts cost,
    discount, total, paid, balance) + placeholder for Timeline+Chat
    (Phase 2)
  - Responsive: right column collapses <1280px, left <900px.

'Vizualizare dashboard' button added on top of the existing
EditWorkOrder page so users can switch between edit form and info-
dense dashboard.

Fixed getSlug() signature (must match parent with ?Panel $panel).

+14 translations. All 306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-08-05 18:48:52 +00:00

102 lines
4.3 KiB
PHP

<?php
namespace App\Filament\Tenant\Resources\WorkOrderResource\Pages;
use App\Filament\Tenant\Resources\WorkOrderResource;
use App\Models\Tenant\WorkOrder;
use App\Services\WorkOrderPdfService;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditWorkOrder extends EditRecord
{
protected static string $resource = WorkOrderResource::class;
/** Manopere / Piese / Subcontract / Plăți se afișează SUS ca taburi, apoi antetul. */
public function hasCombinedRelationManagerTabsWithContent(): bool
{
return true;
}
public function getContentTabLabel(): ?string
{
return 'ⓘ ' . __('Info & antet');
}
public function getContentTabPosition(): ?\Filament\Resources\Pages\Enums\ContentTabPosition
{
// Puts the form (content) AFTER all relation manager tabs
return \Filament\Resources\Pages\Enums\ContentTabPosition::After;
}
protected function getHeaderActions(): array
{
return [
Actions\Action::make('dashboard')
->label(__('Vizualizare dashboard'))
->icon('heroicon-m-squares-2x2')
->color('info')
->url(fn () => route('filament.tenant.pages.work-order-dashboard', ['record' => $this->record->id])),
Actions\Action::make('apply_template')
->label(__('Aplică șablon'))
->icon('heroicon-m-clipboard-document-list')
->color('gray')
->schema([
\Filament\Forms\Components\Select::make('template_id')
->label(__('Șablon serviciu'))
->options(fn () => \App\Models\Tenant\ServiceTemplate::where('is_active', true)->pluck('name', 'id'))
->searchable()
->required(),
])
->action(function (array $data) {
$template = \App\Models\Tenant\ServiceTemplate::with('items')->find($data['template_id']);
if (! $template) return;
$r = app(\App\Services\ServiceComposer::class)->applyTemplate($this->record, $template);
$this->fillForm();
\Filament\Notifications\Notification::make()
->title(__('Șablon aplicat') . ": {$r['labor']} " . __('manopere') . ", {$r['parts']} " . __('piese'))
->success()->send();
}),
Actions\Action::make('ai_diagnose')
->label(__('AI: sugerează diagnostic'))
->icon('heroicon-m-sparkles')
->color('primary')
->visible(fn () => ! empty($this->record->complaint))
->modalHeading(__('Diagnostic AI bazat pe plângerea clientului'))
->modalSubmitAction(false)
->modalCancelActionLabel(__('Închide'))
->modalContent(function () {
[$reply, $meta] = app(\App\Services\Ai\AiAssistantService::class)
->suggestDiagnosis($this->record);
return view('filament.tenant.ai-reply', ['reply' => $reply, 'meta' => $meta]);
}),
Actions\Action::make('tracking')
->label(__('Link client (QR)'))
->icon('heroicon-m-qr-code')
->color('primary')
->modalHeading(fn () => __('Tracking client') . ' — WO #' . $this->record->number)
->modalSubmitAction(false)
->modalCancelActionLabel(__('Închide'))
->modalWidth('lg')
->modalContent(fn () => view('filament.tenant.tracking-qr', [
'wo' => $this->record,
])),
Actions\Action::make('pdf')
->label(__('Descarcă PDF'))
->icon('heroicon-m-document-arrow-down')
->color('gray')
->action(function () {
/** @var WorkOrder $wo */
$wo = $this->record;
$svc = app(WorkOrderPdfService::class);
$pdf = $svc->generate($wo);
return response()->streamDownload(
fn () => print($pdf->output()),
$svc->filename($wo)
);
}),
Actions\DeleteAction::make(),
];
}
}