22
33namespace App \Filament \Home \Pages ;
44
5+ use App \Enums \BusCategory ;
6+ use App \Enums \BusType ;
7+ use App \Models \Operator ;
58use App \Models \Route ;
69use CodeWithDennis \FilamentLucideIcons \Enums \LucideIcon ;
710use Filament \Actions \Action ;
11+ use Filament \Forms \Components \CheckboxList ;
812use Filament \Forms \Components \DatePicker ;
913use Filament \Forms \Components \Select ;
14+ use Filament \Forms \Components \Slider ;
1015use Filament \Forms \Components \TextInput ;
1116use Filament \Infolists \Components \RepeatableEntry ;
1217use Filament \Infolists \Components \TextEntry ;
1318use Filament \Pages \Page ;
14- use Filament \Schemas \Components \Fieldset ;
19+ use Filament \Schemas \Components \Component ;
1520use Filament \Schemas \Components \Flex ;
1621use Filament \Schemas \Components \Section ;
1722use 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+ }
0 commit comments