diff --git a/Season-24-25-Major-Leagues.xlsx b/Season-24-25-Major-Leagues.xlsx new file mode 100644 index 00000000..7a985719 Binary files /dev/null and b/Season-24-25-Major-Leagues.xlsx differ diff --git a/app/Actions/Selections/LoadPlayer.php b/app/Actions/Selections/LoadPlayer.php index 5aa610f3..f22cd8af 100644 --- a/app/Actions/Selections/LoadPlayer.php +++ b/app/Actions/Selections/LoadPlayer.php @@ -62,15 +62,15 @@ class LoadPlayer $colorlevel = round($matches_count / 3); - $time_played = round($minues_played / 60) . ':'; - $time_played .= $minues_played % 60; + $time_played = round($minues_played / 60) . 'h:'; + $time_played .= $minues_played % 60 . 'm'; $position = $ss_positions_map[$val->details->position] ?? 'No Specific Position'; if ($events_played < $colorlevel) { $arr[$position][$val->ss_player_id] = '' . $val->details->player_name . '(' . $events_played . ') (' . $time_played . ')'; } else if ($events_played < $colorlevel * 2) { - $arr[$position][$val->ss_player_id] = '' . $val->details->player_name . ' (' . $events_played . ') (' . $time_played . ''; + $arr[$position][$val->ss_player_id] = '' . $val->details->player_name . ' (' . $events_played . ') (' . $time_played . ')'; } else { $arr[$position][$val->ss_player_id] = '' . $val->details->player_name . ' (' . $events_played . ') (' . $time_played . ')'; } diff --git a/app/Console/Commands/Grapper/Sofascore.php b/app/Console/Commands/Grapper/Sofascore.php index cafc8668..204679d3 100644 --- a/app/Console/Commands/Grapper/Sofascore.php +++ b/app/Console/Commands/Grapper/Sofascore.php @@ -24,7 +24,7 @@ class Sofascore { public static string $storage; - public static string $archive_name; + public static string $zipfile; public static string $excel_name; @@ -90,30 +90,40 @@ class Sofascore public static function setStorage() { $task = Nuh::$options['task']; + $debug = Nuh::$options['d']; - self::$storage = storage_path('sofascore_data') . '/'; - // for grapper to start with + $sofascore_data = storage_path('sofascore_data') . '/'; + $task = SofaScoreTask::where('id', $task)->first(); + if (!$task) { + Notice::note("No SofaScoreTask " . Nuh::$options['task'], 'r', 1); + } + $storage_name = Strings::clean($task->name); - $storage_name = Strings::clean(SofaScoreTask::where('id', $task)->value('name')) . '/'; - - switch ($task) { + switch ($task->id) { case 1: - self::$archive_name = Carbon::now()->subDays(3)->format('Y-m-d') . '.zip'; - self::$storage .= $storage_name . Carbon::now()->subDays(3)->format('Y-m-d'); + self::$storage = $sofascore_data . $storage_name . '/' . Carbon::now()->subDays(3)->format('Y-m-d'); + self::$zipfile = $sofascore_data . $storage_name . '/' . Carbon::now()->subDays(3)->format('Y-m-d') . '.zip'; break; case 2: + self::$storage = $sofascore_data . $storage_name . '/' . $task->day_from; + self::$zipfile = $sofascore_data . $storage_name . '/' . $task->day_from . '.zip'; + break; case 3: - self::$archive_name = $storage_name . '.zip'; - self::$storage .= $storage_name; + self::$storage = $sofascore_data . $storage_name . '-' . $task->day_from . '-' . $task->day_to; + self::$zipfile = $sofascore_data . $storage_name . '-' . $task->day_from . '-' . $task->day_to . '.zip'; break; case 4: - self::$archive_name = 'rosa-' . Carbon::now()->format('Y-m-d') . '.zip'; - self::$storage .= $storage_name . 'rosa-' . Carbon::now()->format('Y-m-d'); + self::$storage = $sofascore_data . $storage_name . '/rosa-' . Carbon::now()->format('Y-m-d'); + self::$zipfile = $sofascore_data . $storage_name . '/rosa-' . Carbon::now()->format('Y-m-d') . '.zip'; break; default: - self::$archive_name = 'archive.zip'; + self::$storage = $sofascore_data . $storage_name; + self::$zipfile = $sofascore_data . $storage_name . '/archive.zip'; break; } + + if ($debug) + Notice::note("\nStore:\t" . Sofascore::$storage . "\nZip:\t" . Sofascore::$zipfile, 'c'); } } diff --git a/app/Console/Commands/Grapper/Sofascore/Helper/ZipFolder.php b/app/Console/Commands/Grapper/Sofascore/Helper/ZipFolder.php index 5852da0e..1af1d902 100644 --- a/app/Console/Commands/Grapper/Sofascore/Helper/ZipFolder.php +++ b/app/Console/Commands/Grapper/Sofascore/Helper/ZipFolder.php @@ -12,11 +12,9 @@ class ZipFolder public static function create() { - $zipFilePath = Sofascore::$storage . Sofascore::$archive_name; - $zip = new ZipArchive(); - if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) { + if ($zip->open(Sofascore::$zipfile, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) { if (is_dir(Sofascore::$storage)) { diff --git a/app/Console/Commands/Grapper/Sofascore/MakeExcel.php b/app/Console/Commands/Grapper/Sofascore/MakeExcel.php index 84df6b6f..6a6196d8 100644 --- a/app/Console/Commands/Grapper/Sofascore/MakeExcel.php +++ b/app/Console/Commands/Grapper/Sofascore/MakeExcel.php @@ -3,37 +3,78 @@ namespace App\Console\Commands\Grapper\Sofascore; use App\Console\Commands\Grapper\Sofascore; -use App\Console\Commands\Grapper\Sofascore\Helper\Strings; use App\Console\Commands\Grapper\Sofascore\Helper\ZipFolder; use App\Console\Commands\Nuh; -use Spatie\SimpleExcel\SimpleExcelWriter; +use App\Utilities\Notice; +use PhpOffice\PhpSpreadsheet\IOFactory; +use PhpOffice\PhpSpreadsheet\Spreadsheet; class MakeExcel { + public static $FOLDER = 'Season-25-26-Major-Leagues'; + public static $MAXCOLUMNS = 1000; + public static function create() { - $files = ZipFolder::get_tree(Sofascore::$storage); + ini_set("memory_limit", -1); - $writer = SimpleExcelWriter::create(Sofascore::$storage . '.xlsx'); + $debug = Nuh::$options['d'] ?? 0; - foreach ($files as $file) { + if ($debug) { + Notice::note("Make Excel", 'bb'); + } - $name = str_replace('.json', '', basename($file)); - $writer->addHeader(['#TEAM# ' . $name]); + if ($debug) { + Notice::note("Folder to Import: " . self::$FOLDER . "\nMaximum in Excel: " . self::$MAXCOLUMNS, 'b'); + } - $data = file_get_contents($file); + $files = self::load_files(); - $arr = json_decode($data, true); + foreach ($files as $key => $value) { - if (isset($arr['players']) && is_array($arr['players'])) { - foreach ($arr['players'] as $value) { - if ($value) { - $writer->addRow([$name => json_encode($value)]); - } + $from = $key * self::$MAXCOLUMNS + 1; + $key++; + $to = $key * self::$MAXCOLUMNS; + $filename = self::$FOLDER . '-' . $from . '-' . $to . '.xlsx'; + + $spreadsheet = new Spreadsheet; + $spreadsheet->getProperties()->setTitle($filename); + $activeWorksheet = $spreadsheet->getActiveSheet(); + + $column = 1; + foreach ($value as $file) { + $data = file_get_contents($file); + $data = json_decode($data, true); + $json_string = json_encode($data, JSON_PRETTY_PRINT); + + $arr = explode(PHP_EOL, $json_string); + $row = 0; + foreach ($arr as $val) { + $row++; + $activeWorksheet->setCellValue([$column, $row], trim($val)); } + $column++; + } + + $spreadsheet->setActiveSheetIndex(0); + $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); + $writer->save(Sofascore::$storage . '/' . $filename); + } + } + + + public static function load_files() + { + $files = ZipFolder::get_tree(Sofascore::$storage . '/' . self::$FOLDER); + + $filtered = []; + foreach ($files as $file) { + $path_parts = pathinfo($file); + if (isset($path_parts['extension']) && $path_parts['extension'] == 'json') { + $filtered[] = $file; } } - $writer->close(); + return array_chunk($filtered, self::$MAXCOLUMNS); } } diff --git a/app/Filament/Clusters/StaticData/Resources/CompetitionGroups/CompetitionGroupResource.php b/app/Filament/Clusters/StaticData/Resources/CompetitionGroups/CompetitionGroupResource.php index 5b88c7e6..47676784 100644 --- a/app/Filament/Clusters/StaticData/Resources/CompetitionGroups/CompetitionGroupResource.php +++ b/app/Filament/Clusters/StaticData/Resources/CompetitionGroups/CompetitionGroupResource.php @@ -49,9 +49,4 @@ class CompetitionGroupResource extends Resource { return parent::getEloquentQuery()->count(); } - - public static function getNavigationBadgeColor(): ?string - { - return 'warning'; - } } diff --git a/app/Filament/Clusters/StaticData/Resources/Countries/CountryResource.php b/app/Filament/Clusters/StaticData/Resources/Countries/CountryResource.php index bfd77301..a4848304 100644 --- a/app/Filament/Clusters/StaticData/Resources/Countries/CountryResource.php +++ b/app/Filament/Clusters/StaticData/Resources/Countries/CountryResource.php @@ -142,11 +142,6 @@ class CountryResource extends Resource return parent::getEloquentQuery()->where('disabled', false)->count(); } - public static function getNavigationBadgeColor(): ?string - { - return 'warning'; - } - public static function getEloquentQuery(): Builder { return parent::getEloquentQuery()->where('disabled', false); diff --git a/app/Filament/Clusters/StaticData/Resources/Elements/ElementResource.php b/app/Filament/Clusters/StaticData/Resources/Elements/ElementResource.php index 8f35d27f..5aed9231 100644 --- a/app/Filament/Clusters/StaticData/Resources/Elements/ElementResource.php +++ b/app/Filament/Clusters/StaticData/Resources/Elements/ElementResource.php @@ -45,9 +45,4 @@ class ElementResource extends Resource { return parent::getEloquentQuery()->count(); } - - public static function getNavigationBadgeColor(): ?string - { - return 'warning'; - } } diff --git a/app/Filament/Clusters/StaticData/Resources/SofaScoreRosas/SofaScoreRosaResource.php b/app/Filament/Clusters/StaticData/Resources/SofaScoreRosas/SofaScoreRosaResource.php index 3bd74a1b..9eb4f95f 100644 --- a/app/Filament/Clusters/StaticData/Resources/SofaScoreRosas/SofaScoreRosaResource.php +++ b/app/Filament/Clusters/StaticData/Resources/SofaScoreRosas/SofaScoreRosaResource.php @@ -18,6 +18,8 @@ class SofaScoreRosaResource extends Resource protected static ?string $cluster = StaticDataCluster::class; + protected static ?int $navigationSort = 3; + protected static ?string $recordTitleAttribute = 'name'; protected static ?string $navigationLabel = 'Rosters'; diff --git a/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/SofaScoreTaskResource.php b/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/SofaScoreTaskResource.php index 8bc4597c..84b35765 100644 --- a/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/SofaScoreTaskResource.php +++ b/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/SofaScoreTaskResource.php @@ -24,7 +24,7 @@ class SofaScoreTaskResource extends Resource protected static ?string $modelLabel = 'Tasks'; - protected static ?int $navigationSort = 1; + protected static ?int $navigationSort = 2; protected static string|UnitEnum|null $navigationGroup = 'SofaScore'; diff --git a/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/Tables/SofaScoreTasksTable.php b/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/Tables/SofaScoreTasksTable.php index 8a97a813..ff57782e 100644 --- a/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/Tables/SofaScoreTasksTable.php +++ b/app/Filament/Clusters/StaticData/Resources/SofaScoreTasks/Tables/SofaScoreTasksTable.php @@ -22,9 +22,10 @@ class SofaScoreTasksTable ->icon(fn($record) => $record->sport->icon), TextColumn::make('sport.name'), TextColumn::make('mode') - ->label('Grapping dates') + ->label('Grapping Task') ->formatStateUsing(fn(string $state, $record): string => match ($state) { - 'daily' => 'Daily', + 'daily' => 'Daily run', + 'excel' => 'Import to Excel', 'date' => $record->day_from, 'range' => $record->day_from . ' <=> ' . $record->day_to, }), diff --git a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/StatisticFixturesResource.php b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/StatisticFixturesResource.php index 125ab4d5..d4155346 100644 --- a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/StatisticFixturesResource.php +++ b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/StatisticFixturesResource.php @@ -20,9 +20,9 @@ class StatisticFixturesResource extends Resource protected static ?string $modelLabel = 'Fixtures'; - protected static string|UnitEnum|null $navigationGroup = 'Statistiko'; + protected static string|UnitEnum|null $navigationGroup = 'SofaScore'; - protected static ?int $navigationSort = 2; + protected static ?int $navigationSort = 5; protected static ?string $cluster = StaticDataCluster::class; diff --git a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Tables/StatisticFixturesTable.php b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Tables/StatisticFixturesTable.php index 9a6c4680..7faf01a7 100644 --- a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Tables/StatisticFixturesTable.php +++ b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Tables/StatisticFixturesTable.php @@ -3,15 +3,19 @@ namespace App\Filament\Clusters\StaticData\Resources\StatisticFixtures\Tables; use App\Actions\LoadStatisticFixturesLeaguesOptions; +use App\Models\Sport; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteAction; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; +use Filament\Forms\Components\Select; +use Filament\Schemas\Components\Utilities\Get; use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Enums\FiltersLayout; -use Filament\Tables\Filters\SelectFilter; +use Filament\Tables\Filters\Filter; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Builder; class StatisticFixturesTable { @@ -30,30 +34,51 @@ class StatisticFixturesTable TextColumn::make('league.name') ->label('League') ->searchable() - ->wrap() - ->tooltip(fn($record) => $record->league_id) - ->hidden(fn() => auth()->user()->sport_id == 5) - ->description(fn($record) => ucwords($record->league?->country->name)), + ->description( + fn($record) => $record->league->sofascore_category->name + ), TextColumn::make('starttime')->dateTime('Y-m-d H:i'), - TextColumn::make('home.name') + TextColumn::make('home.ss_team_name') ->tooltip(fn($record) => $record->home_id) ->color('primary') ->searchable(), - TextColumn::make('away.name') + TextColumn::make('away.ss_team_name') ->tooltip(fn($record) => $record->away_id) ->color('success') ->searchable(), - // TextColumn::make('exp_home')->alignCenter()->numeric(), - // TextColumn::make('exp_away')->alignCenter()->numeric(), TextColumn::make('updated_at')->alignCenter()->date(), ]) ->filters([ - SelectFilter::make('league_id') - ->options(fn() => LoadStatisticFixturesLeaguesOptions::load(1)) - ->preload() - ->searchable() - ->columnSpan(2) - ->label('League'), + Filter::make('fixture_filters') + ->columns(3) + ->columnSpan(3) + ->schema([ + Select::make('sport_id') + ->default(1) + ->options(fn() => Sport::query()->where('is_active', 1)->pluck('name', 'id')) + ->selectablePlaceholder(false) + ->label('Sport') + ->live(), + Select::make('league_id') + ->options(fn(Get $get) => LoadStatisticFixturesLeaguesOptions::load($get('sport_id'))) + ->preload() + ->searchable() + ->columnSpan(2) + ->label('League'), + ])->query(function (Builder $query, array $data): Builder { + return $query->when( + $data['league_id'], + function (Builder $query, $league_id) { + $query->where('league_id', $league_id)->orderBy('league_id'); + } + )->when( + $data['sport_id'], + function (Builder $query, $away_id) { + $query->where('sport_id', (int) $away_id); + } + ); + }), + ], layout: FiltersLayout::AboveContent) ->deferFilters(false) ->recordActions([ diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoDetails/StatistikoDetailResource.php b/app/Filament/Clusters/StaticData/Resources/StatistikoDetails/StatistikoDetailResource.php index 40287fe1..22286956 100644 --- a/app/Filament/Clusters/StaticData/Resources/StatistikoDetails/StatistikoDetailResource.php +++ b/app/Filament/Clusters/StaticData/Resources/StatistikoDetails/StatistikoDetailResource.php @@ -20,11 +20,11 @@ class StatistikoDetailResource extends Resource protected static ?string $modelLabel = 'Details'; - protected static string|UnitEnum|null $navigationGroup = 'Statistiko'; + protected static string|UnitEnum|null $navigationGroup = 'SofaScore'; protected static ?string $cluster = StaticDataCluster::class; - protected static ?int $navigationSort = 4; + protected static ?int $navigationSort = 9; protected static ?string $recordTitleAttribute = 'player_name'; diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php index 3ffd6adf..65982900 100644 --- a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php +++ b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php @@ -20,9 +20,9 @@ class StatistikoEventsResource extends Resource protected static ?string $modelLabel = 'Events'; - protected static string|UnitEnum|null $navigationGroup = 'Statistiko'; + protected static string|UnitEnum|null $navigationGroup = 'SofaScore'; - protected static ?int $navigationSort = 3; + protected static ?int $navigationSort = 6; protected static ?string $cluster = StaticDataCluster::class; diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php index 65332c44..7b3e6525 100644 --- a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php +++ b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php @@ -35,23 +35,12 @@ class StatistikoEventsTable TextColumn::make('match_id') ->sortable(), TextColumn::make('league.name') - ->searchable() - ->copyable() - ->copyMessage('Liga name copied') - ->description(fn($record) => ucwords($record->league?->country->name)) - ->copyMessageDuration(1500), - TextColumn::make('home.name') - ->searchable() - ->copyable() - ->copyMessage('Home team name copied') - ->copyMessageDuration(1500), - TextColumn::make('away.name') - ->searchable() - ->copyable() - ->copyMessage('Away team name copied') - ->copyMessageDuration(1500), + ->searchable(), + TextColumn::make('home.ss_team_name')->color('info') + ->searchable(), + TextColumn::make('away.ss_team_name')->color('success') + ->searchable(), TextColumn::make('starttime')->dateTime('Y-m-d H:i'), - ]) ->filters([ Filter::make('event_filters') diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoImports/StatistikaImportResource.php b/app/Filament/Clusters/StaticData/Resources/StatistikoImports/StatistikaImportResource.php index 15fda088..3c21423d 100644 --- a/app/Filament/Clusters/StaticData/Resources/StatistikoImports/StatistikaImportResource.php +++ b/app/Filament/Clusters/StaticData/Resources/StatistikoImports/StatistikaImportResource.php @@ -20,7 +20,7 @@ class StatistikaImportResource extends Resource protected static ?string $modelLabel = 'File Uploads'; - protected static string|UnitEnum|null $navigationGroup = 'Statistiko'; + protected static string|UnitEnum|null $navigationGroup = 'SofaScore'; protected static ?int $navigationSort = 1; diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php b/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php index 6d52f902..17492452 100644 --- a/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php +++ b/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php @@ -20,11 +20,11 @@ class StatistikoPlayerResource extends Resource protected static ?string $modelLabel = 'Player'; - protected static string|UnitEnum|null $navigationGroup = 'Statistiko'; + protected static string|UnitEnum|null $navigationGroup = 'SofaScore'; protected static ?string $cluster = StaticDataCluster::class; - protected static ?int $navigationSort = 5; + protected static ?int $navigationSort = 8; protected static ?string $recordTitleAttribute = 'player.name'; diff --git a/app/Models/SofaScoreTournament.php b/app/Models/SofaScoreTournament.php index 0e248f81..cc287bcd 100644 --- a/app/Models/SofaScoreTournament.php +++ b/app/Models/SofaScoreTournament.php @@ -3,9 +3,14 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use MongoDB\Laravel\Eloquent\HybridRelations; class SofaScoreTournament extends Model { + use HybridRelations; + + protected $connection = 'mariadb'; + protected $fillable = [ 'id', 'sport_id', diff --git a/app/Models/StatisticFixtures.php b/app/Models/StatisticFixtures.php index 32fc660d..3bbef192 100644 --- a/app/Models/StatisticFixtures.php +++ b/app/Models/StatisticFixtures.php @@ -30,7 +30,7 @@ class StatisticFixtures extends Model public function league() { - return $this->belongsTo(CompetitionGroup::class); + return $this->belongsTo(SofaScoreTournament::class, 'league_id', 'tournament_id'); } public function home() diff --git a/app/Models/StatistikoEvent.php b/app/Models/StatistikoEvent.php index 235062e1..a793964e 100644 --- a/app/Models/StatistikoEvent.php +++ b/app/Models/StatistikoEvent.php @@ -53,18 +53,18 @@ class StatistikoEvent extends Model return $this->belongsTo(Sport::class, 'sport_id', 'id'); } - public function league(): BelongsTo + public function league() { - return $this->belongsTo(CompetitionGroup::class, 'league_id', 'id'); + return $this->belongsTo(SofaScoreTournament::class, 'league_id', 'tournament_id'); } public function home(): BelongsTo { - return $this->belongsTo(Element::class, 'home_id', 'id'); + return $this->belongsTo(SofaScoreRosa::class, 'home_id', 'ss_team_id'); } public function away(): BelongsTo { - return $this->belongsTo(Element::class, 'away_id', 'id'); + return $this->belongsTo(SofaScoreRosa::class, 'away_id', 'ss_team_id'); } } diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 6f466825..e15ebaea 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -19,6 +19,7 @@ use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\AuthenticateSession; use Filament\Http\Middleware\DisableBladeIconComponents; use Filament\Http\Middleware\DispatchServingFilamentEvent; +use Filament\Navigation\NavigationGroup; use Filament\Panel; use Filament\PanelProvider; use Filament\Support\Enums\Width; @@ -64,7 +65,6 @@ class AdminPanelProvider extends PanelProvider ->emailChangeVerification() ->databaseNotifications() ->databaseNotificationsPolling('10s') // default is 30 - ->sidebarCollapsibleOnDesktop() ->profile(isSimple: false) ->default() ->globalSearch(false) @@ -85,11 +85,10 @@ class AdminPanelProvider extends PanelProvider ->viteTheme('resources/css/filament/admin/theme.css') ->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources') ->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages') - // ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') + ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') ->discoverClusters(in: app_path('Filament/Clusters'), for: 'App\\Filament\\Clusters') ->maxContentWidth(Width::ScreenTwoExtraLarge) ->breadcrumbs(false) - ->topNavigation() ->sidebarCollapsibleOnDesktop(false) ->userMenuItems([ 'profile' => Action::make('profile') diff --git a/composer.json b/composer.json index 424c7921..cbe5e486 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ "mongodb/laravel-mongodb": "^5.1", "mongodb/mongodb": "^2.2", "outhebox/blade-flags": "*", + "phpoffice/phpspreadsheet": "^5.9", "spatie/simple-excel": "^3.9", "stevebauman/location": "*", "swisnl/filament-backgrounds": "^2.0" diff --git a/composer.lock b/composer.lock index e56b8761..db60ab76 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "96261ec0c9ff5e24cff0f1ea3568f040", + "content-hash": "b00c887f246ff78cec67da8281097834", "packages": [ { "name": "agencetwogether/hookshelper", @@ -1023,6 +1023,82 @@ ], "time": "2026-07-18T12:35:13+00:00" }, + { + "name": "composer/pcre", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/d5a341b3fb61f3001970940afb1d332968a183ed", + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<2.2.2" + }, + "require-dev": { + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.4.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2026-06-07T11:47:49+00:00" + }, { "name": "danharrin/date-format-converter", "version": "v0.3.1", @@ -4089,6 +4165,191 @@ ], "time": "2026-06-27T03:16:11+00:00" }, + { + "name": "maennchen/zipstream-php", + "version": "3.2.2", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e", + "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-zlib": "*", + "php-64bit": "^8.3" + }, + "require-dev": { + "brianium/paratest": "^7.7", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.86", + "guzzlehttp/guzzle": "^7.5", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.5", + "phpunit/phpunit": "^12.0", + "vimeo/psalm": "^6.0" + }, + "suggest": { + "guzzlehttp/psr7": "^2.4", + "psr/http-message": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.2" + }, + "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + } + ], + "time": "2026-04-11T18:38:28+00:00" + }, + { + "name": "markbaker/complex", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" + }, + "time": "2022-12-06T16:21:08+00:00" + }, + { + "name": "markbaker/matrix", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "^4.0", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "sebastian/phpcpd": "^4.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@demon-angel.eu" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" + }, + "time": "2022-12-02T22:17:43+00:00" + }, { "name": "masterminds/html5", "version": "2.10.1", @@ -5334,6 +5595,115 @@ }, "time": "2025-09-24T15:06:41+00:00" }, + { + "name": "phpoffice/phpspreadsheet", + "version": "5.9.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "05e99ebf61238a70227b4d9cc02d0030d34f6339" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/05e99ebf61238a70227b4d9cc02d0030d34f6339", + "reference": "05e99ebf61238a70227b4d9cc02d0030d34f6339", + "shasum": "" + }, + "require": { + "composer/pcre": "^1||^2||^3", + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-filter": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "maennchen/zipstream-php": "^2.1 || ^3.0", + "markbaker/complex": "^3.0", + "markbaker/matrix": "^3.0", + "php": "^8.2", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-main", + "dompdf/dompdf": "^2.0 || ^3.0", + "ext-intl": "*", + "friendsofphp/php-cs-fixer": "^3.2", + "mitoteam/jpgraph": "^10.5", + "mpdf/mpdf": "^8.1.1", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/phpstan": "^1.1 || ^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", + "phpstan/phpstan-phpunit": "^1.0 || ^2.0", + "phpunit/phpunit": "^10.5 || ^11.0", + "squizlabs/php_codesniffer": "^3.7", + "tecnickcom/tcpdf": "^6.5" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard and StringHelper::setLocale()", + "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + }, + { + "name": "Owen Leibman" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.9.0" + }, + "time": "2026-07-12T19:17:39+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.5",