2, 'xl' => 3, ]; public function resetFilters(): void { $filters = array_keys($this->filters); foreach ($filters as $filter) { switch ($filter) { case 'accuracy': $this->filters[$filter] = 0.125; break; case 'similar_past_matches': $this->filters[$filter] = 'none'; break; case 'team_position': $this->filters[$filter] = 'all'; break; case 'statistic_type': $this->filters[$filter] = 'gls'; break; case 'season_or_date': $this->filters[$filter] = 'season'; break; default: $this->filters[$filter] = null; break; } } } public function getHeading(): string|Htmlable|null { return ''; } /** * Diese Methode liefert das Daten-Array für ALLE Widgets. * Durch 'once()' läuft die Query pro Request exakt 1x. */ // public function getSharedWidgetData(): array // { // return once(function () { // $filters = $this->getFilters(); // // Ihre MongoDB / Eloquent Query basierend auf den aktuellen Filtern // return Order::query() // ->when($filters['start_date'] ?? null, fn ($q, $date) => $q->where('created_at', '>=', $date)) // ->when($filters['status'] ?? null, fn ($q, $status) => $q->where('status', $status)) // ->selectRaw('count(*) as total_count, sum(total_price) as total_revenue, avg(total_price) as average_amount') // ->first() // ->toArray(); // }); // } // // Im Widget -> Nutzt exakt dasselbe Array aus dem Speicher // $sharedData = $this->getPage()->getSharedWidgetData(); public function filtersForm(Schema $schema): Schema { return $schema ->components([ // change sport TODO // ToggleButtons::make('status') // ->columnSpanFull() // ->hiddenLabel() // ->inline() // ->default(1) // ->options([ // '1' => 'Soccer', // '3' => 'Basketball', // '2' => 'Ice Hockey', // '5' => 'Tennis', // ]) // ->icons([ // '1' => 'icon-soccerball', // '3' => 'icon-basketball', // '2' => 'icon-icehockey', // '5' => 'icon-tennisball', // ]), Grid::make([ 'default' => 1, 'sm' => 2, 'md' => 6, ]) ->columnSpanFull() ->schema([ Hidden::make('seasonmode'), $this->selectSofascoreCategoryId(), $this->selectLeagueId(), $this->selectMatchId(), $this->selectTeamId(), $this->selectTeamPosition(), Actions::make([ Action::make('esc') ->hiddenLabel() ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') ->tooltip('Clear All (esc)') ->icon('phosphor-x') ->color('gray') ->keyBindings(['esc']) ->outlined() ->action('resetFilters'), Action::make('copy') ->hiddenLabel() ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') ->visible(fn (Get $get) => $get('team_id')) ->tooltip('Copy data for pasting into spreadsheet') ->color('success') ->outlined() ->icon('phosphor-copy') ->action(function ($livewire) { // 1. Call your custom Livewire function to generate the data $dataToCopy = $livewire->generateDynamicPayload(); $this->js("navigator.clipboard.writeText(`$dataToCopy`)"); // 3. Send a helpful Filament Toast notification to the UI Notification::make() ->title('Copied to clipboard!') ->success() ->send(); }), ]), ]), Grid::make([ 'default' => 1, 'sm' => 3, 'md' => 4, ]) ->columnSpanFull() ->schema([ $this->selectStatisticType(), $this->selectSimilarPastMatches(), $this->sliderAccuracy(), $this->selectPlayerId(), $this->selectPlayerOnField(), ]), Grid::make([ 'default' => 8, 'sm' => 8, ]) ->columnSpanFull() ->schema([ $this->radioSeasonOrDate(), $this->selectSeason(), $this->datePickerStartDate(), $this->datePickerEndDate(), ]), ]); } /** * Summary of generateDynamicPayload */ public function generateDynamicPayload(): string { $data = LoadEventsBoxes::load($this->filters, false); $header = ['Team', 'Event', 'Odd 1', 'Odd X', 'Odd 2', 'Category', 'EXP H', 'EXP A', 'AGV+', 'AGV-', 'AGV Team Season H', 'AGV Team Season A', 'AGV League H', 'AGV League A']; $copystring = implode(';', $header)."\n"; $row = []; $row[] = $data['active_team']; $row[] = $data['count_events']; $row[] = $data['win_odd']; $row[] = $data['draw_odd']; $row[] = $data['lost_odd']; $row[] = 'Goals'; $row[] = $data['gls']['home']; $row[] = $data['gls']['away']; $row[] = $data['gls_team']['home']; $row[] = $data['gls_team']['away']; $row[] = $data['gls_team_season']['home']; $row[] = $data['gls_team_season']['away']; $row[] = $data['gls_liga_season']['home']; $row[] = $data['gls_liga_season']['away']; $copystring .= implode(';', $row)."\n"; $row = []; $row = array_fill(0, 5, ''); $row[] = 'Fouls'; $row[] = $data['fls']['home']; $row[] = $data['fls']['away']; $row[] = $data['fls_team']['home']; $row[] = $data['fls_team']['away']; $row[] = $data['fls_team_season']['home']; $row[] = $data['fls_team_season']['away']; $row[] = $data['fls_liga_season']['home']; $row[] = $data['fls_liga_season']['away']; $copystring .= implode(';', $row)."\n"; $row = []; $row = array_fill(0, 5, ''); $row[] = 'Offside'; $row[] = $data['ofs']['home']; $row[] = $data['ofs']['away']; $row[] = $data['ofs_team']['home']; $row[] = $data['ofs_team']['away']; $row[] = $data['ofs_team_season']['home']; $row[] = $data['ofs_team_season']['away']; $row[] = $data['ofs_liga_season']['home']; $row[] = $data['ofs_liga_season']['away']; $copystring .= implode(';', $row)."\n"; $row = []; $row = array_fill(0, 5, ''); $row[] = 'Cards'; $row[] = $data['crd']['home']; $row[] = $data['crd']['away']; $row[] = $data['crd_team']['home']; $row[] = $data['crd_team']['away']; $row[] = $data['crd_team_season']['home']; $row[] = $data['crd_team_season']['away']; $row[] = $data['crd_liga_season']['home']; $row[] = $data['crd_liga_season']['away']; $copystring .= implode(';', $row)."\n"; $row = []; $row = array_fill(0, 5, ''); $row[] = 'Shots on traget'; $row[] = $data['snt']['home']; $row[] = $data['snt']['away']; $row[] = $data['snt_team']['home']; $row[] = $data['snt_team']['away']; $row[] = $data['snt_team_season']['home']; $row[] = $data['snt_team_season']['away']; $row[] = $data['snt_liga_season']['home']; $row[] = $data['snt_liga_season']['away']; $copystring .= implode(';', $row)."\n"; $row = []; $row = array_fill(0, 5, ''); $row[] = 'Total Shots'; $row[] = $data['tsh']['home']; $row[] = $data['tsh']['away']; $row[] = $data['tsh_team']['home']; $row[] = $data['tsh_team']['away']; $row[] = $data['tsh_team_season']['home']; $row[] = $data['tsh_team_season']['away']; $row[] = $data['tsh_liga_season']['home']; $row[] = $data['tsh_liga_season']['away']; $copystring .= implode(';', $row)."\n"; return $copystring; } protected function tooltip_similar_past_matches(): HtmlString { $str = '
'; $str .= '
Similar Past Matches (SMP)
'; $str .= '
None
'; $str .= '
Team within selected league
'; $str .= '
League
'; $str .= '
Simmilar events in league in the range of slider.
'; $str .= '
All Database
'; $str .= '
Simmilar events in database in the range of slider.
'; $str .= '
'; return new HtmlString($str); } protected function tooltip_player_info(): HtmlString { $str = '
'; $str .= '
Player Information
'; $str .= '
Events played:
'; $str .= '
sum
'; $str .= '
Stronger foot:
'; $str .= '
left | right | both
'; $str .= '
Average on field:
'; $str .= '
minutes
'; $str .= '
'; return new HtmlString($str); } /** * FROM HERE ONLY FORM FILTERS * Komplexe Filter in eigene Methoden auslagern (faster) */ private function selectSofascoreCategoryId(): Select { return Select::make('sofascore_category_id') ->live() ->preload() ->searchable(false) ->prefixIconColor(fn (Get $get): string => $get('sofascore_category_id') ? 'success' : 'danger') ->prefixIcon('phosphor-globe') ->hiddenLabel() ->options(fn () => LoadSofaScoreCategory::load()) ->placeholder('Select Country') ->afterStateUpdated(function (callable $set, $state) { $set('seasonmode', SofaScoreCategory::where('id', $state)->value('season_mode')); $set('league_id', null); $set('match_id', null); $set('team_id', null); $set('ss_player_id', null); $set('season', null); }); } private function selectLeagueId(): Select { return Select::make('league_id') ->live() ->preload() ->prefixIconColor(fn (Get $get): string => $get('league_id') ? 'success' : 'danger') ->prefixIcon('phosphor-trophy') ->hiddenLabel() ->options(fn (Get $get) => LoadStatisticFixturesLeaguesOptions::load($get('sofascore_category_id'))) ->placeholder('Select League') ->afterStateUpdated(function (callable $set) { $set('ss_player_id', null); $set('match_id', null); $set('team_id', null); $this->dispatch('reset-tab'); }); } private function selectMatchId(): Select { return Select::make('match_id') ->live() ->hiddenLabel() ->columnSpan(fn (Get $get) => $get('similar_past_matches') != 'none' ? 2 : 1) ->prefixIconColor(fn (Get $get): string => $get('match_id') ? 'success' : 'danger') ->prefixIcon('phosphor-calendar-check') ->options(function (Get $get) { return LoadStatisticFixturesMatchOptions::load($get('league_id')); }) ->afterStateUpdated(function (callable $set) { $set('team_id', null); $set('ss_player_id', null); $this->dispatch('reset-tab'); }) ->placeholder('Select Event'); } private function selectTeamId(): Select { return Select::make('team_id') ->live() ->hiddenLabel() ->prefixIconColor(function (Get $get): string { if ($get('team_id')) { return 'success'; } elseif ($get('similar_past_matches') != 'none') { return 'gray'; } else { return 'danger'; } }) ->prefixIcon('phosphor-users') ->suffixAction(Action::make('reset') ->icon('phosphor-x') ->tooltip('Clear Team') ->action(fn (callable $set) => $set('team_id', 0).$set('ss_player_id', null)) ->color('gray')) ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') ->options(function (Get $get) { if ($get('match_id')) { $res = StatisticFixtures::where('id', $get('match_id'))->first(); $arr = []; if ($res) { $arr[$res->home_id] = SofaScoreRosa::query()->where('ss_team_id', $res->home_id)->value('ss_team_name'); $arr[$res->away_id] = SofaScoreRosa::query()->where('ss_team_id', $res->away_id)->value('ss_team_name'); } return $arr; } }) ->afterStateUpdated(function (callable $set) { $set('ss_player_id', null); $set('team_position', 'all'); $this->dispatch('reset-tab'); }) ->placeholder('Select Team'); } private function selectTeamPosition(): Select { return Select::make('team_position') ->live() ->hiddenLabel() ->placeholder('Select Team Position') ->prefix('TP') ->prefixAction( Action::make('iconInfo') ->color('success') ->icon('phosphor-question') ->tooltip(fn () => 'Team Position') ) ->visible(fn (Get $get) => $get('team_id')) ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') ->default('all') ->selectablePlaceholder(false) ->options([ 'all' => 'All', 'home' => 'Home', 'away' => 'Away', ])->afterStateUpdated(function (callable $set) { $set('ss_player_id', null); }); } private function selectStatisticType(): Select { return Select::make('statistic_type') ->live() ->hiddenLabel() ->allowHtml() ->placeholder('Statistic Type') ->prefixIconColor('success') ->prefixIcon(function (Get $get) { return match ($get('statistic_type')) { 'gls' => 'phosphor-soccer-ball', 'crn' => 'phosphor-angle', 'fls' => 'phosphor-first-aid-kit', 'ofs' => 'phosphor-arrow-fat-lines-right', 'crd' => 'phosphor-cards', 'snt' => 'phosphor-target', 'tsh' => 'phosphor-chart-polar', default => 'phosphor-soccer-ball', }; }) ->default('gls') ->selectablePlaceholder(false) ->options([ 'gls' => 'Goals', 'crn' => 'Corner', 'fls' => 'Fouls Commited', 'ofs' => 'Offside', 'crd' => 'Cards', 'snt' => 'Shots On Target', 'tsh' => 'Total Shots', ]); } private function selectSimilarPastMatches(): Select { return Select::make('similar_past_matches') ->live() // ->columnSpan(2) ->hiddenLabel() ->hidden(fn (Get $get) => $get('team_id') != null) ->columnSpan(fn (Get $get) => $get('similar_past_matches') != 'none' ? 2 : 1) ->suffixAction(Action::make('reset') ->icon('phosphor-x') ->tooltip('Clear SMP') ->action(fn (callable $set) => $set('similar_past_matches', 'none')) ->color('gray')) ->placeholder('Similar Past Matches') ->suffix(fn (Get $get): string|HtmlString => $get('similar_past_matches') != 'none' ? new HtmlString('
± '.$get('accuracy').'
') : '') ->prefix('SPM') ->prefixAction( Action::make('iconInfo') ->icon('phosphor-question') ->color(fn (Get $get): string => $get('similar_past_matches') != 'none' ? 'success' : 'danger') ->tooltip(fn () => $this->tooltip_similar_past_matches()) ) ->default('none') ->selectablePlaceholder(false) ->afterStateUpdated(function (callable $set) { $set('ss_player_id', null); $set('team_position', null); $this->dispatch('reset-tab'); }) ->options([ 'none' => 'None', 'league' => 'League', 'all' => 'All Database', ]); } private function sliderAccuracy(): Slider { return Slider::make('accuracy') ->live() ->hiddenLabel() ->hidden(fn (Get $get) => $get('similar_past_matches') == 'none') ->fillTrack() ->minValue(0) ->maxValue(0.25) ->default(0.125) ->step(0.025) ->decimalPlaces(3) ->pips() ->pipsFormatter(RawJs::make(<<<'JS' `${$value.toFixed(2)}` JS)); } private function selectPlayerId(): Select { return Select::make('ss_player_id') ->live() ->hiddenLabel() ->allowHtml() ->columnSpan(2) ->placeholder('Player') ->visible(fn (Get $get) => $get('team_id')) ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') ->prefixIconColor(fn (Get $get): string => $get('similar_past_matches') == 'none' ? 'success' : '') ->prefixIcon('icon-player') ->preload() ->searchable() ->extraAttributes(fn () => [ 'id' => 'player_selector', 'style' => 'width: 100%;', ]) ->suffixAction( Action::make('iconInfo') ->icon('phosphor-question') ->color('success') ->tooltip(fn () => $this->tooltip_player_info()) ) ->options(function (Get $get) { $team_id = $get('team_id'); $team_position = $get('team_position'); $sofascore_category_id = $get('sofascore_category_id'); $season = $get('season'); $seasonmode = $get('seasonmode'); return LoadPlayerSelection::load($team_id, $team_position, $sofascore_category_id, $season, $seasonmode); }); } private function selectPlayerOnField(): Select { return Select::make('player_on_field') ->live() ->hiddenLabel() ->placeholder('Time on field') ->prefixIcon('phosphor-watch') ->default('all') ->visible(fn (Get $get) => $get('ss_player_id')) ->prefixIconColor('success') ->selectablePlaceholder(false) ->options([ 'all' => 'All', 'lineup' => 'Lineup', 'substituted' => 'Substituted', 'notplayed' => 'Not Played', ]); } private function radioSeasonOrDate(): Radio { return Radio::make('season_or_date') ->live() ->extraAttributes([ 'class' => 'radio-statistic-group', ]) ->visible(fn (Get $get) => $get('team_id')) ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') ->columnSpan(2) ->inline() ->default('season') ->hiddenLabel() ->options([ 'season' => 'Season', 'date' => 'Date', ]); } private function selectSeason(): Select { return Select::make('season') ->live() ->columnSpan(2) ->hiddenLabel() ->multiple() ->placeholder('Current Season') ->prefixIconColor('success') ->visible(fn (Get $get) => $get('team_id')) ->hidden(fn (Get $get) => $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') ->prefixIcon('phosphor-calendar-star') ->options(function (Get $get) { if ($get('seasonmode') == 'halfyear') { return ['26/27' => '26/27', '25/26' => '25/26', '24/25' => '24/25']; } else { return ['2026' => '2026', '2025' => '2025', '2024' => '2024']; } }) ->afterStateUpdated(function (callable $set, Get $get) { $set('ss_player_id', null); }); } private function datePickerStartDate(): DatePicker { return DatePicker::make('start_date') ->live() ->hiddenLabel() ->columnSpan(2) ->visible(fn (Get $get) => $get('team_id')) ->hidden(fn (Get $get) => $get('season_or_date') == 'season') ->native(false) ->prefixIconColor(fn (Get $get): string => $get('start_date') ? 'success' : 'primary') ->prefixIcon('phosphor-calendar') ->prefix('Start') ->suffixAction( Action::make('clear_start') ->icon('phosphor-x') ->color('gray') ->action(fn (Set $set) => $set('start_date', null)) ); } private function datePickerEndDate(): DatePicker { return DatePicker::make('end_date') ->live() ->hiddenLabel() ->columnSpan(2) ->visible(fn (Get $get) => $get('team_id')) ->hidden(fn (Get $get) => $get('season_or_date') == 'season') ->native(false) ->prefixIconColor(fn (Get $get): string => $get('end_date') ? 'success' : 'primary') ->prefixIcon('phosphor-calendar') ->prefix('End') ->suffixAction( Action::make('clear_end') ->icon('phosphor-x') ->color('gray') ->action(fn (Set $set) => $set('end_date', null)) ); } }