query( Item::where('can_be_loaned', true)->whereIn('type', ["game", "literature"])) ->emptyStateHeading(__('No results')) ->searchable(true) ->columns([ Grid::make() ->columns(1) ->schema([ Stack::make([ TextColumn::make('reserved') ->weight(FontWeight::Bold) ->formatStateUsing(fn (string $state): string => $state ? __('On loan') : __('Available')) ->color(fn($record) => $record->reserved ? 'danger' : 'success' ) ->badge(), ImageColumn::make('image') ->label(__('Image')) ->disk('public') ->size('100%') ->extraImgAttributes([ 'class' => 'reserve-card-image', 'loading' => 'lazy' ]), //->visibility('private'), TextColumn::make('desc') ->label(__('Description')) ->sortable() ->searchable() ->weight(FontWeight::Bold) ->size(TextSize::Large), Stack::make([ TextColumn::make('players') ->label(__('Players')) ->default(__('No information')) ->sortable() ->prefix(__('Players') . ': '), //->suffix(' st'), TextColumn::make('play_time') ->label(__('Play time')) ->sortable() ->default(__('No information')) ->prefix(__('Play time (min)') . ': '), //->suffix(' min'), TextColumn::make('age') ->label(__('Age')) ->sortable() ->default(__('No information')) ->prefix(__('Age') . ': ') //->suffix(' år'), ]) ->extraAttributes(['class' => 'reserve-card-meta']) ->hidden(fn ($record) => $record->type === 'literature'), ])->extraAttributes(['class' => 'reserve-card']) ]) ]) //->defaultSort('desc', 'asc') ->defaultSort(function (Builder $query): Builder { return $query ->orderBy('reserved', 'asc') ->orderBy('desc', 'asc'); }) ->defaultPaginationPageOption(12) ->paginated([12, 25, 50, 100, 'all']) ->contentGrid([ 'sm' => 2, 'md' => 3, 'xl' => 4, ]) ->filters([ Filter::make('filters') ->form([ Select::make('type') ->label(__('Type')) ->live() ->options([ 'game' => __('Game'), 'literature' => __('Literature') ]), Select::make('category_id') ->multiple() ->label(__('Category literature')) ->options(Category::all()->whereIn('type', 'literature')->pluck('name', 'id')) ->hidden(fn ($get): string => $get('type') == 'game' || $get('type') == ''), Select::make('category_id') ->multiple() ->label(__('Category games')) ->options(Category::all()->whereIn('type', 'game')->pluck('name', 'id')) ->hidden(fn ($get): string => $get('type') == 'literature' || $get('type') == ''), ]) ->query(function (Builder $query, array $data): Builder { return $query ->when( $data['type'], fn (Builder $query, $type): Builder => $query->where('type', $type), ) ->when( $data['category_id'], fn (Builder $query, $category_id): Builder => $query->whereIn('category_id', $category_id), ); }) ->columns([ 'deafult' => 1, 'md' => 2, ]) ->columnSpan(2), Filter::make('reserved') ->label(__('Available')) ->query(fn (Builder $query): Builder => $query->where('reserved', false)) ->columnSpanFull() ->toggle() ],layout: FiltersLayout::AboveContent) ->actions([ Action::make('reserve') ->label(__('Reserve')) ->button() ->color('primary') ->form([ TextInput::make('username') ->label(__('Name')) ->required(), TextInput::make('email') ->label(__('Email')) ->email() ->required(), TextInput::make('phone') ->label(__('Phone')) ->tel() ->required(), Checkbox::make('gdpr') ->label(__('By checking this box you agree that we store your email address and phone number.')) ->accepted(), ]) ->action(function (array $data, Item $record): void { $reservation = Reserveditem::create([ 'item_id' => $record->id, 'reserved_date' => Carbon::now(), 'username' => $data['username'], 'email' => $data['email'], 'phone' => $data['phone'] ]); Item::where('id', $record->id)->update(['reserved' => true]); // The reservation is already saved, so a mail failure must never // take down the response for the visitor. $mailSent = true; try { Mail::to($data['email']) ->send(new ReservationCreatedUser($reservation)); } catch (Throwable $exception) { $mailSent = false; Log::error('Could not send reservation email to the visitor: ' . $exception->getMessage(), [ 'reservation_id' => $reservation->id, ]); } if ($adminAddress = config('mail.to_address')) { try { Mail::to($adminAddress) ->send(new ReservationCreated($reservation)); } catch (Throwable $exception) { Log::error('Could not send reservation email to staff: ' . $exception->getMessage(), [ 'reservation_id' => $reservation->id, ]); } } else { Log::warning('mail.to_address is not set, no reservation email sent to staff.', [ 'reservation_id' => $reservation->id, ]); } Notification::make() ->title(__('The game is reserved!')) ->body($mailSent ? __('A confirmation email has been sent to the address you provided. Read it for more information about collecting the game.') : __('We could not send a confirmation email, but your reservation is registered and we will contact you.')) ->success() ->seconds(10) ->send(); }) ->hidden(fn ($record) => $record->reserved), Action::make('More info') ->translateLabel() ->modalSubmitAction(false) ->infolist([ Section::make('') ->schema([ ImageEntry::make('image') ->translateLabel() ->disk('public') ->width(300) ->height('auto'), TextEntry::make('desc') ->label('Description') ->translateLabel(), TextEntry::make('category.name') ->translateLabel(), TextEntry::make('players') ->translateLabel(), TextEntry::make('play_time') ->translateLabel(), TextEntry::make('age') ->translateLabel(), ]) ->columns() ->hidden(fn ($record) => $record->type === 'literature'), Section::make('') ->translateLabel() ->schema([ ImageEntry::make('image') ->translateLabel() ->disk('public'), TextEntry::make('desc') ->label('Description') ->translateLabel(), TextEntry::make('category.name') ->translateLabel(), ]) ->columns() ->hidden(fn ($record) => $record->type === "game"), ]), ]) ->bulkActions([ ]); } }