schema([ Select::make('user_id') ->relationship('user', 'name') ->searchable() ->preload() ->required(), Select::make('status') ->label('Status') ->options([ 'open' => 'Open', 'pending' => 'In Progress', 'closed' => 'Closed', ]) ->default('open') ->required(), TextInput::make('subject') ->label('Subject') ->required() ->maxLength(255) ->columnSpanFull(), TextArea::make('message') ->label('Message') ->required() ->rows(7) ->maxLength(2000) ->columnSpanFull(), ]); } public static function table(Table $table): Table { return $table ->defaultSort('created_at', 'desc') ->columns([ TextColumn::make('ticket_id') ->label('Ticket ID') ->sortable(), TextColumn::make('user.name'), TextColumn::make('subject') ->limit(50) ->label('Subject'), BadgeColumn::make('status') ->colors([ 'success' => fn ($state) => $state === 'open', 'warning' => fn ($state) => $state === 'pending', 'danger' => fn ($state) => $state === 'closed', ]) ->sortable(), TextColumn::make('created_at') ->label('Created At') ->dateTime('F d, Y • h:i A')->sortable(), TextColumn::make('last_response_at') ->label('Last Response') ->sortable() ->formatStateUsing(fn ($state) => $state?->diffForHumans()), ]) ->filters([ SelectFilter::make('status') ->label('Status') ->options([ 'open' => 'Open', 'pending' => 'In Progress', 'closed' => 'Closed', ]) ->attribute('status'), Filter::make('created_at') ->form([ DatePicker::make('created_from')->label('Created From'), DatePicker::make('created_until')->label('Created Until'), ]) ->query(function ($query, array $data) { return $query ->when($data['created_from'], fn ($query, $date) => $query->whereDate('created_at', '>=', $date)) ->when($data['created_until'], fn ($query, $date) => $query->whereDate('created_at', '<=', $date)); }), ]) // ->actions([ // Tables\Actions\EditAction::make(), // ]) ->actions([ Action::make('view') ->label('View & Respond') ->icon('heroicon-o-eye') ->form(function (Ticket $ticket): array { return [ TextArea::make('response') ->label('Your Response') ->required() ->rows(7) ->placeholder('Type your response here...'), Select::make('status') ->label('Ticket Status') ->options([ 'open' => 'Open', 'pending' => 'In Progress', 'closed' => 'Closed', ]) ->default($ticket->status === 'open' ? 'pending' : $ticket->status) ->required(), ]; }) ->modalContent(function (Ticket $ticket) { $html = '
'; // Ticket Subject & Message $html .= '
'; $html .= '
Subject: ' . e($ticket->subject) . '
'; $html .= '

Message: ' . nl2br(e($ticket->message)) . '

'; $html .= '
'; // Responses Section $html .= '
Previous Responses
'; foreach ($ticket->responses as $response) { $html .= '
'; $html .= '
'; $html .= '' . e($response->user->name) . ''; $html .= '' . e($response->created_at->diffForHumans()) . ''; $html .= '
'; $html .= '

' . nl2br(e($response->response)) . '

'; $html .= '
'; } if ($ticket->responses->isEmpty()) { $html .= '

No responses yet.

'; } $html .= '
'; return new \Illuminate\Support\HtmlString($html); }) ->action(function (array $data, Ticket $ticket) { TicketResponse::create([ 'ticket_id' => $ticket->id, 'user_id' => auth()->id(), 'response' => $data['response'], ]); // Update ticket status and last response time $ticket->update([ 'status' => $data['status'], 'last_response_at' => now(), ]); // Send success notification Notification::make() ->title('Response sent successfully!') ->success() ->send(); }) ->modalHeading('View & Respond to Ticket') ->modalSubmitActionLabel('Send Reply'), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), Tables\Actions\BulkAction::make('notify_users') ->label('Send Email Notification') ->color('success') ->icon('heroicon-o-envelope') ->requiresConfirmation() ->deselectRecordsAfterCompletion() ->action(function (\Illuminate\Support\Collection $records) { foreach ($records as $ticket) { $responses = $ticket->responses() ->with('user') ->orderBy('created_at', 'desc') ->get(); if ($ticket->user && $ticket->user->email) { \Illuminate\Support\Facades\Mail::to($ticket->user->email) ->send(new \App\Mail\TicketResponseNotification($ticket, $responses)); } } \Filament\Notifications\Notification::make() ->title('Email notifications sent successfully!') ->success() ->send(); }), ]), ]); } public static function getRelations(): array { return [ RelationManagers\ResponsesRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListTickets::route('/'), 'create' => Pages\CreateTicket::route('/create'), 'edit' => Pages\EditTicket::route('/{record}/edit'), ]; } }