Skip to content

Commit 2a1a5b6

Browse files
committed
refactor: improve code quality and type safety
- Add proper type hints to method parameters and return types - Import classes at top of files instead of using FQCNs - Fix coding style issues (spacing, array syntax, etc.) - Update test assertions for proper format strings - Remove unused imports and fix docblocks - Follow PSR-12 coding standards consistently
1 parent 0d9ecc0 commit 2a1a5b6

File tree

24 files changed

+309
-259
lines changed

24 files changed

+309
-259
lines changed

app/Filament/Home/Pages/Home.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Home extends Page
2222

2323
public ?array $data = [];
2424

25-
public function mount()
25+
public function mount(): void
2626
{
2727
$this->form->fill([]);
2828
}

app/Filament/Home/Pages/Search.php

Lines changed: 150 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22

33
namespace App\Filament\Home\Pages;
44

5+
use App\Enums\BusCategory;
6+
use App\Enums\BusType;
7+
use App\Models\Operator;
58
use App\Models\Route;
69
use CodeWithDennis\FilamentLucideIcons\Enums\LucideIcon;
710
use Filament\Actions\Action;
11+
use Filament\Forms\Components\CheckboxList;
812
use Filament\Forms\Components\DatePicker;
913
use Filament\Forms\Components\Select;
14+
use Filament\Forms\Components\Slider;
1015
use Filament\Forms\Components\TextInput;
1116
use Filament\Infolists\Components\RepeatableEntry;
1217
use Filament\Infolists\Components\TextEntry;
1318
use Filament\Pages\Page;
14-
use Filament\Schemas\Components\Fieldset;
19+
use Filament\Schemas\Components\Component;
1520
use Filament\Schemas\Components\Flex;
1621
use Filament\Schemas\Components\Section;
1722
use Filament\Schemas\Components\View;
@@ -28,14 +33,26 @@ class Search extends Page
2833

2934
#[Url]
3035
public string $from = '';
36+
3137
#[Url]
3238
public string $to = '';
39+
3340
#[Url]
3441
public string $date = '';
42+
3543
#[Url]
3644
public string $passengers = '';
3745

38-
public function mount()
46+
#[Url]
47+
public array $price_range = [500, 3000];
48+
49+
#[Url]
50+
public string $category = '';
51+
52+
#[Url]
53+
public string $type = '';
54+
55+
public function mount(): void
3956
{
4057
$this->form->fill([
4158
'from' => $this->from,
@@ -57,92 +74,8 @@ public function content(Schema $schema): Schema
5774
->get()->all())
5875
->columns(12)
5976
->components([
60-
Section::make('filters')
61-
->heading('Filters')
62-
->columnSpan(3)
63-
->description('Use the filters below to refine your search results.')
64-
->schema([
65-
// Add filter components here, e.g., TextInput, Select, etc.
66-
]),
67-
Section::make()
68-
->contained(false)
69-
->columnSpan(9)
70-
->schema([
71-
RepeatableEntry::make('*')
72-
->hiddenLabel()
73-
->contained(false)
74-
->extraAttributes(['class' => 'gap-4'])
75-
->schema([
76-
Section::make()
77-
->collapsible()
78-
->icon(fn (Route $record) => 'logo-' . $record->operator->logo)
79-
->iconSize('lg')
80-
->heading(fn (Route $record) => $record->operator->name)
81-
->description(fn (Route $record) => $record->departure_time->format('h:i A') . ' - ' . $record->arrival_time->format('h:i A'))
82-
->afterHeader([
83-
TextEntry::make('bus.category')
84-
->hiddenLabel()
85-
->badge()
86-
->color(fn (Route $record) => $record->bus->category?->getColor() ?? 'gray'),
87-
TextEntry::make('bus.type')
88-
->hiddenLabel()
89-
->badge()
90-
->color(fn (Route $record) => $record->bus->type?->getColor() ?? 'gray'),
91-
])
92-
->schema([
93-
TextEntry::make('bus.bus_number')
94-
->hiddenLabel()
95-
->label('Bus Number')
96-
->size('lg')
97-
->weight('bold'),
98-
Flex::make([
99-
TextEntry::make('origin_city')
100-
->hiddenLabel()
101-
->icon(LucideIcon::MapPin)
102-
->size('lg')
103-
->grow(false),
104-
View::make('filament.schemas.components.route-duration'),
105-
TextEntry::make('destination_city')
106-
->hiddenLabel()
107-
->icon(LucideIcon::MapPin)
108-
->size('lg')
109-
->grow(false),
110-
])->columnSpanFull(),
111-
Flex::make([
112-
TextEntry::make('departure_time')
113-
->hiddenLabel()
114-
->dateTime('h:i A, d M'),
115-
TextEntry::make('arrival_time')
116-
->hiddenLabel()
117-
->dateTime('h:i A, d M')
118-
->grow(false),
119-
])->columnSpanFull(),
120-
TextEntry::make('bus.seats_available')
121-
->hiddenLabel()
122-
->label('Seats Available')
123-
->color('success'),
124-
])
125-
->footer([
126-
Flex::make([
127-
TextEntry::make('bus.min_price')
128-
->hiddenLabel()
129-
->money('USD', 100)
130-
->color('primary')
131-
->size('lg')
132-
->weight('bold'),
133-
Action::make('book')
134-
->label('Book Now')
135-
->icon(LucideIcon::Ticket)
136-
->outlined()
137-
->url(fn (Route $record) => $record)
138-
->openUrlInNewTab()
139-
->button(),
140-
])->columnSpanFull()->extraAttributes([
141-
'class' => 'search-result-footer items-center',
142-
]),
143-
]),
144-
])
145-
]),
77+
$this->getSearchFiltersComponents(),
78+
$this->getSearchResultsComponents(),
14679
]);
14780
}
14881

@@ -177,7 +110,7 @@ public function form(Schema $schema): Schema
177110
]);
178111
}
179112

180-
public function search()
113+
public function search(): never
181114
{
182115
$this->validate([
183116
'from' => 'required|string|max:255',
@@ -187,22 +120,132 @@ public function search()
187120
]);
188121

189122
dd($this->from, $this->to, $this->date, $this->passengers);
190-
// You can replace this with actual search logic, such as querying a database or an API.
191-
// For example, you might want to redirect to a results page:
192-
// return redirect()->route('search.results', [
193-
// 'from' => $this->from,
194-
// 'to' => $this->to,
195-
// 'date' => $this->date,
196-
// 'passengers' => $this->passengers,
197-
// ]);
198-
199-
// For now, we will just dump the search parameters for demonstration purposes.
200-
// In a real application, you would replace this with actual search logic.
201-
return redirect()->route('filament.home.pages.search', [
202-
'from' => $this->from,
203-
'to' => $this->to,
204-
'date' => $this->date,
205-
'passengers' => $this->passengers,
206-
]);
207123
}
208-
}
124+
125+
private function getSearchFiltersComponents(): Component
126+
{
127+
return Section::make()
128+
->heading('Filters')
129+
->columnSpan(3)
130+
->description('Use the filters below to refine your search results.')
131+
->extraAttributes(['class' => 'sticky top-20'])
132+
->schema([
133+
Select::make('category')
134+
->label('Bus Category')
135+
->options(collect(BusCategory::cases())->mapWithKeys(fn (BusCategory $category) => [$category->value => $category->getLabel()]))
136+
->placeholder('Select a category')
137+
->searchable()
138+
->columnSpanFull(),
139+
Select::make('type')
140+
->label('Bus Type')
141+
->options(collect(BusType::cases())->mapWithKeys(fn (BusType $type) => [$type->value => $type->getLabel()]))
142+
->placeholder('Select a type')
143+
->searchable()
144+
->columnSpanFull(),
145+
Section::make()
146+
->columnSpanFull()
147+
->description('Price range')
148+
->contained(false)
149+
->schema([
150+
Slider::make('price_range')
151+
->hiddenLabel()
152+
->extraFieldWrapperAttributes(['class' => 'px-5'])
153+
->range(500, 3000)
154+
->step(50)
155+
->decimalPlaces(0)
156+
->default([500, 2000])
157+
->tooltips()
158+
->columnSpanFull(),
159+
]),
160+
CheckboxList::make('operators')
161+
->options(Operator::query()
162+
->orderBy('name')
163+
->get()
164+
->pluck('name', 'id'))
165+
->columnSpanFull(),
166+
]);
167+
}
168+
169+
private function getSearchResultsComponents(): Component
170+
{
171+
return Section::make()
172+
->contained(false)
173+
->columnSpan(9)
174+
->schema([
175+
RepeatableEntry::make('*')
176+
->hiddenLabel()
177+
->contained(false)
178+
->extraAttributes(['class' => 'gap-4'])
179+
->schema([
180+
Section::make()
181+
->collapsible()
182+
->icon(fn (Route $record): string => 'logo-' . $record->operator->logo)
183+
->iconSize('lg')
184+
->heading(fn (Route $record) => $record->operator->name)
185+
->description(fn (Route $record): string => $record->departure_time->format('h:i A') . ' - ' . $record->arrival_time->format('h:i A'))
186+
->afterHeader([
187+
TextEntry::make('bus.category')
188+
->hiddenLabel()
189+
->badge()
190+
->color(fn (Route $record) => $record->bus->category?->getColor() ?? 'gray'),
191+
TextEntry::make('bus.type')
192+
->hiddenLabel()
193+
->badge()
194+
->color(fn (Route $record) => $record->bus->type?->getColor() ?? 'gray'),
195+
])
196+
->schema([
197+
TextEntry::make('bus.bus_number')
198+
->hiddenLabel()
199+
->label('Bus Number')
200+
->size('lg')
201+
->weight('bold'),
202+
Flex::make([
203+
TextEntry::make('origin_city')
204+
->hiddenLabel()
205+
->icon(LucideIcon::MapPin)
206+
->size('lg')
207+
->grow(false),
208+
View::make('filament.schemas.components.route-duration'),
209+
TextEntry::make('destination_city')
210+
->hiddenLabel()
211+
->icon(LucideIcon::MapPin)
212+
->size('lg')
213+
->grow(false),
214+
])->columnSpanFull(),
215+
Flex::make([
216+
TextEntry::make('departure_time')
217+
->hiddenLabel()
218+
->dateTime('h:i A, d M'),
219+
TextEntry::make('arrival_time')
220+
->hiddenLabel()
221+
->dateTime('h:i A, d M')
222+
->grow(false),
223+
])->columnSpanFull(),
224+
TextEntry::make('bus.seats_available')
225+
->hiddenLabel()
226+
->label('Seats Available')
227+
->color('success'),
228+
])
229+
->footer([
230+
Flex::make([
231+
TextEntry::make('bus.min_price')
232+
->hiddenLabel()
233+
->money('USD', 100)
234+
->color('primary')
235+
->size('lg')
236+
->weight('bold'),
237+
Action::make('book')
238+
->label('Book Now')
239+
->icon(LucideIcon::Ticket)
240+
->outlined()
241+
->url(fn (Route $record): Route => $record)
242+
->openUrlInNewTab()
243+
->button(),
244+
])->columnSpanFull()->extraAttributes([
245+
'class' => 'search-result-footer items-center',
246+
]),
247+
]),
248+
]),
249+
]);
250+
}
251+
}

app/Filament/Operator/Resources/Buses/Pages/CreateBus.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\ValueObjects\SeatConfiguration;
77
use Filament\Resources\Pages\CreateRecord;
88
use Illuminate\Support\Facades\Auth;
9+
use InvalidArgumentException;
910

1011
class CreateBus extends CreateRecord
1112
{
@@ -15,35 +16,35 @@ protected function mutateFormDataBeforeCreate(array $data): array
1516
{
1617
// Set the operator_id from the authenticated user's first operator
1718
$data['operator_id'] = Auth::user()->operators()->first()?->id;
18-
19+
1920
// Process seat configuration data only if seat configuration fields are provided
2021
$seatConfigFields = ['deck', 'seat_type', 'total_columns', 'column_label', 'column_layout', 'total_rows', 'row_label', 'price_per_seat'];
2122
$hasSeatConfigData = array_intersect_key($data, array_flip($seatConfigFields));
22-
23-
if (!empty($hasSeatConfigData)) {
23+
24+
if ($hasSeatConfigData !== []) {
2425
try {
2526
$seatConfig = SeatConfiguration::fromFormData($data);
2627
$data['seat_config'] = $seatConfig;
27-
28+
2829
// Ensure total_seats matches the calculated seats from configuration
2930
$calculatedSeats = $seatConfig->getTotalSeats();
3031
$data['total_seats'] = $calculatedSeats;
31-
} catch (\InvalidArgumentException $e) {
32+
} catch (InvalidArgumentException $e) {
3233
// Log the error and let validation handle it
3334
logger()->error('Invalid seat configuration data', [
3435
'data' => $data,
3536
'error' => $e->getMessage(),
3637
]);
3738
}
38-
39+
3940
// Remove form-only fields that shouldn't be stored in the database
4041
$formOnlyFields = [
4142
'deck', 'seat_type', 'total_columns', 'column_label', 'column_layout',
4243
'total_rows', 'row_label', 'price_per_seat',
4344
'seat_type_upper', 'total_columns_upper', 'column_label_upper',
44-
'column_layout_upper', 'total_rows_upper', 'row_label_upper', 'price_per_seat_upper'
45+
'column_layout_upper', 'total_rows_upper', 'row_label_upper', 'price_per_seat_upper',
4546
];
46-
47+
4748
foreach ($formOnlyFields as $field) {
4849
unset($data[$field]);
4950
}

0 commit comments

Comments
 (0)