'DR', 4 => 'MR', 6 => 'RW', 9 => 'DC', 10 => 'DM', 11 => 'MC', 12 => 'AM', 15 => 'SW', 16 => 'DC', 17 => 'DM', 18 => 'MC', 19 => 'AM', 20 => 'SM', 21 => 'ST', 23 => 'DC', 24 => 'DM', 25 => 'MC', 26 => 'AM', 30 => 'DL', 32 => 'ML', 34 => 'LM']; public bool $copyDisabled = true; public bool $calculationDisabled = true; public string $ss_team_name = ''; public array $lineupsMap = [ '3313' => [9, 16, 23, 11, 18, 25, 19, 6, 34, 21], '3331' => [9, 16, 23, 17, 11, 25, 12, 19, 26, 21], '3331-' => [9, 16, 23, 10, 18, 24, 12, 19, 26, 21], '3331+' => [9, 16, 23, 11, 18, 25, 12, 19, 26, 21], '3412-' => [9, 16, 23, 4, 10, 24, 32, 19, 20, 21], '3412+' => [9, 16, 23, 4, 11, 25, 32, 19, 20, 21], '3421-' => [9, 16, 23, 4, 10, 24, 32, 12, 26, 21], '3421+' => [9, 16, 23, 4, 11, 25, 32, 12, 26, 21], '343-' => [9, 16, 23, 4, 10, 24, 32, 6, 34, 21], '343+' => [9, 16, 23, 4, 11, 25, 32, 6, 34, 21], '3511' => [9, 16, 23, 4, 11, 17, 25, 32, 19, 21], '3511-' => [9, 16, 23, 4, 10, 18, 24, 32, 19, 21], '3511+' => [9, 16, 23, 4, 11, 18, 25, 32, 19, 21], '352' => [9, 16, 23, 4, 11, 17, 25, 32, 20, 21], '352-' => [9, 16, 23, 4, 10, 18, 24, 32, 20, 21], '352+' => [9, 16, 23, 4, 11, 18, 25, 32, 20, 21], '4132' => [2, 9, 23, 30, 17, 12, 19, 26, 20, 21], '4213-' => [2, 9, 23, 30, 10, 24, 19, 6, 34, 21], '4213+' => [2, 9, 23, 30, 11, 25, 19, 6, 34, 21], '4222' => [2, 9, 23, 30, 10, 24, 12, 26, 20, 21], '4231' => [2, 9, 23, 30, 10, 24, 12, 19, 26, 21], '424' => [2, 9, 23, 30, 10, 24, 6, 34, 20, 21], '4312' => [2, 9, 23, 30, 17, 11, 25, 19, 20, 21], '4312-' => [2, 9, 23, 30, 10, 18, 24, 19, 20, 21], '4312+' => [2, 9, 23, 30, 11, 18, 25, 19, 20, 21], '4321' => [2, 9, 23, 30, 17, 11, 25, 12, 26, 21], '4321-' => [2, 9, 23, 30, 10, 18, 24, 12, 26, 21], '4321+' => [2, 9, 23, 30, 11, 18, 25, 12, 26, 21], '433' => [2, 9, 23, 30, 17, 11, 25, 6, 34, 21], '433-' => [2, 9, 23, 30, 10, 18, 24, 6, 34, 21], '433+' => [2, 9, 23, 30, 11, 18, 25, 6, 34, 21], '4411-' => [2, 9, 23, 30, 4, 10, 24, 32, 19, 21], '4411+' => [2, 9, 23, 30, 4, 11, 25, 32, 19, 21], '442' => [2, 9, 23, 30, 4, 17, 18, 32, 20, 21], '442-' => [2, 9, 23, 30, 4, 10, 24, 32, 20, 21], '442+' => [2, 9, 23, 30, 4, 11, 25, 32, 20, 21], '451' => [2, 9, 23, 30, 4, 17, 11, 25, 32, 21], '451-' => [2, 9, 23, 30, 4, 10, 18, 24, 32, 21], '451+' => [2, 9, 23, 30, 4, 11, 18, 25, 32, 21], '523-' => [2, 9, 16, 23, 30, 10, 24, 6, 34, 21], '523+' => [2, 9, 16, 23, 30, 11, 25, 6, 34, 21], '5311' => [2, 9, 16, 23, 30, 17, 11, 25, 19, 21], '5311-' => [2, 9, 16, 23, 30, 10, 18, 24, 19, 21], '5311+' => [2, 9, 16, 23, 30, 11, 18, 25, 19, 21], '532' => [2, 9, 16, 23, 30, 17, 11, 25, 20, 21], '532-' => [2, 9, 16, 23, 30, 10, 18, 24, 20, 21], '532+' => [2, 9, 16, 23, 30, 11, 18, 25, 20, 21], '541-' => [2, 9, 16, 23, 30, 4, 10, 24, 32, 21], '541+' => [2, 9, 16, 23, 30, 4, 11, 25, 32, 21], ]; public array $lineup = []; public array $lineup_options = [ '3313' => '3313', '3331' => '3331', '3331-' => '3331-', '3331+' => '3331+', '3412-' => '3412-', '3412+' => '3412+', '3421-' => '3421-', '3421+' => '3421+', '343-' => '343-', '343+' => '343+', '3511' => '3511', '3511-' => '3511-', '3511+' => '3511+', '352' => '352', '352-' => '352-', '352+' => '352+', '4132' => '4132', '4213-' => '4213-', '4213+' => '4213+', '4222' => '4222', '4231' => '4231', '424' => '424', '4312' => '4312', '4312-' => '4312-', '4312+' => '4312+', '4321' => '4321', '4321-' => '4321-', '4321+' => '4321+', '433' => '433', '433-' => '433-', '433+' => '433+', '4411-' => '4411-', '4411+' => '4411+', '442' => '442', '442-' => '442-', '442+' => '442+', '451' => '451', '451-' => '451-', '451+' => '451+', '523-' => '523-', '523+' => '523+', '5311' => '5311', '5311-' => '5311-', '5311+' => '5311+', '532' => '532', '532-' => '532-', '532+' => '532+', '541-' => '541-', '541+' => '541+', ]; public string $lineup_selected = '3313'; public array $boxes = []; public array $beschriftung = []; public function mount(array $filters) { $this->ss_team_name = SofaScoreRosa::where('ss_team_id', $filters['team_id'])->value('ss_team_name'); $this->sourceRecords = PlayerCalculator::load($filters); $this->lineup = $this->lineupsMap[$this->lineup_selected]; for ($i = 1; $i <= 35; $i++) { $this->boxes[$i] = []; if (isset($this->activeBoxes[$i])) { $this->beschriftung[$i] = $this->activeBoxes[$i]; } else { $this->beschriftung[$i] = ''; } } // Log::debug('beschriftung', $this->beschriftung); } public function getHeadingTable(): HtmlString { return new HtmlString('
Gls
Fls
Ofs
Snt
Tsh
Crd
Foot
Evt
Ømin
'); } public function form(Schema $schema): Schema { return $schema ->columns(4) ->components([ Select::make('lineup_selected') ->live() ->hiddenLabel() ->columnSpan(2) ->prefix('Lineup') ->prefixIcon('icon-soccerplayer') ->searchable() ->options($this->lineup_options) ->afterStateUpdated(function ($state, $livewire) { $livewire->updateLineup($state); }), ]); } public function table(Table $table): Table { return $table ->headerActions([ // FilamentView::registerRenderHook( // PanelsRenderHook::GLOBAL_SEARCH_AFTER, // fn (): View => view('filament.modals.position-abbreviation'), // ); Action::make('close') ->size(Size::Small) ->tooltip('Close application') ->hiddenLabel() ->icon('phosphor-x') ->close(), Action::make('lineups') ->size(Size::Small) ->tooltip('Lineup abbreviation explanation') ->hiddenLabel() ->icon('phosphor-question-mark') ->slideOver() ->slideOverPosition(SlideOverPosition::Start) ->modalWidth(Width::ExtraLarge) ->modalSubmitAction(false) ->modalCancelAction(false) ->modalContent(fn () => view('filament.modals.position-abbreviation')), Action::make('reset') ->hiddenLabel() ->size(Size::Small) ->tooltip('Remove all players from field') ->icon('phosphor-arrows-clockwise') ->action(fn () => $this->clearAll()), Action::make('calculate') ->hiddenLabel() ->tooltip('Calculate expected values') ->size(Size::Small) ->icon('phosphor-calculator') ->disabled($this->calculationDisabled) ->action(fn () => $this->calculateAspg()), Action::make('copy') ->tooltip('Copy results for pasting into a spread sheet') ->hiddenLabel() ->size(Size::Small) ->icon('phosphor-copy') ->disabled($this->copyDisabled) ->action(fn () => $this->copyResult()), ]) /** * WICHTIG: Da Filament v5 zwingend eine Query braucht, nutzen wir ein * leeres Modell (z.B. ein beliebiges Basis-Modell deines Projekts) NUR als Dummy-Builder. * Alternativ kannst du ein anonymes Model nutzen. */ ->query(User::query()->whereRaw('1 = 0')) // Verhindert DB-Abfragen ->striped() ->defaultSort('name') ->columns([ ViewColumn::make('drag_card') ->columnSpanFull() ->label(fn () => $this->getHeadingTable()) ->view('filament.tables.columns.drag-card'), ]) ->filters([ SelectFilter::make('position_area') ->columnSpanFull() ->native(false) ->options([ // 'attack' => 'Attack', // 'midfield' => 'Midfield', // 'defence' => 'Denfence', // 'goalkeeper' => 'Goalkeeper', 'attack' => 'Attack', 'midfield' => 'Midfield', 'defence' => 'Defence', 'goalkeeper' => 'Goalkeeper', ])->modifyFormFieldUsing(fn (Select $component) => $component->allowHtml()) ->query(function ($query) { return $query; })->indicateUsing(function (array $data): array { // WICHTIG: Ein leeres Array sorgt dafür, dass kein Indicator-Badge erzeugt wird return []; }), ], layout: FiltersLayout::AboveContent) ->deferFilters(false) ->records(function () { $collection = collect($this->sourceRecords); $selectedPosition = $this->tableFilters['position_area']['value'] ?? null; if (! empty($selectedPosition)) { $collection = $collection->where('position_area', $selectedPosition); } return $collection; }); } #[On('element-dropped-in-box')] public function handleElementDropped(mixed $elementData, mixed $boxNumber): void { $boxNumber = (int) $boxNumber; $player = is_array($elementData) ? $elementData : json_decode($elementData, true); if (! $player || ! isset($player['id'])) { return; } foreach ($this->sourceRecords as $k => $record) { if ($record['id'] == (int) $player['id']) { $this->calculationDisabled = false; if ($this->boxes[$boxNumber]) { $this->clearBox($boxNumber); } $this->boxes[$boxNumber] = $record; $this->sourceRecords[$k]['active'] = 1; $this->sourceRecords[$k]['position'] = $this->activeBoxes[$boxNumber]; } } } public function updateLineup(?string $state) { $this->clearAll(); if (isset($this->lineupsMap[$state])) { $this->lineup = $this->lineupsMap[$state]; } else { $this->lineup = []; } } public function clearBox(int $boxNumber): void { if (isset($this->boxes[$boxNumber])) { $tmp = $this->boxes[$boxNumber]; $player_id = 0; foreach ($tmp as $key => $value) { if ($key == 'id') { $player_id = $value; } } foreach ($this->sourceRecords as $k => $record) { if ($record['id'] == (int) $player_id) { $this->boxes[$boxNumber] = []; $this->sourceRecords[$k]['position'] = ''; $this->sourceRecords[$k]['active'] = 0; } } } } public function calculateAspg(): void { $this->copyDisabled = false; } public function clearAll(): void { for ($i = 1; $i <= 35; $i++) { $this->boxes[$i] = []; } foreach ($this->sourceRecords as $k => $record) { $this->sourceRecords[$k]['position'] = ''; $this->sourceRecords[$k]['active'] = 0; } $this->copyDisabled = true; $this->calculationDisabled = true; } public function copyResult() { return; $copystring = ''; foreach ($this->results as $row) { unset($row['origin']); unset($row['pcolor']); unset($row['ecolor']); unset($row['info']); $copystring .= implode("\t", $row)."\n"; } $this->js("navigator.clipboard.writeText(`$copystring`)"); } public function render() { return view('livewire.board-dispatcher'); } }