diff --git a/app/Filament/Resources/Events/Tables/EventsTable.php b/app/Filament/Resources/Events/Tables/EventsTable.php index 8a220155..5c9f51e9 100644 --- a/app/Filament/Resources/Events/Tables/EventsTable.php +++ b/app/Filament/Resources/Events/Tables/EventsTable.php @@ -68,6 +68,7 @@ class EventsTable ->poll('10s') ->deferLoading() ->defaultPaginationPageOption(5) + ->extremePaginationLinks() ->paginated([5, 10, 15]) ->columns([ IconColumn::make('sport.icon') diff --git a/app/Filament/Resources/Users/Schemas/UserForm.php b/app/Filament/Resources/Users/Schemas/UserForm.php index ff47ba8b..021453e3 100644 --- a/app/Filament/Resources/Users/Schemas/UserForm.php +++ b/app/Filament/Resources/Users/Schemas/UserForm.php @@ -3,7 +3,6 @@ namespace App\Filament\Resources\Users\Schemas; use App\Models\Bookmaker; -use App\Models\Client; use Filament\Forms\Components\Hidden; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; @@ -55,21 +54,16 @@ class UserForm Select::make('client_id') ->relationship('client', 'name') ->preload(), - + Select::make('provider_id') + ->relationship('provider', 'name') + ->preload(), Select::make('bookmaker_id') ->label('Active Bookmaker') ->options(fn () => Bookmaker::query()->where('is_client', 1)->pluck('name', 'id')) ->preload(), Select::make('partner_bookmaker_id') ->label('Partner Bookmaker') - ->options(function () { - $bookmaker = Client::where('id', auth()->user()->client_id)->value('bookmaker'); - - return Bookmaker::query()->whereIn('id', $bookmaker)->pluck('name', 'id'); - }) - ->preload(), - Select::make('provider_id') - ->relationship('provider', 'name') + ->options(fn () => Bookmaker::query()->where('is_client', 1)->pluck('name', 'id')) ->preload(), ]), Section::make('Authorisations') diff --git a/app/Livewire/AlarmBookmaker.php b/app/Livewire/AlarmBookmaker.php index 6b5f9154..c91b2c5f 100644 --- a/app/Livewire/AlarmBookmaker.php +++ b/app/Livewire/AlarmBookmaker.php @@ -50,22 +50,22 @@ class AlarmBookmaker extends Component implements HasActions, HasSchemas, HasTab ->where('sport_id', auth()->user()->sport_id)) ->paginated(false) ->columns([ - IconColumn::make('sport.icon') - ->label('') - ->width('1rem') - ->icon(function ($record): string { - return $record->sport->icon; - }) - ->color(fn ($record): string => match ($record->level_id) { - 1 => 'success', - 2 => 'warning', - 3 => 'danger', - }), - TextColumn::make('sport.name'), - TextColumn::make('multiline_setting.name')->label('Bettype'), + // IconColumn::make('sport.icon') + // ->label('') + // ->width('1rem') + // ->icon(function ($record): string { + // return $record->sport->icon; + // }) + // ->color(fn ($record): string => match ($record->level_id) { + // 1 => 'success', + // 2 => 'warning', + // 3 => 'danger', + // }), + // TextColumn::make('sport.name'), TextColumn::make('name') + ->badge() ->color(fn ($record): string => match ($record->level_id) { - 1 => 'success', + 1 => 'info', 2 => 'warning', 3 => 'danger', }), @@ -74,6 +74,7 @@ class AlarmBookmaker extends Component implements HasActions, HasSchemas, HasTab ->width('2rem') ->prefix('Threshold:') ->rules(['required', 'decimal:2', 'between:0,2']), + TextColumn::make('multiline_setting.name')->label('Bettype'), ToggleColumn::make('disabled'), ]) ->defaultSort('level_id') diff --git a/app/Livewire/ComparingBookmakerMenu.php b/app/Livewire/ComparingBookmakerMenu.php index c5a14c66..7ca1fc7d 100644 --- a/app/Livewire/ComparingBookmakerMenu.php +++ b/app/Livewire/ComparingBookmakerMenu.php @@ -48,7 +48,6 @@ class ComparingBookmakerMenu extends Component implements HasActions, HasSchemas ->reorderRecordsTriggerAction(function (Action $action) { return $action->button(); }) - ->paginated(false) ->striped() ->query(ComparingBookmaker::query() ->with('bookmaker') @@ -56,8 +55,10 @@ class ComparingBookmakerMenu extends Component implements HasActions, HasSchemas ->where('client_bookmaker_id', $this->user->bookmaker_id) ->orderBy('sorting') ) + ->deferLoading() ->defaultPaginationPageOption(10) ->paginated([5, 10, 15, 30, 50]) + ->extremePaginationLinks() ->columns([ TextColumn::make('Position') ->alignCenter() diff --git a/app/Livewire/MapperLeft.php b/app/Livewire/MapperLeft.php index 3699b63c..35e850b5 100644 --- a/app/Livewire/MapperLeft.php +++ b/app/Livewire/MapperLeft.php @@ -10,6 +10,7 @@ use App\Models\Country; use App\Models\Event; use App\Models\Mapper; use Carbon\Carbon; +use CodeWithKyrian\FilamentDateRange\Forms\Components\DateRangePicker; use Filament\Actions\Action; use Filament\Actions\Concerns\InteractsWithActions; use Filament\Actions\Contracts\HasActions; @@ -18,7 +19,10 @@ use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Concerns\InteractsWithSchemas; use Filament\Schemas\Contracts\HasSchemas; use Filament\Support\Enums\Alignment; +use Filament\Support\Enums\FontWeight; use Filament\Support\Enums\Size; +use Filament\Tables\Columns\IconColumn; +use Filament\Tables\Columns\TextColumn; use Filament\Tables\Concerns\InteractsWithTable; use Filament\Tables\Contracts\HasTable; use Filament\Tables\Enums\FiltersLayout; @@ -68,10 +72,74 @@ class MapperLeft extends Component implements HasActions, HasSchemas, HasTable return $table ->query(LoadEvents::load($this->search_left, auth()->user()->sport_id)) ->columns([ + TextColumn::make('starttime') + ->sortable() + ->time('H:i') + ->alignCenter() + ->description(fn ($record): string => Carbon::parse($record->starttime)->format('d. M. y')), + IconColumn::make('country.icon')->icon(fn (string $state): string => $state)->label(''), + TextColumn::make('competition_group.name')->label('Group') + ->wrap() + ->tooltip('Click to filter by this group') + ->description(fn ($record): string => $record->country->name) + ->action(function ($record) { + if (! in_array($record->competition_group_id, $this->tableFilters['events']['competition_group_id'])) { + $this->tableFilters['events']['competition_group_id'][] = (string) $record->competition_group_id; + $this->dispatch('refreshMapperRight'); + } + }), + TextColumn::make('home.name') + ->label('Home') + ->color('home') + ->weight(FontWeight::Bold) + ->alignRight(), + IconColumn::make('id')->icon('phosphor-minus')->label('')->color('black'), + TextColumn::make('away.name') + ->color('away') + ->label('Away') + ->weight(FontWeight::Bold), MapperLeftColumn::make('left')->label(''), + ])->recordActions([ + Action::make('search_home') + ->iconButton() + ->icon('phosphor-magnifying-glass') + ->color('home') + ->action(function ($record) { + $this->dispatch('search_right', $record->home->name); + }), + Action::make('search_away') + ->icon('phosphor-magnifying-glass') + ->iconButton() + ->color('away') + ->action(function ($record) { + $this->dispatch('search_right', $record->away->name); + }), + // Action::make('drag_left') + // ->icon('phosphor-arrows-out') + // ->iconButton() + // ->extraAttributes([ + // 'x-data' => '{ moveoverleft: false }', + // 'x-on' => '{ + // dragstart = { + // self: dragging = true; + // event.dataTransfer.effectAllowed = "move; + // event.dataTransfer.setData("text/plain", event.target.id) + // }, + // dragover = { + // prevent: "moveoverleft = true" + // }, + // dragleave = { + // prevent: "moveoverleft = false" + // } + // }', + // ]) + // ->action(function ($record) { + // $this->dispatch('search_right', $record->away->name); + // }), ]) + ->defaultSort('starttime') ->searchable(['home.name', 'away.name']) - ->defaultPaginationPageOption(5) + ->defaultPaginationPageOption(10) ->filters([ Filter::make('events') ->schema([ @@ -79,7 +147,6 @@ class MapperLeft extends Component implements HasActions, HasSchemas, HasTable ->placeholder('Country') ->hiddenLabel() // ->multiple() - ->columnSpan(2) ->searchable() ->preload() ->options(function () { @@ -96,31 +163,25 @@ class MapperLeft extends Component implements HasActions, HasSchemas, HasTable ->placeholder('League') ->hiddenLabel() ->label('') - ->columnSpan(2) ->multiple() ->searchable() ->options(function (Get $get) { - if ($get('country_id')) { - $res = Event::query()->where('sport_id', auth()->user()->sport_id)->where('betradar_id', 0)->where('starttime', '>', Carbon::now())->where('country_id', $get('country_id'))->groupBy('competition_group_id')->pluck('competition_group_id')->toArray(); - } else { - $res = Event::query()->where('sport_id', auth()->user()->sport_id)->where('betradar_id', 0)->where('starttime', '>', Carbon::now())->groupBy('competition_group_id')->pluck('competition_group_id')->toArray(); - } - - $comps = CompetitionGroup::with('country')->where('id', $res)->get(); - - $arr = []; - foreach ($comps as $val) { - if (isset($val->country->name)) { - $arr[$val->id] = $val->country->name.' - '.$val->name; - } else { - $arr[$val->id] = $val->name; - } - } - asort($arr); - - return $arr; + return CompetitionGroup::where('sport_id', auth()->user()->sport_id) + ->whereHas('event', function ($query) { + $query->where('starttime', '>', now()) + ->where('betradar_id', 0); + }) + ->orderBy('name') + ->pluck('name', 'id'); }) ->live(), + DateRangePicker::make('starttime_period') + ->columnSpan(2) + ->displayFormat('d M Y') + ->minDate(now()) + ->hiddenLabel() + ->label('') + ->live(), ]) ->query(function (Builder $query, array $data): Builder { return $query @@ -129,8 +190,36 @@ class MapperLeft extends Component implements HasActions, HasSchemas, HasTable fn (Builder $query, $country_id) => $query->where('country_id', $country_id) )->when( $data['competition_group_id'], - fn (Builder $query, $competition_group_id) => $query->whereIn('competition_group_id', $competition_group_id) - ); + function (Builder $query, $competition_group_id) { + $this->setPage(1); + + return $query->whereIn('competition_group_id', $competition_group_id); + } + )->when( + $data['starttime_period'], + function (Builder $query, $starttime_period) { + + // dd($starttime_period); + + if (isset($starttime_period['start']) && isset($starttime_period['end'])) { + $from = Carbon::createFromDate($starttime_period['start']); + $end = Carbon::createFromDate($starttime_period['end']); + + return $query + ->whereDate('starttime', '>=', $from->format('Y-m-d 00:00:00')) + ->whereDate('starttime', '<=', $end->format('Y-m-d 00:00:00')); + } elseif (isset($starttime_period['start'])) { + $from = Carbon::createFromDate($starttime_period['start']); + + return $query + ->whereDate('starttime', '>=', $from->format('Y-m-d 00:00:00')); + } elseif (isset($starttime_period['end'])) { + $end = Carbon::createFromDate($starttime_period['end']); + + return $query + ->whereDate('starttime', '<=', $end->format('Y-m-d 00:00:00')); + } + }); })->indicateUsing(function (): array { $indicators = []; if ($this->search_left) { @@ -150,6 +239,7 @@ class MapperLeft extends Component implements HasActions, HasSchemas, HasTable ->toolbarActions([ Action::make('refreshMapperLeft') ->hiddenLabel() + ->color('gray') ->icon('phosphor-x') ->size(Size::Small) ->action(function (Component $livewire) { diff --git a/app/Livewire/MapperRight.php b/app/Livewire/MapperRight.php index d144e5e0..0a17eb62 100644 --- a/app/Livewire/MapperRight.php +++ b/app/Livewire/MapperRight.php @@ -8,6 +8,7 @@ use App\Livewire\Mapper\StoreMapped; use App\Models\Country; use App\Models\Event; use App\Models\Mapper; +use CodeWithKyrian\FilamentDateRange\Forms\Components\DateRangePicker; use Filament\Actions\Action; use Filament\Actions\Concerns\InteractsWithActions; use Filament\Actions\Contracts\HasActions; @@ -16,10 +17,14 @@ use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Concerns\InteractsWithSchemas; use Filament\Schemas\Contracts\HasSchemas; use Filament\Support\Enums\Alignment; +use Filament\Support\Enums\FontWeight; use Filament\Support\Enums\Size; +use Filament\Tables\Columns\IconColumn; +use Filament\Tables\Columns\TextColumn; use Filament\Tables\Concerns\InteractsWithTable; use Filament\Tables\Contracts\HasTable; use Filament\Tables\Enums\FiltersLayout; +use Filament\Tables\Enums\RecordActionsPosition; use Filament\Tables\Filters\Filter; use Filament\Tables\Filters\Indicator; use Filament\Tables\Table; @@ -67,8 +72,47 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable ->query(LoadProvider::load($this->search_right, auth()->user())) ->columns([ MapperRightColumn::make('right')->label(''), + TextColumn::make('home') + ->color('home') + ->weight(FontWeight::Bold) + ->alignRight(), + IconColumn::make('id')->icon('phosphor-minus')->label('')->color('black'), + TextColumn::make('away') + ->color('away') + ->weight(FontWeight::Bold), + TextColumn::make('group') + ->wrap() + ->tooltip('Click to filter by this group') + ->description(fn ($record): string => $record->country_betsapi?->name.' '.$record->country) + ->action(function ($record) { + if (! in_array($record->group_id, $this->tableFilters['events']['group_id'])) { + $this->tableFilters['events']['group_id'][] = (string) $record->group_id; + $this->dispatch('refreshMapperRight'); + } + }), + IconColumn::make('group_cc')->icon(fn (string $state): string => 'flag-country-'.$state)->label(''), + TextColumn::make('starttime') + ->sortable() + ->time('H:i') + ->alignCenter() + ->description(fn ($record): string => Carbon::parse($record->starttime)->format('d. M. y')), ])->searchable(['home', 'away']) - ->defaultPaginationPageOption(5) + ->recordActions([ + Action::make('search_home') + ->iconButton() + ->icon('phosphor-magnifying-glass') + ->color('home') + ->action(function ($record) { + $this->dispatch('search_left', $record->home); + }), + Action::make('search_away') + ->icon('phosphor-magnifying-glass') + ->iconButton() + ->color('away') + ->action(function ($record) { + $this->dispatch('search_left', $record->away); + }), + ], position: RecordActionsPosition::BeforeColumns) ->filters([ Filter::make('events') ->schema([ @@ -80,7 +124,6 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable ->searchable() ->preload() // ->multiple() - ->columnSpan(2) ->live() ->options(function (Get $get) { return Mapper::query()->where('sport_id', auth()->user()->sport_id)->where('provider_id', auth()->user()->provider_id)->where('starttime', '>', Carbon::now())->groupBy('country_id')->pluck('country', 'country_id')->toArray(); @@ -98,7 +141,6 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable ->searchable() ->preload() // ->multiple() - ->columnSpan(2) ->live() ->options(function () { $res = Mapper::query()->where('sport_id', auth()->user()->sport_id)->where('provider_id', auth()->user()->provider_id)->where('starttime', '>', Carbon::now())->groupBy('group_cc')->pluck('group_cc')->toArray(); @@ -115,7 +157,6 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable ->label('Leagues') ->hiddenLabel() ->label('') - ->columnSpan(2) ->searchable() ->preload() ->multiple() @@ -129,6 +170,13 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable } }) ->live(), + DateRangePicker::make('starttime_period') + ->columnSpan(2) + ->displayFormat('d M Y') + ->minDate(now()) + ->hiddenLabel() + ->label('') + ->live(), ]) ->query(function (Builder $query, array $data): Builder { return $query @@ -140,8 +188,36 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable fn (Builder $query, $group_cc) => $query->where('group_cc', $group_cc) )->when( $data['group_id'], - fn (Builder $query, $group_id) => $query->whereIn('group_id', $group_id) - ); + function (Builder $query, $group_id) { + $this->setPage(1); + + return $query->whereIn('group_id', $group_id); + } + )->when( + $data['starttime_period'], + function (Builder $query, $starttime_period) { + + // dd($starttime_period); + + if (isset($starttime_period['start']) && isset($starttime_period['end'])) { + $from = Carbon::createFromDate($starttime_period['start']); + $end = Carbon::createFromDate($starttime_period['end']); + + return $query + ->whereDate('starttime', '>=', $from->format('Y-m-d 00:00:00')) + ->whereDate('starttime', '<=', $end->format('Y-m-d 00:00:00')); + } elseif (isset($starttime_period['start'])) { + $from = Carbon::createFromDate($starttime_period['start']); + + return $query + ->whereDate('starttime', '>=', $from->format('Y-m-d 00:00:00')); + } elseif (isset($starttime_period['end'])) { + $end = Carbon::createFromDate($starttime_period['end']); + + return $query + ->whereDate('starttime', '<=', $end->format('Y-m-d 00:00:00')); + } + }); })->indicateUsing(function (): array { $indicators = []; if ($this->search_right) { @@ -154,14 +230,19 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable return $indicators; }) ->columns(4)->columnSpan(4), + ], layout: FiltersLayout::AboveContent) + // IconColumn::make('search_home')->icon('phosphor-magnifying-magnifying')->label('')->color('home')->width(30), + // IconColumn::make('search_away')->icon('phosphor-magnifying-glass')->label('')->color('away')->width(30), // ->hiddenFilterIndicators() + ->defaultPaginationPageOption(10) ->persistFiltersInSession() ->filtersFormColumns(3) ->deferFilters(false) ->toolbarActions([ Action::make('refreshMapperRight') ->hiddenLabel() + ->color('gray') ->icon('phosphor-x') ->size(Size::Small) ->action(function (Component $livewire) { @@ -170,7 +251,7 @@ class MapperRight extends Component implements HasActions, HasSchemas, HasTable $livewire->fill(['tableSearch' => '']); $livewire->resetTableFiltersForm(); // Clears all filters $this->dispatch('refreshMapperRight'); - $this->dispatch('refreshMapperLeft'); + // $this->dispatch('refreshMapperLeft'); }), ]); } diff --git a/app/Models/CompetitionGroup.php b/app/Models/CompetitionGroup.php index 47543865..ade56cde 100644 --- a/app/Models/CompetitionGroup.php +++ b/app/Models/CompetitionGroup.php @@ -14,6 +14,11 @@ class CompetitionGroup extends Model 'level', ]; + public function event() + { + return $this->belongsTo(Event::class, 'id', 'competition_group_id'); + } + public function sport() { return $this->belongsTo(Sport::class); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 30591f70..338f7678 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -76,6 +76,10 @@ class AppServiceProvider extends ServiceProvider // break; // } // }); + FilamentColor::register([ + 'home' => Color::Sky, + 'away' => Color::Lime, + ]); // FilamentColor::register([ // 'danger' => Color::Red, diff --git a/composer.lock b/composer.lock index fbc76bd3..4c68483a 100644 --- a/composer.lock +++ b/composer.lock @@ -543,16 +543,16 @@ }, { "name": "brick/math", - "version": "0.14.4", + "version": "0.14.5", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "a8b53e6cc4d3a336543f042a4dfa0e3f2f2356a4" + "reference": "618a8077b3c326045e10d5788ed713b341fcfe40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/a8b53e6cc4d3a336543f042a4dfa0e3f2f2356a4", - "reference": "a8b53e6cc4d3a336543f042a4dfa0e3f2f2356a4", + "url": "https://api.github.com/repos/brick/math/zipball/618a8077b3c326045e10d5788ed713b341fcfe40", + "reference": "618a8077b3c326045e10d5788ed713b341fcfe40", "shasum": "" }, "require": { @@ -591,7 +591,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.4" + "source": "https://github.com/brick/math/tree/0.14.5" }, "funding": [ { @@ -599,7 +599,7 @@ "type": "github" } ], - "time": "2026-02-02T16:57:31+00:00" + "time": "2026-02-03T18:06:51+00:00" }, { "name": "carbonphp/carbon-doctrine-types", @@ -4579,16 +4579,16 @@ }, { "name": "nette/utils", - "version": "v4.1.1", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72" + "reference": "f76b5dc3d6c6d3043c8d937df2698515b99cbaf5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/c99059c0315591f1a0db7ad6002000288ab8dc72", - "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72", + "url": "https://api.github.com/repos/nette/utils/zipball/f76b5dc3d6c6d3043c8d937df2698515b99cbaf5", + "reference": "f76b5dc3d6c6d3043c8d937df2698515b99cbaf5", "shasum": "" }, "require": { @@ -4601,7 +4601,7 @@ "require-dev": { "jetbrains/phpstorm-attributes": "^1.2", "nette/tester": "^2.5", - "phpstan/phpstan-nette": "^2.0@stable", + "phpstan/phpstan": "^2.0@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -4662,9 +4662,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.1.1" + "source": "https://github.com/nette/utils/tree/v4.1.2" }, - "time": "2025-12-22T12:14:32+00:00" + "time": "2026-02-03T17:21:09+00:00" }, { "name": "nikic/php-parser", @@ -12982,12 +12982,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.3" }, - "platform-dev": [], - "plugin-api-version": "2.6.0" + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/database/seeders/RolesAndPermissionsSeeder.php b/database/seeders/RolesAndPermissionsSeeder.php index 8dc348b4..4cbdd6a5 100644 --- a/database/seeders/RolesAndPermissionsSeeder.php +++ b/database/seeders/RolesAndPermissionsSeeder.php @@ -75,7 +75,7 @@ class RolesAndPermissionsSeeder extends Seeder 'client_id' => 2, 'sport_id' => 1, 'bookmaker_id' => 35, - 'partner_bookmaker_id' => 34, + 'partner_bookmaker_id' => 36, 'provider_id' => 5, ]); $user->assignRole('regular_user'); diff --git a/resources/views/filament/tables/columns/mapper-left-column.blade.php b/resources/views/filament/tables/columns/mapper-left-column.blade.php index 2c709cdb..e0f8bd09 100644 --- a/resources/views/filament/tables/columns/mapper-left-column.blade.php +++ b/resources/views/filament/tables/columns/mapper-left-column.blade.php @@ -1,5 +1,4 @@ -