whereBetween('date', [$start, $end]) ->get() ->map(fn (Appointment $a) => [ 'id' => $a->id, 'title' => trim($a->title ?: ($a->client?->name ?? '—')), 'start' => $a->date->format('Y-m-d') . 'T' . ($a->time_start ?? '08:00:00'), 'end' => $a->date->format('Y-m-d') . 'T' . ($a->time_end ?? '09:00:00'), 'backgroundColor' => $a->color ?: ($a->master?->color ?? '#3b82f6'), 'borderColor' => $a->color ?: ($a->master?->color ?? '#3b82f6'), 'extendedProps' => [ 'client' => $a->client?->name, 'vehicle' => trim(($a->vehicle?->make ?? '') . ' ' . ($a->vehicle?->model ?? '')), 'plate' => $a->vehicle?->plate, 'master' => $a->master?->name, 'post' => $a->post?->name, 'status' => $a->status, 'notes' => $a->notes, ], ])->all(); } /** Drag-drop reschedule. */ public function moveEvent(int $id, string $start, string $end): void { $a = Appointment::find($id); if (! $a) return; [$startDate, $startTime] = $this->splitIso($start); [, $endTime] = $this->splitIso($end); $a->update([ 'date' => $startDate, 'time_start' => $startTime, 'time_end' => $endTime, ]); Notification::make() ->title('Programare mutată') ->body($a->title . ' → ' . $startDate . ' ' . substr($startTime, 0, 5)) ->success()->send(); $this->dispatch('events-changed'); } public function quickCreate(string $start, string $end): void { $this->createData = [ 'date' => substr($start, 0, 10), 'time_start' => substr($start, 11, 5), 'time_end' => substr($end, 11, 5), ]; $this->createForm->fill($this->createData); $this->dispatch('open-create-modal'); } public function createForm(Schema $schema): Schema { return $schema->components([ Forms\Components\Hidden::make('date'), Forms\Components\TextInput::make('title')->label('Subiect')->required(), Schemas\Components\Section::make('Când') ->columns(2) ->schema([ Forms\Components\TimePicker::make('time_start')->label('De la')->seconds(false)->required(), Forms\Components\TimePicker::make('time_end')->label('Până la')->seconds(false)->required(), ]), Schemas\Components\Section::make('Cine') ->columns(2) ->schema([ Forms\Components\Select::make('client_id')->label('Client') ->options(fn () => Client::pluck('name', 'id')) ->searchable() ->live(), Forms\Components\Select::make('vehicle_id')->label('Auto') ->options(fn (\Filament\Schemas\Components\Utilities\Get $get) => $get('client_id') ? Vehicle::where('client_id', $get('client_id'))->pluck('plate', 'id') : []), Forms\Components\Select::make('master_id')->label('Maistru') ->options(fn () => User::where('status', 'active')->pluck('name', 'id')) ->searchable(), Forms\Components\Select::make('post_id')->label('Pod') ->options(fn () => Post::where('is_active', true)->pluck('name', 'id')) ->searchable(), ]), Forms\Components\Textarea::make('notes')->rows(2), ])->statePath('createData'); } public function saveCreate(): void { $data = $this->createForm->getState(); Appointment::create([ 'date' => $data['date'], 'time_start' => $data['time_start'], 'time_end' => $data['time_end'], 'title' => $data['title'], 'client_id' => $data['client_id'] ?? null, 'vehicle_id' => $data['vehicle_id'] ?? null, 'master_id' => $data['master_id'] ?? null, 'post_id' => $data['post_id'] ?? null, 'notes' => $data['notes'] ?? null, 'status' => 'scheduled', ]); $this->createData = []; Notification::make()->title('Programare adăugată')->success()->send(); $this->dispatch('close-create-modal'); $this->dispatch('events-changed'); } public function deleteEvent(int $id): void { Appointment::where('id', $id)->delete(); Notification::make()->title('Programare ștearsă')->success()->send(); $this->dispatch('events-changed'); } protected function splitIso(string $iso): array { // "2026-05-07T10:30:00" → ["2026-05-07", "10:30:00"] if (str_contains($iso, 'T')) { return explode('T', $iso); } return [substr($iso, 0, 10), substr($iso, 11) ?: '08:00:00']; } }