From 3d6612e35475e5c7914f33becb72709ab724b2fb Mon Sep 17 00:00:00 2001 From: danielhe4rt Date: Sun, 22 Mar 2026 22:11:21 -0300 Subject: [PATCH 1/8] remove: old admin panel --- .../Resources/Messages/MessageResource.php | 48 ----- .../Messages/Pages/CreateMessage.php | 13 -- .../Resources/Messages/Pages/EditMessage.php | 21 --- .../Resources/Messages/Pages/ListMessages.php | 21 --- .../Messages/Schemas/MessageForm.php | 68 ------- .../Messages/Tables/MessagesTable.php | 58 ------ .../Resources/Feedback/FeedbackResource.php | 48 ----- .../Feedback/Pages/CreateFeedback.php | 13 -- .../Resources/Feedback/Pages/EditFeedback.php | 21 --- .../Resources/Feedback/Pages/ListFeedback.php | 21 --- .../Feedback/Schemas/FeedbackForm.php | 64 ------- .../Feedback/Tables/FeedbackTable.php | 56 ------ .../EventAgenda/EventAgendaResource.php | 169 ------------------ .../EventAgenda/Pages/CreateEventAgenda.php | 20 --- .../EventAgenda/Pages/EditEventAgenda.php | 25 --- .../EventAgenda/Pages/ListEventAgendas.php | 21 --- .../Admin/Resources/Events/EventResource.php | 63 ------- .../Resources/Events/Pages/CreateEvent.php | 13 -- .../Resources/Events/Pages/EditEvent.php | 21 --- .../Resources/Events/Pages/ListEvents.php | 21 --- .../AttendeesRelationManager.php | 60 ------- .../RelationManagers/TalksRelationManager.php | 40 ----- .../Resources/Events/Schemas/EventForm.php | 107 ----------- .../Resources/Events/Tables/EventsTable.php | 59 ------ .../Resources/Talks/Pages/CreateTalk.php | 13 -- .../Admin/Resources/Talks/Pages/EditTalk.php | 21 --- .../Admin/Resources/Talks/Pages/ListTalks.php | 21 --- .../Resources/Talks/Schemas/TalkForm.php | 78 -------- .../Resources/Talks/Tables/TalksTable.php | 40 ----- .../Admin/Resources/Talks/TalkResource.php | 55 ------ .../Resources/Badges/BadgeResource.php | 48 ----- .../Resources/Badges/Pages/CreateBadge.php | 13 -- .../Resources/Badges/Pages/EditBadge.php | 21 --- .../Resources/Badges/Pages/ListBadges.php | 21 --- .../Resources/Badges/Schemas/BadgeForm.php | 64 ------- .../Resources/Badges/Tables/BadgesTable.php | 52 ------ .../Resources/Seasons/Pages/CreateSeason.php | 13 -- .../Resources/Seasons/Pages/EditSeason.php | 21 --- .../Resources/Seasons/Pages/ListSeasons.php | 21 --- .../Resources/Seasons/Schemas/SeasonForm.php | 55 ------ .../Resources/Seasons/SeasonResource.php | 48 ----- .../Resources/Seasons/Tables/SeasonsTable.php | 59 ------ .../Shared/Widgets/SeasonStatsOverview.php | 55 ------ .../Resources/Tenants/Pages/CreateTenant.php | 13 -- .../Resources/Tenants/Pages/EditTenant.php | 21 --- .../Resources/Tenants/Pages/ListTenants.php | 21 --- .../EventsRelationManager.php | 34 ---- .../MembersRelationManager.php | 107 ----------- .../Resources/Tenants/Schemas/TenantForm.php | 52 ------ .../Resources/Tenants/Tables/TenantsTable.php | 38 ---- .../Resources/Tenants/TenantResource.php | 65 ------- .../Resources/Users/Pages/CreateUser.php | 13 -- .../Admin/Resources/Users/Pages/EditUser.php | 108 ----------- .../Admin/Resources/Users/Pages/ListUsers.php | 29 --- .../Resources/Users/Schemas/UserForm.php | 44 ----- .../Resources/Users/Tables/UsersTable.php | 41 ----- .../Admin/Resources/Users/UserResource.php | 58 ------ 57 files changed, 2434 deletions(-) delete mode 100644 app-modules/activity/src/Filament/Admin/Resources/Messages/MessageResource.php delete mode 100644 app-modules/activity/src/Filament/Admin/Resources/Messages/Pages/CreateMessage.php delete mode 100644 app-modules/activity/src/Filament/Admin/Resources/Messages/Pages/EditMessage.php delete mode 100644 app-modules/activity/src/Filament/Admin/Resources/Messages/Pages/ListMessages.php delete mode 100644 app-modules/activity/src/Filament/Admin/Resources/Messages/Schemas/MessageForm.php delete mode 100644 app-modules/activity/src/Filament/Admin/Resources/Messages/Tables/MessagesTable.php delete mode 100644 app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/FeedbackResource.php delete mode 100644 app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Pages/CreateFeedback.php delete mode 100644 app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Pages/EditFeedback.php delete mode 100644 app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Pages/ListFeedback.php delete mode 100644 app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Schemas/FeedbackForm.php delete mode 100644 app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Tables/FeedbackTable.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/EventAgenda/EventAgendaResource.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/EventAgenda/Pages/CreateEventAgenda.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/EventAgenda/Pages/EditEventAgenda.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/EventAgenda/Pages/ListEventAgendas.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/EventResource.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/Pages/CreateEvent.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/Pages/EditEvent.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/Pages/ListEvents.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/RelationManagers/AttendeesRelationManager.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/RelationManagers/TalksRelationManager.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/Schemas/EventForm.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Events/Tables/EventsTable.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Talks/Pages/CreateTalk.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Talks/Pages/EditTalk.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Talks/Pages/ListTalks.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Talks/Schemas/TalkForm.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Talks/Tables/TalksTable.php delete mode 100644 app-modules/events/src/Filament/Admin/Resources/Talks/TalkResource.php delete mode 100644 app-modules/gamification/src/Badge/Filament/Resources/Badges/BadgeResource.php delete mode 100644 app-modules/gamification/src/Badge/Filament/Resources/Badges/Pages/CreateBadge.php delete mode 100644 app-modules/gamification/src/Badge/Filament/Resources/Badges/Pages/EditBadge.php delete mode 100644 app-modules/gamification/src/Badge/Filament/Resources/Badges/Pages/ListBadges.php delete mode 100644 app-modules/gamification/src/Badge/Filament/Resources/Badges/Schemas/BadgeForm.php delete mode 100644 app-modules/gamification/src/Badge/Filament/Resources/Badges/Tables/BadgesTable.php delete mode 100644 app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Pages/CreateSeason.php delete mode 100644 app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Pages/EditSeason.php delete mode 100644 app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Pages/ListSeasons.php delete mode 100644 app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Schemas/SeasonForm.php delete mode 100644 app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/SeasonResource.php delete mode 100644 app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Tables/SeasonsTable.php delete mode 100644 app-modules/gamification/src/Season/Filament/Shared/Widgets/SeasonStatsOverview.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/Pages/CreateTenant.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/Pages/EditTenant.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/Pages/ListTenants.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/RelationManagers/EventsRelationManager.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/RelationManagers/MembersRelationManager.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/Schemas/TenantForm.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/Tables/TenantsTable.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Tenants/TenantResource.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Users/Pages/CreateUser.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Users/Pages/EditUser.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Users/Pages/ListUsers.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Users/Schemas/UserForm.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Users/Tables/UsersTable.php delete mode 100644 app-modules/identity/src/Filament/Admin/Resources/Users/UserResource.php diff --git a/app-modules/activity/src/Filament/Admin/Resources/Messages/MessageResource.php b/app-modules/activity/src/Filament/Admin/Resources/Messages/MessageResource.php deleted file mode 100644 index 1c95155e..00000000 --- a/app-modules/activity/src/Filament/Admin/Resources/Messages/MessageResource.php +++ /dev/null @@ -1,48 +0,0 @@ - ListMessages::route('/'), - 'create' => CreateMessage::route('/create'), - 'edit' => EditMessage::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/activity/src/Filament/Admin/Resources/Messages/Pages/CreateMessage.php b/app-modules/activity/src/Filament/Admin/Resources/Messages/Pages/CreateMessage.php deleted file mode 100644 index 546c2393..00000000 --- a/app-modules/activity/src/Filament/Admin/Resources/Messages/Pages/CreateMessage.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - Select::make('external_identity_id') - ->label('Provider') - ->getOptionLabelFromRecordUsing(fn (ExternalIdentity $record) => $record->provider->getLabel()) - ->preload() - ->searchable() - ->relationship( - name: 'provider', - titleAttribute: 'provider', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - - TextInput::make('channel_id') - ->label('Chanel') - ->nullable(), - - Select::make('tenant_id') - ->label('Tenant') - ->preload() - ->searchable() - ->relationship( - name: 'tenant', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->nullable(), - - TextInput::make('provider_message_id') - ->label('Message ID at Provider') - ->maxLength(100) - ->nullable(), - - Textarea::make('content') - ->label('Content') - ->rows(5) - ->required(), - - DateTimePicker::make('sent_at') - ->label('Sent at') - ->nullable(), - - TextInput::make('obtained_experience') - ->label('Experience Gained') - ->numeric() - ->nullable(), - ]); - } -} diff --git a/app-modules/activity/src/Filament/Admin/Resources/Messages/Tables/MessagesTable.php b/app-modules/activity/src/Filament/Admin/Resources/Messages/Tables/MessagesTable.php deleted file mode 100644 index 42e9d8ec..00000000 --- a/app-modules/activity/src/Filament/Admin/Resources/Messages/Tables/MessagesTable.php +++ /dev/null @@ -1,58 +0,0 @@ -columns([ - TextColumn::make('provider.provider') - ->badge() - ->label('Provider') - ->sortable() - ->searchable(), - - TextColumn::make('channel_id') - ->label('Channel') - ->sortable() - ->searchable(), - - TextColumn::make('content') - ->label('Content') - ->limit(60) - ->wrap(), - - TextColumn::make('sent_at') - ->label('Sent') - ->sortable(), - - TextColumn::make('obtained_experience') - ->label('Obteined XP') - ->numeric() - ->sortable(), - - TextColumn::make('created_at') - ->label('Created') - ->dateTime('d/m/Y H:i') - ->sortable(), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/FeedbackResource.php b/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/FeedbackResource.php deleted file mode 100644 index 3c8258b5..00000000 --- a/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/FeedbackResource.php +++ /dev/null @@ -1,48 +0,0 @@ - ListFeedback::route('/'), - 'create' => CreateFeedback::route('/create'), - 'edit' => EditFeedback::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Pages/CreateFeedback.php b/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Pages/CreateFeedback.php deleted file mode 100644 index 7066ecab..00000000 --- a/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Pages/CreateFeedback.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - Select::make('sender_id') - ->label('Sender') - ->preload() - ->searchable() - ->relationship( - name: 'sender', - titleAttribute: 'username', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - - Select::make('target_id') - ->label('Target') - ->preload() - ->searchable() - ->relationship( - name: 'target', - titleAttribute: 'username', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - - Select::make('tenant_id') - ->label('Target') - ->preload() - ->searchable() - ->relationship( - name: 'tenant', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - - TextInput::make('type') - ->label('Type') - ->required() - ->maxLength(50), - - Textarea::make('message') - ->label('Message') - ->required() - ->rows(5) - ->maxLength(500), - ]); - } -} diff --git a/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Tables/FeedbackTable.php b/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Tables/FeedbackTable.php deleted file mode 100644 index 64113396..00000000 --- a/app-modules/community/src/Feedback/Filament/Admin/Resources/Feedback/Tables/FeedbackTable.php +++ /dev/null @@ -1,56 +0,0 @@ -columns([ - TextColumn::make('sender.username') - ->label('Sender') - ->sortable() - ->searchable(), - - TextColumn::make('target.username') - ->label('Target') - ->sortable() - ->searchable(), - - TextColumn::make('type') - ->label('Type') - ->sortable(), - - TextColumn::make('message') - ->label('Message') - ->limit(50) - ->wrap(), - - TextColumn::make('review.id') - ->label('Review') - ->sortable(), - - TextColumn::make('created_at') - ->label('Created') - ->dateTime('d/m/Y H:i') - ->sortable(), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/EventAgenda/EventAgendaResource.php b/app-modules/events/src/Filament/Admin/Resources/EventAgenda/EventAgendaResource.php deleted file mode 100644 index 836879dd..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/EventAgenda/EventAgendaResource.php +++ /dev/null @@ -1,169 +0,0 @@ -components([ - Select::make('tenant_id') - ->relationship('tenant', 'name') - ->required(), - Select::make('event_id') - ->relationship( - 'event', - 'title', - ) - ->required(), - - MorphToSelect::make('schedulable') - ->types([ - Type::make(EventSubmission::class) - ->titleAttribute('title'), - Type::make(EventSegment::class) - ->titleAttribute('title'), - ]), - - Fieldset::make('Schedule') - ->schema([ - TimePicker::make('starting_at') - ->native(false) - ->required(), - - TimePicker::make('ending_at') - ->native(false) - ->required(), - ]), - - TextEntry::make('created_at') - ->label('Created Date') - ->state(fn (?EventAgenda $record): string => $record?->created_at?->diffForHumans() ?? '-'), - - TextEntry::make('updated_at') - ->label('Last Modified Date') - ->state(fn (?EventAgenda $record): string => $record?->updated_at?->diffForHumans() ?? '-'), - ]); - } - - public static function table(Table $table): Table - { - return $table - ->columns([ - TextColumn::make('tenant.name') - ->searchable() - ->sortable(), - - TextColumn::make('event.title') - ->searchable() - ->sortable(), - - TextColumn::make('schedulable_type'), - - TextColumn::make('schedulable_id'), - - TextColumn::make('starting_at'), - - TextColumn::make('ending_at'), - ]) - ->filters([ - TrashedFilter::make(), - ]) - ->recordActions([ - EditAction::make(), - DeleteAction::make(), - RestoreAction::make(), - ForceDeleteAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - RestoreBulkAction::make(), - ForceDeleteBulkAction::make(), - ]), - ]); - } - - public static function getPages(): array - { - return [ - 'index' => ListEventAgendas::route('/'), - 'create' => CreateEventAgenda::route('/create'), - 'edit' => EditEventAgenda::route('/{record}/edit'), - ]; - } - - public static function getEloquentQuery(): Builder - { - return parent::getEloquentQuery() - ->withoutGlobalScopes([ - SoftDeletingScope::class, - ]); - } - - public static function getGlobalSearchEloquentQuery(): Builder - { - return parent::getGlobalSearchEloquentQuery()->with(['tenant', 'event']); - } - - public static function getGloballySearchableAttributes(): array - { - return ['tenant.name', 'event.title']; - } - - public static function getGlobalSearchResultDetails(Model $record): array - { - /** @var EventAgenda $record */ - $details = []; - - if ($record->tenant) { - $details['Tenant'] = $record->tenant->name; - } - - if ($record->event) { - $details['Event'] = $record->event->title; - } - - return $details; - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/EventAgenda/Pages/CreateEventAgenda.php b/app-modules/events/src/Filament/Admin/Resources/EventAgenda/Pages/CreateEventAgenda.php deleted file mode 100644 index 35e5c7ac..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/EventAgenda/Pages/CreateEventAgenda.php +++ /dev/null @@ -1,20 +0,0 @@ - ListEvents::route('/'), - 'create' => CreateEvent::route('/create'), - 'edit' => EditEvent::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/Events/Pages/CreateEvent.php b/app-modules/events/src/Filament/Admin/Resources/Events/Pages/CreateEvent.php deleted file mode 100644 index dfe24965..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/Events/Pages/CreateEvent.php +++ /dev/null @@ -1,13 +0,0 @@ -attendees()->count(); - } - - public static function getIcon(Model $ownerRecord, string $pageClass): string|BackedEnum|null - { - return Heroicon::Users; - } - - public function table(Table $table): Table - { - return $table - ->columns([ - TextColumn::make('username'), - TextColumn::make('email'), - IconColumn::make('is_donator'), - TextColumn::make('pivot.status') - ->label('Status') - ->badge(), - ]) - ->recordActions([ - DetachAction::make() - ->using(function (User $record): void { - /** @var EventModel $ownerRecord */ - $ownerRecord = $this->getOwnerRecord(); - $ownerRecord->leave($record->getKey()); - }), - ]); - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/Events/RelationManagers/TalksRelationManager.php b/app-modules/events/src/Filament/Admin/Resources/Events/RelationManagers/TalksRelationManager.php deleted file mode 100644 index 79955d2c..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/Events/RelationManagers/TalksRelationManager.php +++ /dev/null @@ -1,40 +0,0 @@ -talks()->count(); - } - - public static function getIcon(Model $ownerRecord, string $pageClass): string|BackedEnum|null - { - return Heroicon::Microphone; - } - - public function table(Table $table): Table - { - return $table - ->headerActions([ - CreateAction::make(), - ]); - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/Events/Schemas/EventForm.php b/app-modules/events/src/Filament/Admin/Resources/Events/Schemas/EventForm.php deleted file mode 100644 index 44cc84d1..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/Events/Schemas/EventForm.php +++ /dev/null @@ -1,107 +0,0 @@ -components([ - Flex::make([ - Section::make('Informações Gerais') - ->schema([ - Select::make('tenant_id') - ->label('Tenant') - ->relationship('tenant', 'name') - ->required(), - - TextInput::make('title') - ->label('Title') - ->minLength(5) - ->maxLength(255) - ->afterStateUpdated(fn ($state, Set $set) => $set('slug', Str::slug($state))) - ->required(), - - TextInput::make('slug') - ->required(), - - Select::make('event_type') - ->label('Event Type') - ->enum(EventTypeEnum::class) - ->options(EventTypeEnum::class) - ->required(), - ]) - ->columns(2), - ]), - - Flex::make([ - Section::make('Local e Capacidade') - ->schema([ - Grid::make(2)->schema([ - TextInput::make('location') - ->label('Location') - ->minLength(5) - ->maxLength(255) - ->required(), - - TextInput::make('max_attendees') - ->numeric() - ->minValue(1) - ->label('Max Attendees') - ->required(), - ]), - ]), - Section::make('Status') - ->schema([ - Toggle::make('active') - ->label('Active') - ->required(), - ]), - ]), - - Section::make('Datas e Horários') - ->schema([ - Grid::make(3)->schema([ - DateTimePicker::make('event_at') - ->label('Event Date') - ->required(), - - DateTimePicker::make('start_at') - ->label('Start Hour') - ->required(), - - DateTimePicker::make('end_at') - ->label('End Hour') - ->after('start_at') - ->required(), - ]), - ]), - - Section::make('Conteúdo') - ->schema([ - RichEditor::make('description') - ->label('Description') - ->minLength(5) - ->maxLength(255) - ->required(), - ]), - ]) - ->columns(1); - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/Events/Tables/EventsTable.php b/app-modules/events/src/Filament/Admin/Resources/Events/Tables/EventsTable.php deleted file mode 100644 index 1061ebea..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/Events/Tables/EventsTable.php +++ /dev/null @@ -1,59 +0,0 @@ -columns([ - TextColumn::make('title') - ->limit(20) - ->searchable(), - - TextColumn::make('location') - ->searchable(), - TextColumn::make('event_type') - ->badge() - ->searchable(), - - IconColumn::make('active') - ->sortable() - ->boolean(), - - TextColumn::make('attendees_count') - ->label('Inscritos') - ->sortable() - ->formatStateUsing(fn (string $state, $record) => sprintf('%s/%s', $state, $record->max_attendees)), - - TextColumn::make('talks_count') - ->label('Submissions') - ->sortable() - ->counts('talks'), - - TextColumn::make('event_at') - ->sortable() - ->date(), - - TextColumn::make('start_at') - ->label('EventModel Hour') - ->formatStateUsing(fn ($state) => $state->format('d/m/Y H:i')) - ->description(fn ($record) => $record->end_at->format('d/m/Y H:i')) - ->sortable(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/Talks/Pages/CreateTalk.php b/app-modules/events/src/Filament/Admin/Resources/Talks/Pages/CreateTalk.php deleted file mode 100644 index c0cf24a4..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/Talks/Pages/CreateTalk.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - - Flex::make([ - Section::make('Proposta da Palestra') - ->description('Defina o evento, título e tipo da sua proposta.') - ->icon('heroicon-m-clipboard-document-list') - ->schema([ - TextInput::make('title') - ->label('Título da Proposta') - ->minLength(3) - ->maxlength(255) - ->required() - ->columnSpanFull(), - - Select::make('tenant_id') - ->label('Tenant') - ->relationship('tenant', 'name') - ->required() - ->live() - ->columnSpan(1), - - Select::make('user_id') - ->label('User') - ->relationship('user', 'username') - ->required() - ->live() - ->columnSpan(1), - - TextInput::make('field_type') - ->label('Tipo') - ->minLength(3) - ->maxlength(255) - ->required() - ->columnSpan(1), - - Select::make('status') - ->label('Status') - ->options(TalkStatusEnum::class) - ->required() - ->default(TalkStatusEnum::Pending), - ]) - ->columnSpan(2), - ]) - ->columnSpanFull(), - - Section::make('Detalhes e Conteúdo') - ->description('Forneça a descrição completa da sua palestra e o que o público aprenderá.') - ->icon('heroicon-m-document-text') - ->schema([ - RichEditor::make('description') - ->label('Descrição Completa') - ->required() - ->columnSpanFull(), - ]) - ->columnSpanFull(), - - ]); - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/Talks/Tables/TalksTable.php b/app-modules/events/src/Filament/Admin/Resources/Talks/Tables/TalksTable.php deleted file mode 100644 index 4a3b7ee1..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/Talks/Tables/TalksTable.php +++ /dev/null @@ -1,40 +0,0 @@ -columns([ - TextColumn::make('title') - ->description(fn ($record) => $record->user->name) - ->searchable(), - TextColumn::make('description') - ->limit(30) - ->searchable(), - TextColumn::make('field_type') - ->searchable(), - TextColumn::make('status') - ->badge() - ->searchable(), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/events/src/Filament/Admin/Resources/Talks/TalkResource.php b/app-modules/events/src/Filament/Admin/Resources/Talks/TalkResource.php deleted file mode 100644 index 353b809c..00000000 --- a/app-modules/events/src/Filament/Admin/Resources/Talks/TalkResource.php +++ /dev/null @@ -1,55 +0,0 @@ - ListTalks::route('/'), - 'create' => CreateTalk::route('/create'), - 'edit' => EditTalk::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/gamification/src/Badge/Filament/Resources/Badges/BadgeResource.php b/app-modules/gamification/src/Badge/Filament/Resources/Badges/BadgeResource.php deleted file mode 100644 index 5be65e61..00000000 --- a/app-modules/gamification/src/Badge/Filament/Resources/Badges/BadgeResource.php +++ /dev/null @@ -1,48 +0,0 @@ - ListBadges::route('/'), - 'create' => CreateBadge::route('/create'), - 'edit' => EditBadge::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/gamification/src/Badge/Filament/Resources/Badges/Pages/CreateBadge.php b/app-modules/gamification/src/Badge/Filament/Resources/Badges/Pages/CreateBadge.php deleted file mode 100644 index 8010389a..00000000 --- a/app-modules/gamification/src/Badge/Filament/Resources/Badges/Pages/CreateBadge.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - Section::make() - ->description('Badge Information') - ->icon(Heroicon::Tag) - ->schema([ - Section::make() - ->description('Administration Area') - ->schema([ - Select::make('tenant_id') - ->preload() - ->searchable() - ->relationship( - name: 'tenant', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - Select::make('provider') - ->enum(IdentityProvider::class) - ->options(IdentityProvider::class) - ->required(), - Toggle::make('active') - ->required(), - TextInput::make('redeem_code') - ->required(), - ]), - TextInput::make('name') - ->minLength(3) - ->maxLength(255) - ->required(), - RichEditor::make('description') - ->required() - ->columnSpanFull(), - SpatieMediaLibraryFileUpload::make('badge') - ->collection('badge') - ->image() - ->required(), - ]) - ->columnSpanFull(), - ]); - } -} diff --git a/app-modules/gamification/src/Badge/Filament/Resources/Badges/Tables/BadgesTable.php b/app-modules/gamification/src/Badge/Filament/Resources/Badges/Tables/BadgesTable.php deleted file mode 100644 index 1a24d879..00000000 --- a/app-modules/gamification/src/Badge/Filament/Resources/Badges/Tables/BadgesTable.php +++ /dev/null @@ -1,52 +0,0 @@ -columns([ - TextColumn::make('provider') - ->badge() - ->searchable(), - TextColumn::make('name') - ->searchable(), - ImageColumn::make('image_url'), - TextColumn::make('redeem_code') - ->searchable(), - IconColumn::make('active') - ->boolean(), - TextColumn::make('created_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('updated_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('tenant_id') - ->numeric() - ->sortable(), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Pages/CreateSeason.php b/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Pages/CreateSeason.php deleted file mode 100644 index 7ea63aec..00000000 --- a/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Pages/CreateSeason.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - Select::make('tenant_id') - ->preload() - ->searchable() - ->relationship( - name: 'tenant', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - TextInput::make('name') - ->required(), - RichEditor::make('description') - ->required() - ->columnSpanFull(), - DateTimePicker::make('started_at'), - DateTimePicker::make('ended_at') - ->after('started_at'), - TextInput::make('messages_count') - ->required() - ->numeric() - ->default(0), - TextInput::make('participants_count') - ->required() - ->numeric() - ->default(0), - TextInput::make('meeting_count') - ->required() - ->numeric() - ->default(0), - TextInput::make('badges_count') - ->required() - ->numeric() - ->default(0), - ]); - } -} diff --git a/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/SeasonResource.php b/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/SeasonResource.php deleted file mode 100644 index 7cf025a0..00000000 --- a/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/SeasonResource.php +++ /dev/null @@ -1,48 +0,0 @@ - ListSeasons::route('/'), - 'create' => CreateSeason::route('/create'), - 'edit' => EditSeason::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Tables/SeasonsTable.php b/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Tables/SeasonsTable.php deleted file mode 100644 index 94bbc8c6..00000000 --- a/app-modules/gamification/src/Season/Filament/Admin/Resources/Seasons/Tables/SeasonsTable.php +++ /dev/null @@ -1,59 +0,0 @@ -columns([ - TextColumn::make('id') - ->label('ID') - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('name') - ->searchable(), - TextColumn::make('started_at') - ->label('Season') - ->formatStateUsing(fn ($state) => $state->format('d/m/Y H:i')) - ->description(fn ($record) => $record->ended_at?->format('d/m/Y H:i')) - ->sortable(), - TextColumn::make('messages_count') - ->numeric() - ->sortable(), - TextColumn::make('participants_count') - ->numeric() - ->sortable(), - TextColumn::make('meeting_count') - ->numeric() - ->sortable(), - TextColumn::make('badges_count') - ->numeric() - ->sortable(), - TextColumn::make('created_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('updated_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/gamification/src/Season/Filament/Shared/Widgets/SeasonStatsOverview.php b/app-modules/gamification/src/Season/Filament/Shared/Widgets/SeasonStatsOverview.php deleted file mode 100644 index b13c634e..00000000 --- a/app-modules/gamification/src/Season/Filament/Shared/Widgets/SeasonStatsOverview.php +++ /dev/null @@ -1,55 +0,0 @@ -where('started_at', '<=', now()) - ->where(fn (Builder $q) => $q->whereNull('ended_at') - ->orWhere('ended_at', '>', now()) - ) - ->latest('started_at') - ->first(); - - if (! $season) { - return [ - Stat::make('Season ativa', 'Nenhuma') - ->description('Não há season em andamento') - ->color('gray'), - ]; - } - - return [ - Stat::make('Season ativa', $season->name) - ->description( - $season->ended_at - ? 'Finalizada em '.$season->ended_at->diffForHumans() - : 'Iniciada em '.$season->started_at->diffForHumans() - ) - ->descriptionIcon('heroicon-o-flag') - ->color($season->ended_at ? 'gray' : 'primary'), - - Stat::make('Mensagens processadas', $season->messages_count) - ->description('Total de mensagens registradas') - ->descriptionIcon('heroicon-o-chat-bubble-left-right') - ->color('success'), - - Stat::make('Participantes', $season->participants_count) - ->description('Usuários ativos na season') - ->descriptionIcon('heroicon-o-users') - ->color('warning'), - ]; - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Tenants/Pages/CreateTenant.php b/app-modules/identity/src/Filament/Admin/Resources/Tenants/Pages/CreateTenant.php deleted file mode 100644 index 5bd5bc5f..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Tenants/Pages/CreateTenant.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - TextInput::make('username') - ->required(), - TextInput::make('name') - ->required(), - TextInput::make('email') - ->label('Email address') - ->email(), - TextInput::make('password') - ->password(), - Toggle::make('is_donator') - ->required(), - ]); - } - - public function infolist(Schema $schema): Schema - { - return $schema - ->components([ - TextEntry::make('id') - ->label('ID'), - TextEntry::make('username'), - TextEntry::make('name'), - TextEntry::make('email') - ->label('Email address') - ->placeholder('-'), - IconEntry::make('is_donator') - ->boolean(), - TextEntry::make('created_at') - ->dateTime() - ->placeholder('-'), - TextEntry::make('updated_at') - ->dateTime() - ->placeholder('-'), - ]); - } - - public function table(Table $table): Table - { - return $table - ->recordTitleAttribute('name') - ->columns([ - TextColumn::make('id') - ->label('ID') - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('username') - ->searchable(), - TextColumn::make('name') - ->searchable(), - TextColumn::make('email') - ->label('Email address') - ->searchable(), - IconColumn::make('is_donator') - ->boolean(), - TextColumn::make('created_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('updated_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - ]) - ->headerActions([ - AttachAction::make(), - ]) - ->recordActions([ - ViewAction::make(), - EditAction::make(), - DetachAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DetachBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Tenants/Schemas/TenantForm.php b/app-modules/identity/src/Filament/Admin/Resources/Tenants/Schemas/TenantForm.php deleted file mode 100644 index c2dca3e5..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Tenants/Schemas/TenantForm.php +++ /dev/null @@ -1,52 +0,0 @@ -components([ - Section::make() - ->schema([ - TextInput::make('name') - ->minLength(3) - ->maxLength(255) - ->afterStateUpdated(fn ($state, Set $set) => $set('slug', Str::slug($state))) - ->live(debounce: 500) - ->required(), - TextInput::make('domain') - ->required(), - TextInput::make('slug') - ->readonly() - ->partiallyRenderComponentsAfterStateUpdated(['name']) - ->required(), - Select::make('owner_id') - ->native(false) - ->searchable() - ->preload() - ->relationship( - name: 'owner', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - Toggle::make('active') - ->required(), - ]) - ->columnSpanFull(), - ]); - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Tenants/Tables/TenantsTable.php b/app-modules/identity/src/Filament/Admin/Resources/Tenants/Tables/TenantsTable.php deleted file mode 100644 index 8e8f31e2..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Tenants/Tables/TenantsTable.php +++ /dev/null @@ -1,38 +0,0 @@ -columns([ - TextColumn::make('name') - ->searchable(), - TextColumn::make('slug') - ->searchable(), - TextColumn::make('owner.name') - ->searchable(), - IconColumn::make('active') - ->boolean(), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Tenants/TenantResource.php b/app-modules/identity/src/Filament/Admin/Resources/Tenants/TenantResource.php deleted file mode 100644 index 83759b9f..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Tenants/TenantResource.php +++ /dev/null @@ -1,65 +0,0 @@ - ListTenants::route('/'), - 'create' => CreateTenant::route('/create'), - 'edit' => EditTenant::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Users/Pages/CreateUser.php b/app-modules/identity/src/Filament/Admin/Resources/Users/Pages/CreateUser.php deleted file mode 100644 index d1bd92c5..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Users/Pages/CreateUser.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - Tabs::make('UserTabs') - ->tabs([ - Tab::make('General') - ->schema([ - Section::make('General Information') - ->description('Basic user details') - ->schema(fn (Schema $schema) => UserForm::configure($schema)), - ]), - - Tab::make('Address') - ->schema(fn (Schema $schema) => UserAddressForm::form($schema)), - - Tab::make('Information') - ->schema([ - Section::make('Information') - ->description('Additional profile information') - ->relationship('information') - ->schema(fn (Schema $schema) => UserInformationForm::configure($schema)), - ]), - - Tab::make('Gamefication') - ->schema([ - Section::make('Gamefication') - ->description('Player and progression data') - ->schema([ - TextEntry::make('character.tenant.name') - ->label('Tenant'), - - TextEntry::make('character.reputation') - ->label('Reputation'), - - TextEntry::make('character.experience') - ->label('Experience'), - - TextEntry::make('character.daily_bonus_claimed_at') - ->label('Daily Bonus Claimed At') - ->formatStateUsing(fn ($state - ) => $state ? Date::parse($state)->format('Y-m-d') : ''), - ])->columns(4), - ]), - Tab::make('Providers') - ->schema([ - Section::make('Providers') - ->description('Connected OAuth providers') - ->schema([ - Repeater::make('providers') - ->relationship('providers') - ->schema([ - TextEntry::make('provider') - ->label('Provider'), - - TextEntry::make('external_account_id') - ->label('External Account ID'), - - TextEntry::make('metadata.email') - ->label('Email'), - - TextEntry::make('metadata.username') - ->label('Username'), - - TextEntry::make('connected_at') - ->label('Connected At') - ->dateTime(), - ]) - ->columns(3) - ->addable(false) - ->deletable(false), - ]), - ]), - ]) - ->columnSpan('full'), - ]); - } - - protected function getHeaderActions(): array - { - return [ - DeleteAction::make(), - ]; - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Users/Pages/ListUsers.php b/app-modules/identity/src/Filament/Admin/Resources/Users/Pages/ListUsers.php deleted file mode 100644 index 52906acf..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Users/Pages/ListUsers.php +++ /dev/null @@ -1,29 +0,0 @@ -components([ - TextInput::make('username') - ->label('Nome de usuário') - ->placeholder('ex.: joao123') - ->required() - ->minLength(3) - ->maxLength(50), - - TextInput::make('name') - ->label('Nome completo') - ->placeholder('Nome e sobrenome') - ->required() - ->maxLength(100), - - TextInput::make('email') - ->label('E-mail') - ->email() - ->placeholder('ex.: usuario@dominio.com') - ->required() - ->maxLength(255), - - TextInput::make('password') - ->label('Senha') - ->password() - ->placeholder('Mínimo de 8 caracteres') - ->required() - ->minLength(8), - ]); - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Users/Tables/UsersTable.php b/app-modules/identity/src/Filament/Admin/Resources/Users/Tables/UsersTable.php deleted file mode 100644 index 314dbe07..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Users/Tables/UsersTable.php +++ /dev/null @@ -1,41 +0,0 @@ -columns([ - TextColumn::make('username') - ->searchable() - ->sortable(), - TextColumn::make('name') - ->searchable() - ->sortable(), - TextColumn::make('email') - ->searchable() - ->sortable(), - IconColumn::make('is_donator') - ->sortable(), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/identity/src/Filament/Admin/Resources/Users/UserResource.php b/app-modules/identity/src/Filament/Admin/Resources/Users/UserResource.php deleted file mode 100644 index 304ed5ee..00000000 --- a/app-modules/identity/src/Filament/Admin/Resources/Users/UserResource.php +++ /dev/null @@ -1,58 +0,0 @@ -remember('total_users', minutes(5), fn () => self::$model::count()) ?? 0)); - } - - public static function form(Schema $schema): Schema - { - return UserForm::configure($schema); - } - - public static function table(Table $table): Table - { - return UsersTable::configure($table); - } - - public static function getPages(): array - { - return [ - 'index' => ListUsers::route('/'), - 'create' => CreateUser::route('/create'), - 'edit' => EditUser::route('/{record}/edit'), - ]; - } -} From 83f7b1b4a5093be4173e3f1918670768511cce73 Mon Sep 17 00:00:00 2001 From: danielhe4rt Date: Sun, 22 Mar 2026 22:17:34 -0300 Subject: [PATCH 2/8] wip --- .../src/Providers/ActivityServiceProvider.php | 8 -- .../MeetingTypes/MeetingTypeResource.php | 55 ------- .../MeetingTypes/Pages/CreateMeetingType.php | 13 -- .../MeetingTypes/Pages/EditMeetingType.php | 21 --- .../MeetingTypes/Pages/ListMeetingTypes.php | 21 --- .../MeetingTypes/Schemas/MeetingTypeForm.php | 34 ----- .../MeetingTypes/Tables/MeetingTypesTable.php | 48 ------- .../Resources/Meetings/MeetingResource.php | 54 ------- .../Meetings/Pages/CreateMeeting.php | 13 -- .../Resources/Meetings/Pages/EditMeeting.php | 21 --- .../Resources/Meetings/Pages/ListMeetings.php | 21 --- .../Meetings/Schemas/MeetingForm.php | 91 ------------ .../Meetings/Tables/MeetingsTable.php | 52 ------- .../Providers/CommunityServiceProvider.php | 15 +- .../events/src/AdminEventPanelPlugin.php | 34 ----- .../EventSubmissionSpeakerResource.php | 136 ------------------ .../Pages/CreateEventSubmissionSpeaker.php | 20 --- .../Pages/EditEventSubmissionSpeaker.php | 25 ---- .../Pages/ListEventSubmissionSpeakers.php | 21 --- .../Sponsors/Pages/CreateSponsor.php | 13 -- .../Resources/Sponsors/Pages/EditSponsor.php | 21 --- .../Resources/Sponsors/Pages/ListSponsors.php | 21 --- .../Sponsors/Schemas/SponsorForm.php | 48 ------- .../Resources/Sponsors/SponsorResource.php | 56 -------- .../Sponsors/Tables/SponsorsTable.php | 36 ----- .../src/Providers/EventsServiceProvider.php | 2 - .../Providers/GamificationServiceProvider.php | 14 +- .../Shared/Widgets/UsersStatsOverview.php | 51 ------- .../src/Providers/IdentityServiceProvider.php | 12 +- .../EventsRelationManagerTest.php | 33 ----- .../EventsRelationManager.php | 45 ------ app/Providers/Filament/AdminPanelProvider.php | 16 --- 32 files changed, 4 insertions(+), 1067 deletions(-) delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/MeetingTypeResource.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Pages/EditMeetingType.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Pages/ListMeetingTypes.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Schemas/MeetingTypeForm.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/Meetings/MeetingResource.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/Meetings/Pages/CreateMeeting.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/Meetings/Pages/EditMeeting.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/Meetings/Pages/ListMeetings.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/Meetings/Schemas/MeetingForm.php delete mode 100644 app-modules/community/src/Meeting/Filament/Resources/Meetings/Tables/MeetingsTable.php delete mode 100644 app-modules/events/src/AdminEventPanelPlugin.php delete mode 100644 app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource.php delete mode 100644 app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource/Pages/CreateEventSubmissionSpeaker.php delete mode 100644 app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource/Pages/EditEventSubmissionSpeaker.php delete mode 100644 app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource/Pages/ListEventSubmissionSpeakers.php delete mode 100644 app-modules/events/src/Filament/Resources/Sponsors/Pages/CreateSponsor.php delete mode 100644 app-modules/events/src/Filament/Resources/Sponsors/Pages/EditSponsor.php delete mode 100644 app-modules/events/src/Filament/Resources/Sponsors/Pages/ListSponsors.php delete mode 100644 app-modules/events/src/Filament/Resources/Sponsors/Schemas/SponsorForm.php delete mode 100644 app-modules/events/src/Filament/Resources/Sponsors/SponsorResource.php delete mode 100644 app-modules/events/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php delete mode 100644 app-modules/identity/src/Filament/Shared/Widgets/UsersStatsOverview.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/EventsRelationManagerTest.php delete mode 100644 app/Filament/Shared/RelationManagers/EventsRelationManager.php diff --git a/app-modules/activity/src/Providers/ActivityServiceProvider.php b/app-modules/activity/src/Providers/ActivityServiceProvider.php index 435f5772..e5d4c4ce 100644 --- a/app-modules/activity/src/Providers/ActivityServiceProvider.php +++ b/app-modules/activity/src/Providers/ActivityServiceProvider.php @@ -13,14 +13,6 @@ class ActivityServiceProvider extends ServiceProvider { public function register(): void { - Panel::configureUsing(function (Panel $panel): void { - match ($panel->currentPanel()) { - FilamentPanel::Admin => $panel->resources([ - MessageResource::class, - ]), - default => null, - }; - }); } public function boot(): void diff --git a/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/MeetingTypeResource.php b/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/MeetingTypeResource.php deleted file mode 100644 index d6420b6a..00000000 --- a/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/MeetingTypeResource.php +++ /dev/null @@ -1,55 +0,0 @@ - ListMeetingTypes::route('/'), - 'create' => CreateMeetingType::route('/create'), - 'edit' => EditMeetingType::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php b/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php deleted file mode 100644 index e9051525..00000000 --- a/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - TextInput::make('name') - ->required(), - Select::make('week_day') - ->options([ - 1 => 'Monday', - 2 => 'Tuesday', - 3 => 'Wednesday', - 4 => 'Thursday', - 5 => 'Friday', - 6 => 'Saturday', - 7 => 'Sunday', - ]), - TimePicker::make('start_at') - ->required(), - ]); - } -} diff --git a/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php b/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php deleted file mode 100644 index 27d63bae..00000000 --- a/app-modules/community/src/Meeting/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php +++ /dev/null @@ -1,48 +0,0 @@ -columns([ - TextColumn::make('name') - ->searchable(), - TextColumn::make('week_day') - ->numeric() - ->sortable(), - TextColumn::make('start_at') - ->time() - ->sortable(), - TextColumn::make('created_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('updated_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - ]) - ->filters([ - - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/community/src/Meeting/Filament/Resources/Meetings/MeetingResource.php b/app-modules/community/src/Meeting/Filament/Resources/Meetings/MeetingResource.php deleted file mode 100644 index 1faf72e9..00000000 --- a/app-modules/community/src/Meeting/Filament/Resources/Meetings/MeetingResource.php +++ /dev/null @@ -1,54 +0,0 @@ - ListMeetings::route('/'), - 'create' => CreateMeeting::route('/create'), - 'edit' => EditMeeting::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/community/src/Meeting/Filament/Resources/Meetings/Pages/CreateMeeting.php b/app-modules/community/src/Meeting/Filament/Resources/Meetings/Pages/CreateMeeting.php deleted file mode 100644 index c861ce37..00000000 --- a/app-modules/community/src/Meeting/Filament/Resources/Meetings/Pages/CreateMeeting.php +++ /dev/null @@ -1,13 +0,0 @@ -components([ - Section::make('Administration Area') - ->description('Tenant and Administration') - ->schema([ - Select::make('tenant_id') - ->preload() - ->searchable() - ->relationship( - name: 'tenant', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - Select::make('admin_id') - ->preload() - ->searchable() - ->relationship( - name: 'admin', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - ]), - Section::make('Meeting Data') - ->description('Choose the Start and End') - ->schema([ - TimePicker::make('starts_at') - ->hoursStep(2) - ->required(), - TimePicker::make('ends_at') - ->hoursStep(2) - ->after('starts_at') - ->required(), - ]), - Section::make('Meeting Fields') - ->description('Meeting Region') - ->schema([ - RichEditor::make('content') - ->columnSpanFull(), - Select::make('meeting_type_id') - ->preload() - ->searchable() - ->relationship( - name: 'meetingType', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->createOptionForm([ - TextInput::make('name') - ->minLength(3) - ->maxLength(255) - ->required(), - Select::make('week_day') - ->options([ - 1 => 'Monday', - 2 => 'Tuesday', - 3 => 'Wednesday', - 4 => 'Thursday', - 5 => 'Friday', - 6 => 'Saturday', - 7 => 'Sunday', - ]) - ->required(), - TimePicker::make('start_at') - ->required(), - ]) - ->required(), - ]) - ->columnSpanFull(), - ]); - } -} diff --git a/app-modules/community/src/Meeting/Filament/Resources/Meetings/Tables/MeetingsTable.php b/app-modules/community/src/Meeting/Filament/Resources/Meetings/Tables/MeetingsTable.php deleted file mode 100644 index 007e37bc..00000000 --- a/app-modules/community/src/Meeting/Filament/Resources/Meetings/Tables/MeetingsTable.php +++ /dev/null @@ -1,52 +0,0 @@ -columns([ - TextColumn::make('tenant.name') - ->badge() - ->searchable() - ->sortable(), - TextColumn::make('admin.name') - ->label('Admin') - ->searchable() - ->badge(), - TextColumn::make('meetingType.name') - ->sortable(), - TextColumn::make('starts_at') - ->label('Meeting Hour') - ->formatStateUsing(fn ($state) => $state->format('d/m/Y H:i')) - ->description(fn ($record) => $record->ends_at->format('d/m/Y H:i')) - ->sortable(), - TextColumn::make('created_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('updated_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/community/src/Providers/CommunityServiceProvider.php b/app-modules/community/src/Providers/CommunityServiceProvider.php index 2e3383b7..84b69eb8 100644 --- a/app-modules/community/src/Providers/CommunityServiceProvider.php +++ b/app-modules/community/src/Providers/CommunityServiceProvider.php @@ -4,8 +4,6 @@ namespace He4rt\Community\Providers; -use App\Enums\FilamentPanel; -use Filament\Panel; use He4rt\Community\Feedback\Filament\Admin\Resources\Feedback\FeedbackResource; use He4rt\Community\Meeting\Filament\Resources\Meetings\MeetingResource; use He4rt\Community\Meeting\Filament\Resources\MeetingTypes\MeetingTypeResource; @@ -15,21 +13,10 @@ class CommunityServiceProvider extends ServiceProvider { public function register(): void { - Panel::configureUsing(function (Panel $panel): void { - match ($panel->currentPanel()) { - FilamentPanel::Admin => $panel - ->resources([ - MeetingResource::class, - MeetingTypeResource::class, - FeedbackResource::class, - ]), - default => null, - }; - }); } public function boot(): void { - $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); + $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations'); } } diff --git a/app-modules/events/src/AdminEventPanelPlugin.php b/app-modules/events/src/AdminEventPanelPlugin.php deleted file mode 100644 index 5be600f5..00000000 --- a/app-modules/events/src/AdminEventPanelPlugin.php +++ /dev/null @@ -1,34 +0,0 @@ -moduleName('event'); - } - - public function register(Panel $panel): void - { - $panel->resources([ - EventResource::class, - TalkResource::class, - EventAgendaResource::class, - SponsorResource::class, - ]); - - } - - public function boot(Panel $panel): void {} -} diff --git a/app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource.php b/app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource.php deleted file mode 100644 index f66b07d9..00000000 --- a/app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource.php +++ /dev/null @@ -1,136 +0,0 @@ -components([ - Select::make('event_id') - ->relationship('event', 'title') - ->searchable() - ->required(), - - Select::make('user_id') - ->relationship('user', 'name') - ->searchable() - ->required(), - - TextEntry::make('created_at') - ->label('Created Date') - ->state(fn (?EventSubmissionSpeaker $record): string => $record?->created_at?->diffForHumans() ?? '-'), - - TextEntry::make('updated_at') - ->label('Last Modified Date') - ->state(fn (?EventSubmissionSpeaker $record): string => $record?->updated_at?->diffForHumans() ?? '-'), - ]); - } - - public static function table(Table $table): Table - { - return $table - ->columns([ - TextColumn::make('event.title') - ->searchable() - ->sortable(), - - TextColumn::make('user.name') - ->searchable() - ->sortable(), - ]) - ->filters([ - TrashedFilter::make(), - ]) - ->recordActions([ - EditAction::make(), - DeleteAction::make(), - RestoreAction::make(), - ForceDeleteAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - RestoreBulkAction::make(), - ForceDeleteBulkAction::make(), - ]), - ]); - } - - public static function getPages(): array - { - return [ - 'index' => ListEventSubmissionSpeakers::route('/'), - 'create' => CreateEventSubmissionSpeaker::route('/create'), - 'edit' => EditEventSubmissionSpeaker::route('/{record}/edit'), - ]; - } - - public static function getEloquentQuery(): Builder - { - return parent::getEloquentQuery() - ->withoutGlobalScopes([ - SoftDeletingScope::class, - ]); - } - - public static function getGlobalSearchEloquentQuery(): Builder - { - return parent::getGlobalSearchEloquentQuery()->with(['submission.event', 'user']); - } - - public static function getGloballySearchableAttributes(): array - { - return ['submission.event.title', 'user.name']; - } - - public static function getGlobalSearchResultDetails(Model $record): array - { - /** @var EventSubmissionSpeaker $record */ - $details = []; - - if ($record->submission?->event) { - $details['Event'] = $record->submission->event->title; - } - - if ($record->user) { - $details['User'] = $record->user->name; - } - - return $details; - } -} diff --git a/app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource/Pages/CreateEventSubmissionSpeaker.php b/app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource/Pages/CreateEventSubmissionSpeaker.php deleted file mode 100644 index 93f9c9cb..00000000 --- a/app-modules/events/src/Filament/Resources/EventSubmissionSpeakerResource/Pages/CreateEventSubmissionSpeaker.php +++ /dev/null @@ -1,20 +0,0 @@ -components([ - Section::make('Sponsors') - ->description('Sponsors Information') - ->schema([ - Select::make('tenant_id') - ->label('Tenant') - ->preload() - ->searchable() - ->relationship( - name: 'tenant', - titleAttribute: 'name', - modifyQueryUsing: fn (Builder $query) => $query->limit(10) - ) - ->required(), - TextInput::make('name') - ->minLength(5) - ->maxLength(255) - ->required(), - SpatieMediaLibraryFileUpload::make('receipt') - ->label('Sponsor Logo') - ->collection('receipt') - ->image() - ->required(), - TextInput::make('homepage_url') - ->url(), - ]) - ->columnSpanFull(), - ]); - } -} diff --git a/app-modules/events/src/Filament/Resources/Sponsors/SponsorResource.php b/app-modules/events/src/Filament/Resources/Sponsors/SponsorResource.php deleted file mode 100644 index 5f64b2d1..00000000 --- a/app-modules/events/src/Filament/Resources/Sponsors/SponsorResource.php +++ /dev/null @@ -1,56 +0,0 @@ - ListSponsors::route('/'), - 'create' => CreateSponsor::route('/create'), - 'edit' => EditSponsor::route('/{record}/edit'), - ]; - } -} diff --git a/app-modules/events/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php b/app-modules/events/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php deleted file mode 100644 index 8c53b71d..00000000 --- a/app-modules/events/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php +++ /dev/null @@ -1,36 +0,0 @@ -columns([ - TextColumn::make('name') - ->searchable(), - TextColumn::make('homepage_url') - ->searchable(), - ]) - ->filters([ - - ]) - ->recordActions([ - EditAction::make(), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), - ]); - } -} diff --git a/app-modules/events/src/Providers/EventsServiceProvider.php b/app-modules/events/src/Providers/EventsServiceProvider.php index 46279d25..17688f79 100644 --- a/app-modules/events/src/Providers/EventsServiceProvider.php +++ b/app-modules/events/src/Providers/EventsServiceProvider.php @@ -6,7 +6,6 @@ use App\Enums\FilamentPanel; use Filament\Panel; -use He4rt\Events\AdminEventPanelPlugin; use He4rt\Events\AppEventPanelPlugin; use He4rt\Events\EventPanelPlugin; use He4rt\Events\Models\EventSegment; @@ -21,7 +20,6 @@ public function register(): void { Panel::configureUsing(function (Panel $panel): void { match ($panel->currentPanel()) { - FilamentPanel::Admin => $panel->plugin(new AdminEventPanelPlugin), FilamentPanel::User => $panel->plugin(new AppEventPanelPlugin), FilamentPanel::Event => $panel->plugin(new EventPanelPlugin()), default => null, diff --git a/app-modules/gamification/src/Providers/GamificationServiceProvider.php b/app-modules/gamification/src/Providers/GamificationServiceProvider.php index 3e9a4ad6..df95d3f4 100644 --- a/app-modules/gamification/src/Providers/GamificationServiceProvider.php +++ b/app-modules/gamification/src/Providers/GamificationServiceProvider.php @@ -18,19 +18,7 @@ class GamificationServiceProvider extends ServiceProvider { public function register(): void { - Panel::configureUsing(function (Panel $panel): void { - match ($panel->currentPanel()) { - FilamentPanel::Admin => $panel - ->resources([ - BadgeResource::class, - SeasonResource::class, - ]) - ->widgets([ - SeasonStatsOverview::class, - ]), - default => null, - }; - }); + } public function boot(): void diff --git a/app-modules/identity/src/Filament/Shared/Widgets/UsersStatsOverview.php b/app-modules/identity/src/Filament/Shared/Widgets/UsersStatsOverview.php deleted file mode 100644 index f2250986..00000000 --- a/app-modules/identity/src/Filament/Shared/Widgets/UsersStatsOverview.php +++ /dev/null @@ -1,51 +0,0 @@ -remember('total_users_donators', minutes(5), fn () => $query - ->where('is_donator', true) - ->count()); - - $totalUsersToday = cache()->remember('total_users_today', minutes(5), fn () => $query - ->whereDate('created_at', today()) - ->count()); - - $totalUsersMonth = cache()->remember('total_users_month', minutes(5), fn () => $query - ->whereYear('created_at', now()->year) - ->whereMonth('created_at', now()->month) - ->count()); - - return [ - Stat::make('Usuários criados hoje', $totalUsersToday) - ->description('Novos usuários nas últimas 24h') - ->descriptionIcon('heroicon-o-user-plus') - ->color('success'), - - Stat::make('Usuários criados este mês', $totalUsersMonth) - ->description('Total no mês atual') - ->descriptionIcon('heroicon-o-calendar') - ->color('primary'), - - Stat::make('Usuários doadores', $totalDonators) - ->description('Usuários com doação ativa') - ->descriptionIcon('heroicon-o-heart') - ->color('warning'), - ]; - } -} diff --git a/app-modules/identity/src/Providers/IdentityServiceProvider.php b/app-modules/identity/src/Providers/IdentityServiceProvider.php index 77c8c6a8..48f3c985 100644 --- a/app-modules/identity/src/Providers/IdentityServiceProvider.php +++ b/app-modules/identity/src/Providers/IdentityServiceProvider.php @@ -22,14 +22,6 @@ public function register(): void { Panel::configureUsing(function (Panel $panel): void { match ($panel->currentPanel()) { - FilamentPanel::Admin => $panel - ->resources([ - UserResource::class, - TenantResource::class, - ]) - ->widgets([ - UsersStatsOverview::class, - ]), FilamentPanel::User => $panel ->pages([ UserProfile::class, @@ -42,8 +34,8 @@ public function register(): void public function boot(): void { - $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); - $this->loadViewsFrom(__DIR__.'/../../resources/views', 'identity'); + $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations'); + $this->loadViewsFrom(__DIR__ . '/../../resources/views', 'identity'); Relation::morphMap([ 'user' => User::class, diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/EventsRelationManagerTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/EventsRelationManagerTest.php deleted file mode 100644 index 34336c24..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/EventsRelationManagerTest.php +++ /dev/null @@ -1,33 +0,0 @@ -user = User::factory()->create(); - actingAs($this->user); - $this->tenant = Tenant::factory()->create(); - Filament::setCurrentPanel('admin'); -}); - -it('should render', function (): void { - livewire(EventsRelationManager::class, ['ownerRecord' => $this->tenant, 'pageClass' => EditTenant::class]) - ->assertOk(); -}); - -it('should list the tenant events', function (): void { - $events = EventModel::factory()->recycle($this->tenant)->count(5)->create(); - livewire(EventsRelationManager::class, ['ownerRecord' => $this->tenant, 'pageClass' => EditTenant::class]) - ->assertOk() - ->assertCanSeeTableRecords($events) - ->assertCountTableRecords($events->count()); -}); diff --git a/app/Filament/Shared/RelationManagers/EventsRelationManager.php b/app/Filament/Shared/RelationManagers/EventsRelationManager.php deleted file mode 100644 index 7bfb089c..00000000 --- a/app/Filament/Shared/RelationManagers/EventsRelationManager.php +++ /dev/null @@ -1,45 +0,0 @@ -events->where('active', true)->count()); - } - - public function form(Schema $schema): Schema - { - return EventForm::configure($schema); - } - - public function table(Table $table): Table - { - return EventsTable::configure($table); - } - - protected function getTableHeaderActions(): array - { - return [ - CreateAction::make() - ->visible(fn ($livewire) => $livewire->pageClass !== EditSponsor::class), - ]; - } -} diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 666eeee8..43363b79 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -41,22 +41,6 @@ public function panel(Panel $panel): Panel Dashboard::class, ]) ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') - ->navigationGroups([ - NavigationGroup::make() - ->label('Administration'), - - NavigationGroup::make() - ->label('Events'), - - NavigationGroup::make() - ->label('Gamefication'), - - NavigationGroup::make() - ->label('Meetings'), - - NavigationGroup::make() - ->label('General'), - ]) ->middleware([ EncryptCookies::class, AddQueuedCookiesToResponse::class, From 742e70714e32455424f04f8ee6d4393f6066f415 Mon Sep 17 00:00:00 2001 From: danielhe4rt Date: Sun, 22 Mar 2026 22:49:59 -0300 Subject: [PATCH 3/8] wip --- .ai/mcp/mcp.json | 11 ++++++ .../src/Providers/IdentityServiceProvider.php | 3 -- app-modules/panel-admin/composer.json | 24 +++++++++++++ .../panel-admin/database/factories/.gitkeep | 0 .../panel-admin/database/migrations/.gitkeep | 0 ...03_22_224033_set_up_panel-admin_module.php | 21 ++++++++++++ .../panel-admin/database/seeders/.gitkeep | 0 .../resources/views/create.blade.php | 4 +++ .../resources/views/edit.blade.php | 4 +++ .../resources/views/index.blade.php | 4 +++ .../resources/views/show.blade.php | 4 +++ .../panel-admin/routes/panel-admin-routes.php | 11 ++++++ .../src/PanelAdminServiceProvider.php | 16 +++++++++ .../PanelAdminServiceProviderTest.php | 8 +++++ app/Providers/Filament/AdminPanelProvider.php | 6 ++-- bootstrap/helpers.php | 14 ++++++-- composer.json | 1 + composer.lock | 34 ++++++++++++++++++- 18 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 app-modules/panel-admin/composer.json create mode 100644 app-modules/panel-admin/database/factories/.gitkeep create mode 100644 app-modules/panel-admin/database/migrations/.gitkeep create mode 100644 app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php create mode 100644 app-modules/panel-admin/database/seeders/.gitkeep create mode 100644 app-modules/panel-admin/resources/views/create.blade.php create mode 100644 app-modules/panel-admin/resources/views/edit.blade.php create mode 100644 app-modules/panel-admin/resources/views/index.blade.php create mode 100644 app-modules/panel-admin/resources/views/show.blade.php create mode 100644 app-modules/panel-admin/routes/panel-admin-routes.php create mode 100644 app-modules/panel-admin/src/PanelAdminServiceProvider.php create mode 100644 app-modules/panel-admin/tests/Feature/Providers/PanelAdminServiceProviderTest.php diff --git a/.ai/mcp/mcp.json b/.ai/mcp/mcp.json index e69de29b..3e55e326 100644 --- a/.ai/mcp/mcp.json +++ b/.ai/mcp/mcp.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "laravel-boost": { + "command": "/usr/bin/php", + "args": [ + "/home/danielhe4rt/dev/he4rt/he4rtdevs.com/artisan", + "boost:mcp" + ] + } + } +} \ No newline at end of file diff --git a/app-modules/identity/src/Providers/IdentityServiceProvider.php b/app-modules/identity/src/Providers/IdentityServiceProvider.php index 48f3c985..b6878deb 100644 --- a/app-modules/identity/src/Providers/IdentityServiceProvider.php +++ b/app-modules/identity/src/Providers/IdentityServiceProvider.php @@ -6,9 +6,6 @@ use App\Enums\FilamentPanel; use Filament\Panel; -use He4rt\Identity\Filament\Admin\Resources\Tenants\TenantResource; -use He4rt\Identity\Filament\Admin\Resources\Users\UserResource; -use He4rt\Identity\Filament\Shared\Widgets\UsersStatsOverview; use He4rt\Identity\Filament\User\Pages\Dashboard; use He4rt\Identity\Filament\User\Pages\UserProfile; use He4rt\Identity\Tenant\Models\Tenant; diff --git a/app-modules/panel-admin/composer.json b/app-modules/panel-admin/composer.json new file mode 100644 index 00000000..8f53ae64 --- /dev/null +++ b/app-modules/panel-admin/composer.json @@ -0,0 +1,24 @@ +{ + "name": "he4rt/panel-admin", + "description": "", + "type": "library", + "version": "1.0", + "license": "proprietary", + "require": {}, + "autoload": { + "psr-4": { + "He4rt\\PanelAdmin\\": "src/", + "He4rt\\PanelAdmin\\Tests\\": "tests/", + "He4rt\\PanelAdmin\\Database\\Factories\\": "database/factories/", + "He4rt\\PanelAdmin\\Database\\Seeders\\": "database/seeders/" + } + }, + "minimum-stability": "stable", + "extra": { + "laravel": { + "providers": [ + "He4rt\\PanelAdmin\\PanelAdminServiceProvider" + ] + } + } +} diff --git a/app-modules/panel-admin/database/factories/.gitkeep b/app-modules/panel-admin/database/factories/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/app-modules/panel-admin/database/migrations/.gitkeep b/app-modules/panel-admin/database/migrations/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php b/app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php new file mode 100644 index 00000000..d657610b --- /dev/null +++ b/app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php @@ -0,0 +1,21 @@ +bigIncrements('id'); + // $table->timestamps(); + // $table->softDeletes(); + // }); + } + + public function down(): void + { + // Don't listen to the haters + // Schema::dropIfExists('panel-admin'); + } +}; diff --git a/app-modules/panel-admin/database/seeders/.gitkeep b/app-modules/panel-admin/database/seeders/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/app-modules/panel-admin/resources/views/create.blade.php b/app-modules/panel-admin/resources/views/create.blade.php new file mode 100644 index 00000000..fba286cf --- /dev/null +++ b/app-modules/panel-admin/resources/views/create.blade.php @@ -0,0 +1,4 @@ +@extends('layouts.app') + +@section('content') +@endsection diff --git a/app-modules/panel-admin/resources/views/edit.blade.php b/app-modules/panel-admin/resources/views/edit.blade.php new file mode 100644 index 00000000..fba286cf --- /dev/null +++ b/app-modules/panel-admin/resources/views/edit.blade.php @@ -0,0 +1,4 @@ +@extends('layouts.app') + +@section('content') +@endsection diff --git a/app-modules/panel-admin/resources/views/index.blade.php b/app-modules/panel-admin/resources/views/index.blade.php new file mode 100644 index 00000000..fba286cf --- /dev/null +++ b/app-modules/panel-admin/resources/views/index.blade.php @@ -0,0 +1,4 @@ +@extends('layouts.app') + +@section('content') +@endsection diff --git a/app-modules/panel-admin/resources/views/show.blade.php b/app-modules/panel-admin/resources/views/show.blade.php new file mode 100644 index 00000000..fba286cf --- /dev/null +++ b/app-modules/panel-admin/resources/views/show.blade.php @@ -0,0 +1,4 @@ +@extends('layouts.app') + +@section('content') +@endsection diff --git a/app-modules/panel-admin/routes/panel-admin-routes.php b/app-modules/panel-admin/routes/panel-admin-routes.php new file mode 100644 index 00000000..d0c9b831 --- /dev/null +++ b/app-modules/panel-admin/routes/panel-admin-routes.php @@ -0,0 +1,11 @@ +name('panel-admins.index'); +// Route::get('/panel-admins/create', [PanelAdminController::class, 'create'])->name('panel-admins.create'); +// Route::post('/panel-admins', [PanelAdminController::class, 'store'])->name('panel-admins.store'); +// Route::get('/panel-admins/{panel-admin}', [PanelAdminController::class, 'show'])->name('panel-admins.show'); +// Route::get('/panel-admins/{panel-admin}/edit', [PanelAdminController::class, 'edit'])->name('panel-admins.edit'); +// Route::put('/panel-admins/{panel-admin}', [PanelAdminController::class, 'update'])->name('panel-admins.update'); +// Route::delete('/panel-admins/{panel-admin}', [PanelAdminController::class, 'destroy'])->name('panel-admins.destroy'); diff --git a/app-modules/panel-admin/src/PanelAdminServiceProvider.php b/app-modules/panel-admin/src/PanelAdminServiceProvider.php new file mode 100644 index 00000000..31a385d2 --- /dev/null +++ b/app-modules/panel-admin/src/PanelAdminServiceProvider.php @@ -0,0 +1,16 @@ +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') + ->discoverResources(in: modules_path('panel-admin/src/Filament/Resources'), for: 'He4rt\\Admin\\Filament\\Resources') + ->discoverPages(in: modules_path('panel-admin/src/Filament/Pages'), for: 'He4rt\\Admin\\Filament\\Pages') + ->discoverWidgets(in: modules_path('panel-admin/src/Filament/Widgets'), for: 'He4rt\\Admin\\Filament\\Widgets') + ->discoverClusters(in: modules_path('panel-admin/src/Filament/Clusters'), for: 'He4rt\\Admin\\Filament\\Clusters') ->pages([ Dashboard::class, ]) diff --git a/bootstrap/helpers.php b/bootstrap/helpers.php index c87f5c25..59e97ffe 100644 --- a/bootstrap/helpers.php +++ b/bootstrap/helpers.php @@ -2,9 +2,17 @@ declare(strict_types=1); -if (! function_exists('module_path')) { - function module_path(string $module, string $path = ''): string +if (!function_exists('modules_path')) { + /** + * Get the path to the modules' folder. + * + * @see https://github.com/InterNACHI/modular/pull/99 + */ + function modules_path(string $path = ''): string { - return base_path(sprintf('app-modules/%s/%s', str($module)->lower()->kebab(), $path)); + $directory_name = config('app-modules.modules_directory', 'app-modules'); + $path = base_path($directory_name.DIRECTORY_SEPARATOR.mb_ltrim($path, '/\\')); + + return str_replace('\\', '/', mb_rtrim($path, '/\\')); } } diff --git a/composer.json b/composer.json index 3e28b4ec..a3dd905d 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "he4rt/identity": ">=1", "he4rt/integration-discord": ">=1", "he4rt/integration-twitch": ">=1", + "he4rt/panel-admin": ">=1", "he4rt/portal": ">=1", "internachi/modular": "dev-main#ad95fe9", "laracord/framework": "dev-next", diff --git a/composer.lock b/composer.lock index 20ffce7f..e57d3e67 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": "f3be323ab4f835734901b5f89dc34c61", + "content-hash": "ec7ee2736989263d48ed1b23f3e70021", "packages": [ { "name": "blade-ui-kit/blade-heroicons", @@ -3417,6 +3417,38 @@ "relative": true } }, + { + "name": "he4rt/panel-admin", + "version": "1.0", + "dist": { + "type": "path", + "url": "app-modules/panel-admin", + "reference": "cbdee07c016511ad846726a0d2d08cb06e3f6513" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "He4rt\\PanelAdmin\\PanelAdminServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "He4rt\\PanelAdmin\\": "src/", + "He4rt\\PanelAdmin\\Tests\\": "tests/", + "He4rt\\PanelAdmin\\Database\\Factories\\": "database/factories/", + "He4rt\\PanelAdmin\\Database\\Seeders\\": "database/seeders/" + } + }, + "license": [ + "proprietary" + ], + "transport-options": { + "symlink": true, + "relative": true + } + }, { "name": "he4rt/portal", "version": "1.0", From 4ed7e23628178f41f293f7bd65c4f8216155f05c Mon Sep 17 00:00:00 2001 From: danielhe4rt Date: Sun, 22 Mar 2026 23:23:50 -0300 Subject: [PATCH 4/8] feat: admin panel --- app-modules/events/src/Models/EventModel.php | 11 +++ .../gamification/src/Badge/Models/Badge.php | 16 +++ .../src/Character/Models/PastSeason.php | 1 + .../gamification/src/Season/Models/Season.php | 9 ++ .../Resources/Badges/BadgeResource.php | 57 +++++++++++ .../Resources/Badges/Pages/CreateBadge.php | 13 +++ .../Resources/Badges/Pages/EditBadge.php | 21 ++++ .../Resources/Badges/Pages/ListBadges.php | 21 ++++ .../Resources/Badges/Schemas/BadgeForm.php | 51 ++++++++++ .../Resources/Badges/Tables/BadgesTable.php | 70 +++++++++++++ .../Characters/CharacterResource.php | 56 +++++++++++ .../Characters/Pages/EditCharacter.php | 21 ++++ .../Characters/Pages/ListCharacters.php | 13 +++ .../BadgesRelationManager.php | 30 ++++++ .../PastSeasonsRelationManager.php | 35 +++++++ .../Characters/Schemas/CharacterForm.php | 38 +++++++ .../Characters/Tables/CharactersTable.php | 97 ++++++++++++++++++ .../EventModels/EventModelResource.php | 66 +++++++++++++ .../EventModels/Pages/CreateEventModel.php | 13 +++ .../EventModels/Pages/EditEventModel.php | 21 ++++ .../EventModels/Pages/ListEventModels.php | 21 ++++ .../AgendaRelationManager.php | 27 +++++ .../AttendeesRelationManager.php | 28 ++++++ .../RelationManagers/TalksRelationManager.php | 45 +++++++++ .../EventModels/Schemas/EventModelForm.php | 57 +++++++++++ .../EventModels/Tables/EventModelsTable.php | 61 ++++++++++++ .../EventSubmissionResource.php | 62 ++++++++++++ .../Pages/CreateEventSubmission.php | 13 +++ .../Pages/EditEventSubmission.php | 21 ++++ .../Pages/ListEventSubmissions.php | 21 ++++ .../SpeakersRelationManager.php | 24 +++++ .../Schemas/EventSubmissionForm.php | 54 ++++++++++ .../Tables/EventSubmissionsTable.php | 53 ++++++++++ .../ExternalIdentityResource.php | 58 +++++++++++ .../Pages/ListExternalIdentities.php | 13 +++ .../Tables/ExternalIdentitiesTable.php | 54 ++++++++++ .../Resources/Feedback/FeedbackResource.php | 69 +++++++++++++ .../Resources/Feedback/Pages/EditFeedback.php | 65 ++++++++++++ .../Resources/Feedback/Pages/ListFeedback.php | 13 +++ .../Feedback/Tables/FeedbackTable.php | 73 ++++++++++++++ .../MeetingTypes/MeetingTypeResource.php | 55 +++++++++++ .../MeetingTypes/Pages/CreateMeetingType.php | 13 +++ .../MeetingTypes/Pages/EditMeetingType.php | 21 ++++ .../MeetingTypes/Pages/ListMeetingTypes.php | 21 ++++ .../MeetingTypes/Schemas/MeetingTypeForm.php | 38 +++++++ .../MeetingTypes/Tables/MeetingTypesTable.php | 37 +++++++ .../Resources/Meetings/MeetingResource.php | 56 +++++++++++ .../Meetings/Pages/CreateMeeting.php | 13 +++ .../Resources/Meetings/Pages/EditMeeting.php | 21 ++++ .../Resources/Meetings/Pages/ListMeetings.php | 21 ++++ .../ParticipantsRelationManager.php | 27 +++++ .../Meetings/Schemas/MeetingForm.php | 42 ++++++++ .../Meetings/Tables/MeetingsTable.php | 64 ++++++++++++ .../Resources/Messages/MessageResource.php | 48 +++++++++ .../Resources/Messages/Pages/ListMessages.php | 13 +++ .../Messages/Tables/MessagesTable.php | 54 ++++++++++ .../Resources/Seasons/Pages/CreateSeason.php | 13 +++ .../Resources/Seasons/Pages/EditSeason.php | 64 ++++++++++++ .../Resources/Seasons/Pages/ListSeasons.php | 21 ++++ .../RankingsRelationManager.php | 38 +++++++ .../Resources/Seasons/Schemas/SeasonForm.php | 42 ++++++++ .../Resources/Seasons/SeasonResource.php | 58 +++++++++++ .../Resources/Seasons/Tables/SeasonsTable.php | 58 +++++++++++ .../Sponsors/Pages/CreateSponsor.php | 13 +++ .../Resources/Sponsors/Pages/EditSponsor.php | 21 ++++ .../Resources/Sponsors/Pages/ListSponsors.php | 21 ++++ .../Sponsors/Schemas/SponsorForm.php | 35 +++++++ .../Resources/Sponsors/SponsorResource.php | 55 +++++++++++ .../Sponsors/Tables/SponsorsTable.php | 42 ++++++++ .../Resources/Tenants/Pages/CreateTenant.php | 13 +++ .../Resources/Tenants/Pages/EditTenant.php | 25 +++++ .../Resources/Tenants/Pages/ListTenants.php | 21 ++++ .../MembersRelationManager.php | 26 +++++ .../Resources/Tenants/Schemas/TenantForm.php | 38 +++++++ .../Resources/Tenants/Tables/TenantsTable.php | 58 +++++++++++ .../Resources/Tenants/TenantResource.php | 74 ++++++++++++++ .../Transactions/Pages/ListTransactions.php | 13 +++ .../Transactions/Tables/TransactionsTable.php | 41 ++++++++ .../Transactions/TransactionResource.php | 48 +++++++++ .../Resources/Users/Pages/CreateUser.php | 13 +++ .../Resources/Users/Pages/EditUser.php | 21 ++++ .../Resources/Users/Pages/ListUsers.php | 21 ++++ .../ProvidersRelationManager.php | 45 +++++++++ .../Resources/Users/Schemas/UserForm.php | 98 +++++++++++++++++++ .../Resources/Users/Tables/UsersTable.php | 48 +++++++++ .../Filament/Resources/Users/UserResource.php | 72 ++++++++++++++ .../Resources/Voices/Pages/ListVoices.php | 13 +++ .../Resources/Voices/Tables/VoicesTable.php | 40 ++++++++ .../Resources/Voices/VoiceResource.php | 52 ++++++++++ .../Resources/Wallets/Pages/ListWallets.php | 13 +++ .../TransactionsRelationManager.php | 35 +++++++ .../Resources/Wallets/Tables/WalletsTable.php | 64 ++++++++++++ .../Resources/Wallets/WalletResource.php | 51 ++++++++++ .../src/Filament/Widgets/ActivityChart.php | 42 ++++++++ .../Filament/Widgets/EconomyStatsOverview.php | 27 +++++ .../Filament/Widgets/PendingReviewsWidget.php | 37 +++++++ .../Widgets/PlatformStatsOverview.php | 32 ++++++ .../Filament/Widgets/SeasonStatsOverview.php | 32 ++++++ .../PanelAdminServiceProviderTest.php | 11 ++- app/Providers/Filament/AdminPanelProvider.php | 17 +++- composer.json | 2 +- composer.lock | 2 +- 102 files changed, 3654 insertions(+), 8 deletions(-) create mode 100644 app-modules/panel-admin/src/Filament/Resources/Badges/BadgeResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Badges/Pages/CreateBadge.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Badges/Pages/EditBadge.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Badges/Pages/ListBadges.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Badges/Schemas/BadgeForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Badges/Tables/BadgesTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Characters/CharacterResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Characters/Pages/EditCharacter.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Characters/Pages/ListCharacters.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Characters/RelationManagers/BadgesRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Characters/RelationManagers/PastSeasonsRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Characters/Schemas/CharacterForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Characters/Tables/CharactersTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/EventModelResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/Pages/CreateEventModel.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/Pages/EditEventModel.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/Pages/ListEventModels.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/AgendaRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/AttendeesRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/TalksRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/Schemas/EventModelForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventModels/Tables/EventModelsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventSubmissions/EventSubmissionResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Pages/CreateEventSubmission.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Pages/EditEventSubmission.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Pages/ListEventSubmissions.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventSubmissions/RelationManagers/SpeakersRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Schemas/EventSubmissionForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Tables/EventSubmissionsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Tables/ExternalIdentitiesTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/EditFeedback.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/ListFeedback.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Feedback/Tables/FeedbackTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/MeetingTypes/MeetingTypeResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Pages/EditMeetingType.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Pages/ListMeetingTypes.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Schemas/MeetingTypeForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Meetings/MeetingResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Meetings/Pages/CreateMeeting.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Meetings/Pages/EditMeeting.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Meetings/Pages/ListMeetings.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Meetings/RelationManagers/ParticipantsRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Meetings/Schemas/MeetingForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Meetings/Tables/MeetingsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Messages/MessageResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Messages/Pages/ListMessages.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Messages/Tables/MessagesTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/CreateSeason.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/EditSeason.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/ListSeasons.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Seasons/RelationManagers/RankingsRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Seasons/Schemas/SeasonForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Seasons/SeasonResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Seasons/Tables/SeasonsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Sponsors/Pages/CreateSponsor.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Sponsors/Pages/EditSponsor.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Sponsors/Pages/ListSponsors.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Sponsors/Schemas/SponsorForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Sponsors/SponsorResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Tenants/Pages/CreateTenant.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Tenants/Pages/EditTenant.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Tenants/Pages/ListTenants.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Tenants/RelationManagers/MembersRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Tenants/Schemas/TenantForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Tenants/Tables/TenantsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Tenants/TenantResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Transactions/Pages/ListTransactions.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Transactions/Tables/TransactionsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Transactions/TransactionResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Users/Pages/CreateUser.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Users/Pages/EditUser.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Users/Pages/ListUsers.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Users/RelationManagers/ProvidersRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Users/Schemas/UserForm.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Users/Tables/UsersTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Users/UserResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Voices/Pages/ListVoices.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Voices/Tables/VoicesTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Voices/VoiceResource.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Wallets/Pages/ListWallets.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Wallets/RelationManagers/TransactionsRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Wallets/Tables/WalletsTable.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/Wallets/WalletResource.php create mode 100644 app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php create mode 100644 app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php create mode 100644 app-modules/panel-admin/src/Filament/Widgets/PendingReviewsWidget.php create mode 100644 app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php create mode 100644 app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php diff --git a/app-modules/events/src/Models/EventModel.php b/app-modules/events/src/Models/EventModel.php index 920bbdf1..00b68bb0 100644 --- a/app-modules/events/src/Models/EventModel.php +++ b/app-modules/events/src/Models/EventModel.php @@ -178,6 +178,17 @@ public function agenda(): HasMany ->oldest('starting_at'); } + /** + * @return BelongsToMany + */ + public function sponsors(): BelongsToMany + { + return $this->belongsToMany(Sponsor::class, 'events_sponsors', 'event_id', 'sponsor_id') + ->using(Pivot\SponsorAttend::class) + ->withPivot(['level']) + ->withTimestamps(); + } + /** @return Attribute */ protected function duration(): Attribute { diff --git a/app-modules/gamification/src/Badge/Models/Badge.php b/app-modules/gamification/src/Badge/Models/Badge.php index 389031be..04badd3a 100644 --- a/app-modules/gamification/src/Badge/Models/Badge.php +++ b/app-modules/gamification/src/Badge/Models/Badge.php @@ -4,12 +4,15 @@ namespace He4rt\Gamification\Badge\Models; +use He4rt\Gamification\Character\Models\Character; use He4rt\Gamification\Database\Factories\BadgeFactory; use He4rt\Identity\ExternalIdentity\Enums\IdentityProvider; use He4rt\Identity\Tenant\Models\Tenant; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\Pivot; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; @@ -39,6 +42,19 @@ public function tenant(): BelongsTo return $this->belongsTo(Tenant::class); } + /** + * @return BelongsToMany + */ + public function characters(): BelongsToMany + { + return $this->belongsToMany( + Character::class, + 'characters_badges', + 'badge_id', + 'character_id' + )->withPivot(['claimed_at']); + } + public function registerMediaCollections(): void { $this->addMediaCollection('badge') diff --git a/app-modules/gamification/src/Character/Models/PastSeason.php b/app-modules/gamification/src/Character/Models/PastSeason.php index 86780bb2..8aef97c7 100644 --- a/app-modules/gamification/src/Character/Models/PastSeason.php +++ b/app-modules/gamification/src/Character/Models/PastSeason.php @@ -23,6 +23,7 @@ final class PastSeason extends Model 'season_id', 'character_id', 'ranking_position', + 'level', 'experience', 'messages_count', 'badges_count', diff --git a/app-modules/gamification/src/Season/Models/Season.php b/app-modules/gamification/src/Season/Models/Season.php index ba01d7c3..45f99bd6 100644 --- a/app-modules/gamification/src/Season/Models/Season.php +++ b/app-modules/gamification/src/Season/Models/Season.php @@ -6,6 +6,7 @@ use He4rt\Community\Meeting\Models\Meeting; use He4rt\Gamification\Badge\Models\Badge; +use He4rt\Gamification\Character\Models\PastSeason; use He4rt\Gamification\Database\Factories\SeasonFactory; use He4rt\Identity\Tenant\Models\Tenant; use Illuminate\Database\Eloquent\Concerns\HasUuids; @@ -62,6 +63,14 @@ public function meetings(): HasMany return $this->hasMany(Meeting::class); } + /** + * @return HasMany + */ + public function rankings(): HasMany + { + return $this->hasMany(PastSeason::class, 'season_id'); + } + /** * @return BelongsTo */ diff --git a/app-modules/panel-admin/src/Filament/Resources/Badges/BadgeResource.php b/app-modules/panel-admin/src/Filament/Resources/Badges/BadgeResource.php new file mode 100644 index 00000000..605439dc --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Badges/BadgeResource.php @@ -0,0 +1,57 @@ + ListBadges::route('/'), + 'create' => CreateBadge::route('/create'), + 'edit' => EditBadge::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Badges/Pages/CreateBadge.php b/app-modules/panel-admin/src/Filament/Resources/Badges/Pages/CreateBadge.php new file mode 100644 index 00000000..2d5b7260 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Badges/Pages/CreateBadge.php @@ -0,0 +1,13 @@ +columns(1) + ->components([ + Select::make('tenant_id') + ->required() + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + + TextInput::make('name') + ->required() + ->maxLength(255), + + Textarea::make('description') + ->nullable() + ->rows(3), + + TextInput::make('redeem_code') + ->required(), + + Select::make('provider') + ->required() + ->options(IdentityProvider::class), + + Toggle::make('active') + ->default(true), + + SpatieMediaLibraryFileUpload::make('badge_image') + ->collection('badge') + ->disk('public'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Badges/Tables/BadgesTable.php b/app-modules/panel-admin/src/Filament/Resources/Badges/Tables/BadgesTable.php new file mode 100644 index 00000000..c0579daf --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Badges/Tables/BadgesTable.php @@ -0,0 +1,70 @@ +columns([ + SpatieMediaLibraryImageColumn::make('badge_image') + ->collection('badge') + ->circular() + ->label('Image'), + + TextColumn::make('name') + ->searchable() + ->sortable(), + + TextColumn::make('tenant.name') + ->badge() + ->color('gray'), + + TextColumn::make('redeem_code') + ->copyable(), + + TextColumn::make('provider') + ->badge(), + + IconColumn::make('active') + ->boolean(), + + TextColumn::make('characters_count') + ->counts('characters') + ->label('Claimed'), + ]) + ->filters([ + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + + TernaryFilter::make('active'), + + SelectFilter::make('provider') + ->options(IdentityProvider::class), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Characters/CharacterResource.php b/app-modules/panel-admin/src/Filament/Resources/Characters/CharacterResource.php new file mode 100644 index 00000000..51d2c26e --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Characters/CharacterResource.php @@ -0,0 +1,56 @@ + ListCharacters::route('/'), + 'edit' => EditCharacter::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Characters/Pages/EditCharacter.php b/app-modules/panel-admin/src/Filament/Resources/Characters/Pages/EditCharacter.php new file mode 100644 index 00000000..f758c0be --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Characters/Pages/EditCharacter.php @@ -0,0 +1,21 @@ +columns([ + TextColumn::make('name') + ->searchable(), + + TextColumn::make('provider') + ->badge(), + + TextColumn::make('claimed_at') + ->dateTime() + ->label('Claimed'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Characters/RelationManagers/PastSeasonsRelationManager.php b/app-modules/panel-admin/src/Filament/Resources/Characters/RelationManagers/PastSeasonsRelationManager.php new file mode 100644 index 00000000..338628da --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Characters/RelationManagers/PastSeasonsRelationManager.php @@ -0,0 +1,35 @@ +columns([ + TextColumn::make('season.name'), + + TextColumn::make('ranking_position') + ->sortable() + ->label('#'), + + TextColumn::make('experience') + ->numeric(0), + + TextColumn::make('messages_count') + ->numeric(0), + + TextColumn::make('badges_count') + ->numeric(0), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Characters/Schemas/CharacterForm.php b/app-modules/panel-admin/src/Filament/Resources/Characters/Schemas/CharacterForm.php new file mode 100644 index 00000000..33b97b09 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Characters/Schemas/CharacterForm.php @@ -0,0 +1,38 @@ +columns(1) + ->components([ + Select::make('user_id') + ->relationship('user', 'username') + ->disabled() + ->dehydrated(false), + + Select::make('tenant_id') + ->relationship('tenant', 'name') + ->disabled() + ->dehydrated(false), + + TextInput::make('experience') + ->required() + ->integer() + ->minValue(0), + + TextInput::make('reputation') + ->required() + ->integer(), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Characters/Tables/CharactersTable.php b/app-modules/panel-admin/src/Filament/Resources/Characters/Tables/CharactersTable.php new file mode 100644 index 00000000..37095aae --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Characters/Tables/CharactersTable.php @@ -0,0 +1,97 @@ +columns([ + TextColumn::make('user.username') + ->searchable() + ->label('User'), + + TextColumn::make('tenant.name') + ->badge() + ->color('gray') + ->label('Tenant'), + + TextColumn::make('level'), + + TextColumn::make('experience') + ->numeric(0) + ->sortable(), + + TextColumn::make('reputation') + ->numeric(0) + ->sortable(), + + TextColumn::make('daily_bonus_claimed_at') + ->dateTime() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + ]) + ->recordActions([ + EditAction::make(), + Action::make('grantXp') + ->label('Grant XP') + ->icon(Heroicon::ArrowTrendingUp) + ->color('success') + ->form([ + TextInput::make('amount') + ->required() + ->integer() + ->minValue(1), + ]) + ->action(fn ($record, array $data) => $record->increment('experience', (int) $data['amount'])) + ->successNotificationTitle('XP granted successfully'), + Action::make('resetDailyBonus') + ->label('Reset Daily Bonus') + ->icon(Heroicon::ArrowPath) + ->color('warning') + ->requiresConfirmation() + ->action(fn ($record) => $record->update(['daily_bonus_claimed_at' => null])) + ->successNotificationTitle('Daily bonus reset'), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + BulkAction::make('grantXpBulk') + ->label('Grant XP') + ->icon(Heroicon::ArrowTrendingUp) + ->color('success') + ->form([ + TextInput::make('amount') + ->required() + ->integer() + ->minValue(1), + ]) + ->action(function (Collection $records, array $data): void { + $records->each(fn ($record) => $record->increment('experience', (int) $data['amount'])); + }) + ->deselectRecordsAfterCompletion() + ->successNotificationTitle('XP granted to selected characters'), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventModels/EventModelResource.php b/app-modules/panel-admin/src/Filament/Resources/EventModels/EventModelResource.php new file mode 100644 index 00000000..c6f1ca9c --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventModels/EventModelResource.php @@ -0,0 +1,66 @@ + ListEventModels::route('/'), + 'create' => CreateEventModel::route('/create'), + 'edit' => EditEventModel::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventModels/Pages/CreateEventModel.php b/app-modules/panel-admin/src/Filament/Resources/EventModels/Pages/CreateEventModel.php new file mode 100644 index 00000000..b02c66ad --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventModels/Pages/CreateEventModel.php @@ -0,0 +1,13 @@ +columns([ + TextColumn::make('schedulable_type') + ->badge() + ->formatStateUsing(fn ($state) => class_basename($state)), + TextColumn::make('starting_at') + ->sortable(), + TextColumn::make('ending_at'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/AttendeesRelationManager.php b/app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/AttendeesRelationManager.php new file mode 100644 index 00000000..4499f360 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/AttendeesRelationManager.php @@ -0,0 +1,28 @@ +columns([ + TextColumn::make('username') + ->searchable(), + TextColumn::make('status') + ->badge(), + TextColumn::make('attend_order') + ->sortable() + ->label('#'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/TalksRelationManager.php b/app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/TalksRelationManager.php new file mode 100644 index 00000000..057f2505 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventModels/RelationManagers/TalksRelationManager.php @@ -0,0 +1,45 @@ +columns([ + TextColumn::make('title') + ->searchable(), + TextColumn::make('user.username') + ->label('Speaker'), + TextColumn::make('status') + ->badge(), + TextColumn::make('field_type'), + ]) + ->actions([ + Action::make('accept') + ->icon(Heroicon::Check) + ->color('success') + ->visible(fn ($record) => $record->status === TalkStatusEnum::Pending) + ->action(fn ($record) => $record->update(['status' => TalkStatusEnum::Accepted])) + ->successNotificationTitle('Talk accepted'), + Action::make('reject') + ->icon(Heroicon::XMark) + ->color('danger') + ->visible(fn ($record) => $record->status === TalkStatusEnum::Pending) + ->action(fn ($record) => $record->update(['status' => TalkStatusEnum::Rejected])) + ->successNotificationTitle('Talk rejected'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventModels/Schemas/EventModelForm.php b/app-modules/panel-admin/src/Filament/Resources/EventModels/Schemas/EventModelForm.php new file mode 100644 index 00000000..f2c2da1e --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventModels/Schemas/EventModelForm.php @@ -0,0 +1,57 @@ +columns(1) + ->components([ + Select::make('tenant_id') + ->required() + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + TextInput::make('title') + ->required() + ->minLength(5) + ->maxLength(255), + TextInput::make('slug') + ->required() + ->unique('events', 'slug', ignoreRecord: true), + RichEditor::make('description') + ->required(), + Select::make('event_type') + ->required() + ->options(EventTypeEnum::class), + TextInput::make('location') + ->required() + ->minLength(5) + ->maxLength(255), + TextInput::make('max_attendees') + ->required() + ->integer() + ->minValue(1), + Toggle::make('active'), + DateTimePicker::make('event_at') + ->required(), + DateTimePicker::make('start_at') + ->required(), + DateTimePicker::make('end_at') + ->required() + ->after('start_at'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventModels/Tables/EventModelsTable.php b/app-modules/panel-admin/src/Filament/Resources/EventModels/Tables/EventModelsTable.php new file mode 100644 index 00000000..3fae44e8 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventModels/Tables/EventModelsTable.php @@ -0,0 +1,61 @@ +columns([ + TextColumn::make('title') + ->searchable() + ->sortable(), + TextColumn::make('tenant.name') + ->badge() + ->color('gray'), + TextColumn::make('event_type') + ->badge(), + IconColumn::make('active') + ->boolean(), + TextColumn::make('event_at') + ->date() + ->sortable(), + TextColumn::make('attendees_count') + ->numeric(0) + ->label('Attendees'), + TextColumn::make('waitlist_count') + ->numeric(0) + ->label('Waitlist'), + ]) + ->filters([ + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + SelectFilter::make('event_type') + ->options(EventTypeEnum::class), + TernaryFilter::make('active'), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/EventSubmissionResource.php b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/EventSubmissionResource.php new file mode 100644 index 00000000..66cf79fb --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/EventSubmissionResource.php @@ -0,0 +1,62 @@ + ListEventSubmissions::route('/'), + 'create' => CreateEventSubmission::route('/create'), + 'edit' => EditEventSubmission::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Pages/CreateEventSubmission.php b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Pages/CreateEventSubmission.php new file mode 100644 index 00000000..1bd36f35 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Pages/CreateEventSubmission.php @@ -0,0 +1,13 @@ +columns([ + TextColumn::make('username') + ->searchable(), + TextColumn::make('name'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Schemas/EventSubmissionForm.php b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Schemas/EventSubmissionForm.php new file mode 100644 index 00000000..ad0befe4 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Schemas/EventSubmissionForm.php @@ -0,0 +1,54 @@ +columns(1) + ->components([ + Select::make('tenant_id') + ->required() + ->relationship('tenant', 'name') + ->searchable() + ->preload() + ->live(), + Select::make('event_id') + ->required() + ->relationship('event', 'title', modifyQueryUsing: fn (Builder $query, Get $get) => $query->where('tenant_id', $get('tenant_id'))) + ->searchable() + ->preload(), + Select::make('user_id') + ->required() + ->relationship('user', 'username') + ->searchable() + ->preload(), + TextInput::make('title') + ->required() + ->minLength(3) + ->maxLength(255), + TextInput::make('field_type') + ->required() + ->minLength(3) + ->maxLength(255), + RichEditor::make('description') + ->required(), + Select::make('status') + ->required() + ->options(TalkStatusEnum::class) + ->default(TalkStatusEnum::Pending), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Tables/EventSubmissionsTable.php b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Tables/EventSubmissionsTable.php new file mode 100644 index 00000000..dea14e27 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/EventSubmissions/Tables/EventSubmissionsTable.php @@ -0,0 +1,53 @@ +columns([ + TextColumn::make('event.title') + ->searchable() + ->label('Event'), + TextColumn::make('user.username') + ->searchable() + ->label('Speaker'), + TextColumn::make('title') + ->searchable(), + TextColumn::make('status') + ->badge(), + TextColumn::make('field_type'), + TextColumn::make('created_at') + ->dateTime() + ->sortable(), + ]) + ->filters([ + SelectFilter::make('status') + ->options(TalkStatusEnum::class), + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php new file mode 100644 index 00000000..08e957fa --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php @@ -0,0 +1,58 @@ + + */ + public static function getRelations(): array + { + return []; + } + + /** + * @return array + */ + public static function getPages(): array + { + return [ + 'index' => ListExternalIdentities::route('/'), + ]; + } + + public static function getRecordRouteBindingEloquentQuery(): Builder + { + return parent::getRecordRouteBindingEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php new file mode 100644 index 00000000..56f2c31f --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php @@ -0,0 +1,13 @@ +columns([ + TextColumn::make('provider') + ->badge(), + TextColumn::make('model_type') + ->badge() + ->color('gray') + ->formatStateUsing(fn (string $state) => class_basename($state)), + TextColumn::make('external_account_id') + ->copyable() + ->label('External ID'), + TextColumn::make('credentials_type') + ->badge(), + TextColumn::make('connected_at') + ->dateTime() + ->sortable(), + TextColumn::make('disconnected_at') + ->dateTime() + ->placeholder('Active'), + ]) + ->filters([ + SelectFilter::make('provider') + ->options(IdentityProvider::class), + TrashedFilter::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ForceDeleteBulkAction::make(), + RestoreBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php b/app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php new file mode 100644 index 00000000..14b2bbac --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php @@ -0,0 +1,69 @@ +count(); + } + + public static function form(Schema $schema): Schema + { + return $schema + ->columns(1) + ->components([ + Placeholder::make('sender') + ->content(fn ($record) => $record?->sender?->username ?? '-'), + Placeholder::make('target') + ->content(fn ($record) => $record?->target?->username ?? '-'), + Placeholder::make('type') + ->content(fn ($record) => $record?->type ?? '-'), + Placeholder::make('message') + ->content(fn ($record) => $record?->message ?? '-'), + Placeholder::make('created_at') + ->content(fn ($record) => $record?->created_at?->format('Y-m-d H:i') ?? '-'), + ]); + } + + public static function table(Table $table): Table + { + return FeedbackTable::configure($table); + } + + public static function getRelations(): array + { + return []; + } + + public static function getPages(): array + { + return [ + 'index' => ListFeedback::route('/'), + 'edit' => EditFeedback::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/EditFeedback.php b/app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/EditFeedback.php new file mode 100644 index 00000000..967c7a99 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/EditFeedback.php @@ -0,0 +1,65 @@ +label('Approve') + ->icon(Heroicon::Check) + ->color('success') + ->action(function (): void { + $this->record->review()->updateOrCreate( + ['feedback_id' => $this->record->id], + [ + 'tenant_id' => $this->record->tenant_id, + 'staff_id' => auth()->id(), + 'status' => ReviewTypeEnum::APPROVED, + 'received_at' => now(), + ] + ); + }) + ->successNotificationTitle('Feedback approved'), + + Action::make('decline') + ->label('Decline') + ->icon(Heroicon::XMark) + ->color('danger') + ->form([ + Textarea::make('reason') + ->required() + ->rows(3), + ]) + ->action(function (array $data): void { + $this->record->review()->updateOrCreate( + ['feedback_id' => $this->record->id], + [ + 'tenant_id' => $this->record->tenant_id, + 'staff_id' => auth()->id(), + 'status' => ReviewTypeEnum::DECLINED, + 'reason' => $data['reason'], + 'received_at' => now(), + ] + ); + }) + ->successNotificationTitle('Feedback declined'), + + DeleteAction::make(), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/ListFeedback.php b/app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/ListFeedback.php new file mode 100644 index 00000000..3de95790 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Feedback/Pages/ListFeedback.php @@ -0,0 +1,13 @@ +defaultSort('created_at', 'desc') + ->columns([ + TextColumn::make('sender.username') + ->searchable() + ->label('From'), + TextColumn::make('target.username') + ->searchable() + ->label('To'), + TextColumn::make('tenant.name') + ->badge() + ->color('gray'), + TextColumn::make('type') + ->badge(), + TextColumn::make('message') + ->limit(60) + ->tooltip(fn ($record) => $record->message), + TextColumn::make('review_status') + ->label('Review') + ->badge() + ->getStateUsing(fn ($record) => $record->review?->status?->value ?? 'pending') + ->color(fn (string $state): string => match ($state) { + 'approved' => 'success', + 'declined' => 'danger', + default => 'warning', + }), + TextColumn::make('created_at') + ->dateTime() + ->sortable(), + ]) + ->filters([ + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + SelectFilter::make('review_status') + ->label('Review Status') + ->options([ + 'pending' => 'Pending', + 'approved' => 'Approved', + 'declined' => 'Declined', + ]) + ->query(function ($query, array $data) { + if (! $data['value']) { + return $query; + } + + return match ($data['value']) { + 'pending' => $query->whereDoesntHave('review'), + default => $query->whereHas('review', fn ($q) => $q->where('status', $data['value'])), + }; + }), + ]) + ->recordActions([ + EditAction::make(), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/MeetingTypeResource.php b/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/MeetingTypeResource.php new file mode 100644 index 00000000..34eb2be3 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/MeetingTypeResource.php @@ -0,0 +1,55 @@ + ListMeetingTypes::route('/'), + 'create' => CreateMeetingType::route('/create'), + 'edit' => EditMeetingType::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php b/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php new file mode 100644 index 00000000..85eba114 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Pages/CreateMeetingType.php @@ -0,0 +1,13 @@ +columns(1) + ->components([ + TextInput::make('name') + ->required() + ->maxLength(255), + Select::make('week_day') + ->required() + ->options([ + 0 => 'Domingo', + 1 => 'Segunda', + 2 => 'Terça', + 3 => 'Quarta', + 4 => 'Quinta', + 5 => 'Sexta', + 6 => 'Sábado', + ]), + TextInput::make('start_at') + ->required() + ->integer() + ->helperText('Minutes from midnight (e.g., 1200 = 20:00)'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php b/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php new file mode 100644 index 00000000..1fd8098c --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/MeetingTypes/Tables/MeetingTypesTable.php @@ -0,0 +1,37 @@ +columns([ + TextColumn::make('name') + ->searchable() + ->sortable(), + TextColumn::make('meeting_day_for_humans') + ->label('Day'), + TextColumn::make('start_at') + ->label('Start Time'), + ]) + ->filters([]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Meetings/MeetingResource.php b/app-modules/panel-admin/src/Filament/Resources/Meetings/MeetingResource.php new file mode 100644 index 00000000..a4b99670 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Meetings/MeetingResource.php @@ -0,0 +1,56 @@ + ListMeetings::route('/'), + 'create' => CreateMeeting::route('/create'), + 'edit' => EditMeeting::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Meetings/Pages/CreateMeeting.php b/app-modules/panel-admin/src/Filament/Resources/Meetings/Pages/CreateMeeting.php new file mode 100644 index 00000000..a38731b3 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Meetings/Pages/CreateMeeting.php @@ -0,0 +1,13 @@ +columns([ + TextColumn::make('username') + ->searchable(), + TextColumn::make('name'), + TextColumn::make('attend_at') + ->dateTime() + ->label('Attended At'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Meetings/Schemas/MeetingForm.php b/app-modules/panel-admin/src/Filament/Resources/Meetings/Schemas/MeetingForm.php new file mode 100644 index 00000000..1254e871 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Meetings/Schemas/MeetingForm.php @@ -0,0 +1,42 @@ +columns(1) + ->components([ + Select::make('tenant_id') + ->required() + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + Select::make('meeting_type_id') + ->required() + ->relationship('meetingType', 'name') + ->preload(), + Select::make('admin_id') + ->required() + ->relationship('admin', 'username') + ->searchable() + ->preload() + ->default(fn () => auth()->id()), + RichEditor::make('content') + ->nullable(), + DateTimePicker::make('starts_at') + ->required(), + DateTimePicker::make('ends_at') + ->nullable(), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Meetings/Tables/MeetingsTable.php b/app-modules/panel-admin/src/Filament/Resources/Meetings/Tables/MeetingsTable.php new file mode 100644 index 00000000..0021d7b5 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Meetings/Tables/MeetingsTable.php @@ -0,0 +1,64 @@ +columns([ + TextColumn::make('meetingType.name') + ->badge() + ->color('primary') + ->label('Type'), + TextColumn::make('tenant.name') + ->badge() + ->color('gray'), + TextColumn::make('admin.username') + ->label('Host'), + TextColumn::make('starts_at') + ->dateTime() + ->sortable(), + TextColumn::make('ends_at') + ->dateTime() + ->placeholder('Ongoing'), + TextColumn::make('members_count') + ->counts('members') + ->label('Participants'), + ]) + ->filters([ + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + ]) + ->recordActions([ + Action::make('endMeeting') + ->label('End Meeting') + ->icon(Heroicon::Stop) + ->color('warning') + ->visible(fn ($record) => $record->ends_at === null) + ->requiresConfirmation() + ->action(fn ($record) => $record->update(['ends_at' => now()])) + ->successNotificationTitle('Meeting ended'), + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Messages/MessageResource.php b/app-modules/panel-admin/src/Filament/Resources/Messages/MessageResource.php new file mode 100644 index 00000000..7bbd8b0e --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Messages/MessageResource.php @@ -0,0 +1,48 @@ +components([]); + } + + public static function table(Table $table): Table + { + return MessagesTable::configure($table); + } + + public static function getRelations(): array + { + return []; + } + + public static function getPages(): array + { + return [ + 'index' => ListMessages::route('/'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Messages/Pages/ListMessages.php b/app-modules/panel-admin/src/Filament/Resources/Messages/Pages/ListMessages.php new file mode 100644 index 00000000..48913747 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Messages/Pages/ListMessages.php @@ -0,0 +1,13 @@ +defaultSort('sent_at', 'desc') + ->columns([ + TextColumn::make('provider.user.username') + ->label('User') + ->searchable(), + TextColumn::make('tenant.name') + ->badge() + ->color('gray'), + TextColumn::make('channel_id'), + TextColumn::make('content') + ->limit(80) + ->tooltip(fn ($record) => $record->content) + ->searchable(), + TextColumn::make('obtained_experience') + ->numeric(0) + ->label('XP'), + TextColumn::make('sent_at') + ->dateTime() + ->sortable(), + ]) + ->filters([ + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + ]) + ->recordActions([ + DeleteAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/CreateSeason.php b/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/CreateSeason.php new file mode 100644 index 00000000..cccf34fd --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/CreateSeason.php @@ -0,0 +1,13 @@ +label('End Season') + ->icon(Heroicon::Stop) + ->color('danger') + ->visible(fn () => $this->record->ended_at === null) + ->requiresConfirmation() + ->modalDescription('This will set ended_at to now.') + ->action(fn () => $this->record->update(['ended_at' => now()])) + ->successNotificationTitle('Season ended'), + + Action::make('computeRankings') + ->label('Compute Rankings') + ->icon(Heroicon::ChartBar) + ->color('warning') + ->requiresConfirmation() + ->modalDescription('This will snapshot all character rankings for this season.') + ->action(function (): void { + $characters = Character::query() + ->where('tenant_id', $this->record->tenant_id) + ->orderByDesc('experience') + ->get(); + + $position = 1; + foreach ($characters as $character) { + PastSeason::create([ + 'tenant_id' => $this->record->tenant_id, + 'season_id' => $this->record->id, + 'character_id' => $character->id, + 'ranking_position' => $position++, + 'level' => $character->level, + 'experience' => $character->experience, + 'messages_count' => 0, + 'badges_count' => $character->badges()->count(), + 'meetings_count' => 0, + ]); + } + }) + ->successNotificationTitle('Rankings computed'), + + DeleteAction::make(), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/ListSeasons.php b/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/ListSeasons.php new file mode 100644 index 00000000..7c574433 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/ListSeasons.php @@ -0,0 +1,21 @@ +defaultSort('ranking_position') + ->columns([ + TextColumn::make('ranking_position') + ->sortable() + ->label('#'), + + TextColumn::make('character.user.username') + ->label('User'), + + TextColumn::make('experience') + ->numeric(0) + ->sortable(), + + TextColumn::make('messages_count') + ->numeric(0), + + TextColumn::make('badges_count') + ->numeric(0), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Seasons/Schemas/SeasonForm.php b/app-modules/panel-admin/src/Filament/Resources/Seasons/Schemas/SeasonForm.php new file mode 100644 index 00000000..8fee6a68 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Seasons/Schemas/SeasonForm.php @@ -0,0 +1,42 @@ +columns(1) + ->components([ + Select::make('tenant_id') + ->required() + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + + TextInput::make('name') + ->required() + ->maxLength(255), + + Textarea::make('description') + ->nullable() + ->rows(3), + + DateTimePicker::make('started_at') + ->required(), + + DateTimePicker::make('ended_at') + ->nullable() + ->after('started_at'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Seasons/SeasonResource.php b/app-modules/panel-admin/src/Filament/Resources/Seasons/SeasonResource.php new file mode 100644 index 00000000..387af7da --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Seasons/SeasonResource.php @@ -0,0 +1,58 @@ + ListSeasons::route('/'), + 'create' => CreateSeason::route('/create'), + 'edit' => EditSeason::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Seasons/Tables/SeasonsTable.php b/app-modules/panel-admin/src/Filament/Resources/Seasons/Tables/SeasonsTable.php new file mode 100644 index 00000000..c4838c11 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Seasons/Tables/SeasonsTable.php @@ -0,0 +1,58 @@ +columns([ + TextColumn::make('name') + ->searchable() + ->sortable(), + + TextColumn::make('tenant.name') + ->badge() + ->color('gray'), + + TextColumn::make('started_at') + ->dateTime() + ->sortable(), + + TextColumn::make('ended_at') + ->dateTime() + ->sortable() + ->placeholder('Active'), + + TextColumn::make('participants_count') + ->numeric(0), + + TextColumn::make('messages_count') + ->numeric(0), + ]) + ->filters([ + SelectFilter::make('tenant_id') + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Sponsors/Pages/CreateSponsor.php b/app-modules/panel-admin/src/Filament/Resources/Sponsors/Pages/CreateSponsor.php new file mode 100644 index 00000000..0391a239 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Sponsors/Pages/CreateSponsor.php @@ -0,0 +1,13 @@ +columns(1) + ->components([ + Select::make('tenant_id') + ->required() + ->relationship('tenant', 'name') + ->searchable() + ->preload(), + TextInput::make('name') + ->required() + ->maxLength(255), + TextInput::make('homepage_url') + ->required() + ->url(), + SpatieMediaLibraryFileUpload::make('receipt_image') + ->collection('receipt') + ->disk('public'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Sponsors/SponsorResource.php b/app-modules/panel-admin/src/Filament/Resources/Sponsors/SponsorResource.php new file mode 100644 index 00000000..f3243982 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Sponsors/SponsorResource.php @@ -0,0 +1,55 @@ + ListSponsors::route('/'), + 'create' => CreateSponsor::route('/create'), + 'edit' => EditSponsor::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php b/app-modules/panel-admin/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php new file mode 100644 index 00000000..7654edad --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Sponsors/Tables/SponsorsTable.php @@ -0,0 +1,42 @@ +columns([ + TextColumn::make('name') + ->searchable() + ->sortable(), + TextColumn::make('tenant.name') + ->badge() + ->color('gray'), + TextColumn::make('homepage_url') + ->limit(30) + ->url(fn ($record) => $record->homepage_url, true), + TextColumn::make('events_count') + ->counts('events') + ->label('Events'), + ]) + ->filters([]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Tenants/Pages/CreateTenant.php b/app-modules/panel-admin/src/Filament/Resources/Tenants/Pages/CreateTenant.php new file mode 100644 index 00000000..8d0e9366 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Tenants/Pages/CreateTenant.php @@ -0,0 +1,13 @@ +columns([ + TextColumn::make('username') + ->searchable(), + TextColumn::make('name') + ->searchable(), + TextColumn::make('email'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Tenants/Schemas/TenantForm.php b/app-modules/panel-admin/src/Filament/Resources/Tenants/Schemas/TenantForm.php new file mode 100644 index 00000000..366e0454 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Tenants/Schemas/TenantForm.php @@ -0,0 +1,38 @@ +columns(1) + ->components([ + TextInput::make('name') + ->required() + ->maxLength(255), + TextInput::make('slug') + ->required() + ->maxLength(100) + ->unique('tenants', 'slug', ignoreRecord: true), + TextInput::make('domain') + ->nullable() + ->maxLength(255), + Select::make('owner_id') + ->relationship('owner', 'username') + ->searchable() + ->preload() + ->required(), + Toggle::make('active') + ->default(true), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Tenants/Tables/TenantsTable.php b/app-modules/panel-admin/src/Filament/Resources/Tenants/Tables/TenantsTable.php new file mode 100644 index 00000000..11b7667a --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Tenants/Tables/TenantsTable.php @@ -0,0 +1,58 @@ +columns([ + TextColumn::make('name') + ->searchable() + ->sortable(), + TextColumn::make('slug') + ->badge() + ->color('gray'), + TextColumn::make('owner.username') + ->searchable() + ->label('Owner'), + IconColumn::make('active') + ->boolean(), + TextColumn::make('members_count') + ->counts('members') + ->label('Members'), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + TernaryFilter::make('active'), + TrashedFilter::make(), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ForceDeleteBulkAction::make(), + RestoreBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Tenants/TenantResource.php b/app-modules/panel-admin/src/Filament/Resources/Tenants/TenantResource.php new file mode 100644 index 00000000..ab222715 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Tenants/TenantResource.php @@ -0,0 +1,74 @@ + + */ + public static function getRelations(): array + { + return [ + MembersRelationManager::class, + ]; + } + + /** + * @return array + */ + public static function getPages(): array + { + return [ + 'index' => ListTenants::route('/'), + 'create' => CreateTenant::route('/create'), + 'edit' => EditTenant::route('/{record}/edit'), + ]; + } + + public static function getRecordRouteBindingEloquentQuery(): Builder + { + return parent::getRecordRouteBindingEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Transactions/Pages/ListTransactions.php b/app-modules/panel-admin/src/Filament/Resources/Transactions/Pages/ListTransactions.php new file mode 100644 index 00000000..6fdbbc42 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Transactions/Pages/ListTransactions.php @@ -0,0 +1,13 @@ +defaultSort('created_at', 'desc') + ->columns([ + TextColumn::make('type') + ->badge(), + TextColumn::make('amount') + ->numeric(0) + ->color(fn (int $state): string => $state >= 0 ? 'success' : 'danger'), + TextColumn::make('balance_after') + ->numeric(0), + TextColumn::make('description') + ->limit(50), + TextColumn::make('reference_type') + ->badge() + ->color('gray') + ->formatStateUsing(fn (?string $state) => $state ? class_basename($state) : '-'), + TextColumn::make('created_at') + ->dateTime() + ->sortable(), + ]) + ->filters([ + SelectFilter::make('type') + ->options(TransactionType::class), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Transactions/TransactionResource.php b/app-modules/panel-admin/src/Filament/Resources/Transactions/TransactionResource.php new file mode 100644 index 00000000..9712c77c --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Transactions/TransactionResource.php @@ -0,0 +1,48 @@ +components([]); + } + + public static function table(Table $table): Table + { + return TransactionsTable::configure($table); + } + + public static function getRelations(): array + { + return []; + } + + public static function getPages(): array + { + return [ + 'index' => ListTransactions::route('/'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Users/Pages/CreateUser.php b/app-modules/panel-admin/src/Filament/Resources/Users/Pages/CreateUser.php new file mode 100644 index 00000000..d28901e7 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Users/Pages/CreateUser.php @@ -0,0 +1,13 @@ +columns([ + TextColumn::make('provider') + ->badge(), + TextColumn::make('external_account_id') + ->copyable() + ->label('External ID'), + TextColumn::make('credentials_type') + ->badge(), + TextColumn::make('connected_at') + ->dateTime() + ->sortable(), + TextColumn::make('disconnected_at') + ->dateTime() + ->placeholder('Connected'), + ]) + ->actions([ + Action::make('disconnect') + ->icon(Heroicon::NoSymbol) + ->color('danger') + ->visible(fn ($record) => $record->disconnected_at === null) + ->requiresConfirmation() + ->action(fn ($record) => $record->update(['disconnected_at' => now()])) + ->successNotificationTitle('Identity disconnected'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Users/Schemas/UserForm.php b/app-modules/panel-admin/src/Filament/Resources/Users/Schemas/UserForm.php new file mode 100644 index 00000000..7a3ea61e --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Users/Schemas/UserForm.php @@ -0,0 +1,98 @@ +columns(1) + ->components([ + Tabs::make('User') + ->tabs([ + Tab::make('General') + ->icon(Heroicon::User) + ->schema([ + TextInput::make('username') + ->required() + ->minLength(3) + ->maxLength(50) + ->unique('users', 'username', ignoreRecord: true) + ->autocomplete('off'), + TextInput::make('name') + ->required() + ->maxLength(100) + ->unique('users', 'name', ignoreRecord: true), + TextInput::make('email') + ->nullable() + ->email() + ->maxLength(255), + TextInput::make('password') + ->password() + ->revealable() + ->required(fn (string $operation): bool => $operation === 'create') + ->nullable() + ->minLength(8) + ->dehydrateStateUsing(fn ($state) => bcrypt($state)) + ->dehydrated(fn ($state) => filled($state)), + Toggle::make('is_donator') + ->default(false), + ]), + Tab::make('Address') + ->icon(Heroicon::MapPin) + ->schema([ + Group::make() + ->relationship('address') + ->schema([ + TextInput::make('country') + ->nullable() + ->maxLength(255), + TextInput::make('state') + ->nullable() + ->maxLength(255), + TextInput::make('city') + ->nullable() + ->maxLength(255), + TextInput::make('zip_code') + ->nullable() + ->maxLength(20), + ]), + ]), + Tab::make('Information') + ->icon(Heroicon::InformationCircle) + ->schema([ + Group::make() + ->relationship('information') + ->schema([ + TextInput::make('nickname') + ->nullable(), + TextInput::make('linkedin_url') + ->nullable() + ->url(), + TextInput::make('github_url') + ->nullable() + ->url(), + DatePicker::make('birthdate') + ->nullable(), + Textarea::make('about') + ->nullable() + ->rows(3), + ]), + ]), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Users/Tables/UsersTable.php b/app-modules/panel-admin/src/Filament/Resources/Users/Tables/UsersTable.php new file mode 100644 index 00000000..31f6e45e --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Users/Tables/UsersTable.php @@ -0,0 +1,48 @@ +columns([ + TextColumn::make('username') + ->searchable() + ->sortable(), + TextColumn::make('name') + ->searchable(), + TextColumn::make('email') + ->searchable(), + IconColumn::make('is_donator') + ->boolean(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + TernaryFilter::make('is_donator'), + ]) + ->defaultSort('created_at', 'desc') + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Users/UserResource.php b/app-modules/panel-admin/src/Filament/Resources/Users/UserResource.php new file mode 100644 index 00000000..48bc1c65 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Users/UserResource.php @@ -0,0 +1,72 @@ + + */ + public static function getGloballySearchableAttributes(): array + { + return ['username', 'name', 'email']; + } + + public static function form(Schema $schema): Schema + { + return UserForm::configure($schema); + } + + public static function table(Table $table): Table + { + return UsersTable::configure($table); + } + + /** + * @return array + */ + public static function getRelations(): array + { + return [ + ProvidersRelationManager::class, + ]; + } + + /** + * @return array + */ + public static function getPages(): array + { + return [ + 'index' => ListUsers::route('/'), + 'create' => CreateUser::route('/create'), + 'edit' => EditUser::route('/{record}/edit'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Voices/Pages/ListVoices.php b/app-modules/panel-admin/src/Filament/Resources/Voices/Pages/ListVoices.php new file mode 100644 index 00000000..960c3544 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Voices/Pages/ListVoices.php @@ -0,0 +1,13 @@ +defaultSort('created_at', 'desc') + ->columns([ + TextColumn::make('provider.user.username') + ->label('User'), + TextColumn::make('channel_name') + ->searchable(), + TextColumn::make('state') + ->badge(), + TextColumn::make('obtained_experience') + ->numeric(0) + ->label('XP'), + TextColumn::make('created_at') + ->dateTime() + ->sortable(), + ]) + ->filters([ + SelectFilter::make('state') + ->options([ + 'disabled' => 'Disabled', + 'muted' => 'Muted', + 'unmuted' => 'Unmuted', + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Voices/VoiceResource.php b/app-modules/panel-admin/src/Filament/Resources/Voices/VoiceResource.php new file mode 100644 index 00000000..0b872515 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Voices/VoiceResource.php @@ -0,0 +1,52 @@ +components([]); + } + + public static function table(Table $table): Table + { + return VoicesTable::configure($table); + } + + public static function getRelations(): array + { + return []; + } + + public static function getPages(): array + { + return [ + 'index' => ListVoices::route('/'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Wallets/Pages/ListWallets.php b/app-modules/panel-admin/src/Filament/Resources/Wallets/Pages/ListWallets.php new file mode 100644 index 00000000..4dac8eb1 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Wallets/Pages/ListWallets.php @@ -0,0 +1,13 @@ +defaultSort('created_at', 'desc') + ->columns([ + TextColumn::make('type') + ->badge(), + TextColumn::make('amount') + ->numeric(0) + ->color(fn (int $state): string => $state >= 0 ? 'success' : 'danger'), + TextColumn::make('balance_after') + ->numeric(0), + TextColumn::make('description') + ->limit(50) + ->tooltip(fn ($record) => $record->description), + TextColumn::make('created_at') + ->dateTime() + ->sortable(), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Wallets/Tables/WalletsTable.php b/app-modules/panel-admin/src/Filament/Resources/Wallets/Tables/WalletsTable.php new file mode 100644 index 00000000..e20d3921 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Wallets/Tables/WalletsTable.php @@ -0,0 +1,64 @@ +columns([ + TextColumn::make('owner_type') + ->badge() + ->color('gray') + ->formatStateUsing(fn (string $state) => class_basename($state)), + TextColumn::make('currency') + ->badge(), + TextColumn::make('balance') + ->numeric(0) + ->sortable(), + TextColumn::make('transactions_count') + ->counts('transactions') + ->label('Transactions'), + ]) + ->filters([ + SelectFilter::make('currency') + ->options(Currency::class), + ]) + ->recordActions([ + Action::make('credit') + ->icon(Heroicon::Plus) + ->color('success') + ->form([ + TextInput::make('amount') + ->required() + ->integer() + ->minValue(1), + TextInput::make('description') + ->nullable() + ->maxLength(255), + ]) + ->action(function ($record, array $data): void { + $record->increment('balance', (int) $data['amount']); + $record->transactions()->create([ + 'type' => TransactionType::Reward, + 'amount' => (int) $data['amount'], + 'balance_after' => $record->fresh()->balance, + 'description' => $data['description'] ?? 'Admin credit', + ]); + }) + ->successNotificationTitle('Wallet credited'), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/Wallets/WalletResource.php b/app-modules/panel-admin/src/Filament/Resources/Wallets/WalletResource.php new file mode 100644 index 00000000..d5dad3f1 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/Wallets/WalletResource.php @@ -0,0 +1,51 @@ +components([]); + } + + public static function table(Table $table): Table + { + return WalletsTable::configure($table); + } + + public static function getRelations(): array + { + return [ + TransactionsRelationManager::class, + ]; + } + + public static function getPages(): array + { + return [ + 'index' => ListWallets::route('/'), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php b/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php new file mode 100644 index 00000000..461e96ee --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php @@ -0,0 +1,42 @@ +map(fn (int $i) => Carbon::today()->subDays($i)); + + $counts = Message::query() + ->where('sent_at', '>=', Carbon::today()->subDays(30)) + ->selectRaw('DATE(sent_at) as date, COUNT(*) as count') + ->groupByRaw('DATE(sent_at)') + ->pluck('count', 'date'); + + return [ + 'datasets' => [ + [ + 'label' => 'Messages', + 'data' => $days->map(fn (Carbon $day) => $counts->get($day->toDateString(), 0))->toArray(), + ], + ], + 'labels' => $days->map(fn (Carbon $day) => $day->format('M d'))->toArray(), + ]; + } + + protected function getType(): string + { + return 'line'; + } +} diff --git a/app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php b/app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php new file mode 100644 index 00000000..71d48a53 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php @@ -0,0 +1,27 @@ +sum('balance')) + ->icon(Heroicon::CurrencyDollar), + Stat::make('Transactions Today', Transaction::whereDate('created_at', today())->count()) + ->icon(Heroicon::ReceiptPercent), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Widgets/PendingReviewsWidget.php b/app-modules/panel-admin/src/Filament/Widgets/PendingReviewsWidget.php new file mode 100644 index 00000000..99c346b5 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Widgets/PendingReviewsWidget.php @@ -0,0 +1,37 @@ +query( + Feedback::query() + ->whereDoesntHave('review') + ->latest() + ->limit(10) + ) + ->columns([ + TextColumn::make('sender.username')->label('From'), + TextColumn::make('target.username')->label('To'), + TextColumn::make('type')->badge(), + TextColumn::make('message')->limit(60), + TextColumn::make('created_at')->dateTime(), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php b/app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php new file mode 100644 index 00000000..0db31409 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php @@ -0,0 +1,32 @@ +icon(Heroicon::Users), + Stat::make('Active Tenants', Tenant::where('active', true)->count()) + ->icon(Heroicon::BuildingOffice), + Stat::make('Total Characters', Character::count()) + ->icon(Heroicon::UserCircle), + Stat::make('Active Events', EventModel::where('active', true)->count()) + ->icon(Heroicon::Ticket), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php b/app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php new file mode 100644 index 00000000..e5e2a57d --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php @@ -0,0 +1,32 @@ +first(); + + return [ + Stat::make('Current Season', $currentSeason?->name ?? 'None') + ->icon(Heroicon::Flag), + Stat::make('Total XP Distributed', Number::abbreviate(Character::sum('experience'))) + ->icon(Heroicon::ArrowTrendingUp), + Stat::make('Badges Claimed', DB::table('characters_badges')->count()) + ->icon(Heroicon::Star), + ]; + } +} diff --git a/app-modules/panel-admin/tests/Feature/Providers/PanelAdminServiceProviderTest.php b/app-modules/panel-admin/tests/Feature/Providers/PanelAdminServiceProviderTest.php index ad4db434..7733bd13 100644 --- a/app-modules/panel-admin/tests/Feature/Providers/PanelAdminServiceProviderTest.php +++ b/app-modules/panel-admin/tests/Feature/Providers/PanelAdminServiceProviderTest.php @@ -1,8 +1,15 @@ assertTrue(true); + } } diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 660a70f2..c32a3e10 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -35,13 +35,22 @@ public function panel(Panel $panel): Panel ...Color::all(), ]) ->viteTheme('resources/css/filament/admin/theme.css') - ->discoverResources(in: modules_path('panel-admin/src/Filament/Resources'), for: 'He4rt\\Admin\\Filament\\Resources') - ->discoverPages(in: modules_path('panel-admin/src/Filament/Pages'), for: 'He4rt\\Admin\\Filament\\Pages') - ->discoverWidgets(in: modules_path('panel-admin/src/Filament/Widgets'), for: 'He4rt\\Admin\\Filament\\Widgets') - ->discoverClusters(in: modules_path('panel-admin/src/Filament/Clusters'), for: 'He4rt\\Admin\\Filament\\Clusters') + ->discoverResources(in: modules_path('panel-admin/src/Filament/Resources'), for: 'He4rt\\PanelAdmin\\Filament\\Resources') + ->discoverPages(in: modules_path('panel-admin/src/Filament/Pages'), for: 'He4rt\\PanelAdmin\\Filament\\Pages') + ->discoverWidgets(in: modules_path('panel-admin/src/Filament/Widgets'), for: 'He4rt\\PanelAdmin\\Filament\\Widgets') + ->discoverClusters(in: modules_path('panel-admin/src/Filament/Clusters'), for: 'He4rt\\PanelAdmin\\Filament\\Clusters') ->pages([ Dashboard::class, ]) + ->navigationGroups([ + NavigationGroup::make('Community'), + NavigationGroup::make('Gamification'), + NavigationGroup::make('Economy'), + NavigationGroup::make('Events'), + NavigationGroup::make('Activity'), + NavigationGroup::make('Meetings'), + NavigationGroup::make('Moderation'), + ]) ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') ->middleware([ EncryptCookies::class, diff --git a/composer.json b/composer.json index a3dd905d..ef32d8ac 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "he4rt/identity": ">=1", "he4rt/integration-discord": ">=1", "he4rt/integration-twitch": ">=1", - "he4rt/panel-admin": ">=1", + "he4rt/panel-admin": "^1.0", "he4rt/portal": ">=1", "internachi/modular": "dev-main#ad95fe9", "laracord/framework": "dev-next", diff --git a/composer.lock b/composer.lock index e57d3e67..b0dd74d6 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": "ec7ee2736989263d48ed1b23f3e70021", + "content-hash": "f49064900ba918d2aababcfdfe950f2f", "packages": [ { "name": "blade-ui-kit/blade-heroicons", From 974fc61b8a8640396c2ed6fec236c16d96750aa5 Mon Sep 17 00:00:00 2001 From: danielhe4rt Date: Sun, 22 Mar 2026 23:25:03 -0300 Subject: [PATCH 5/8] wip: linting --- .../src/Providers/ActivityServiceProvider.php | 7 +--- .../Providers/CommunityServiceProvider.php | 9 ++---- app-modules/events/src/Models/EventModel.php | 3 +- .../Providers/GamificationServiceProvider.php | 10 +----- .../src/Providers/IdentityServiceProvider.php | 4 +-- ...03_22_224033_set_up_panel-admin_module.php | 32 ++++++++++--------- .../panel-admin/routes/panel-admin-routes.php | 2 ++ .../Resources/Feedback/FeedbackResource.php | 2 +- .../Resources/Seasons/Pages/EditSeason.php | 2 +- .../src/Filament/Widgets/ActivityChart.php | 7 ++-- .../Filament/Widgets/EconomyStatsOverview.php | 4 +-- .../Widgets/PlatformStatsOverview.php | 8 ++--- .../Filament/Widgets/SeasonStatsOverview.php | 4 +-- .../src/PanelAdminServiceProvider.php | 10 +++--- .../PanelAdminServiceProviderTest.php | 2 +- bootstrap/helpers.php | 2 +- phpstan.ignore.neon | 5 +++ 17 files changed, 52 insertions(+), 61 deletions(-) diff --git a/app-modules/activity/src/Providers/ActivityServiceProvider.php b/app-modules/activity/src/Providers/ActivityServiceProvider.php index e5d4c4ce..4616aee0 100644 --- a/app-modules/activity/src/Providers/ActivityServiceProvider.php +++ b/app-modules/activity/src/Providers/ActivityServiceProvider.php @@ -4,16 +4,11 @@ namespace He4rt\Activity\Providers; -use App\Enums\FilamentPanel; -use Filament\Panel; -use He4rt\Activity\Filament\Admin\Resources\Messages\MessageResource; use Illuminate\Support\ServiceProvider; class ActivityServiceProvider extends ServiceProvider { - public function register(): void - { - } + public function register(): void {} public function boot(): void { diff --git a/app-modules/community/src/Providers/CommunityServiceProvider.php b/app-modules/community/src/Providers/CommunityServiceProvider.php index 84b69eb8..ef5c9c0e 100644 --- a/app-modules/community/src/Providers/CommunityServiceProvider.php +++ b/app-modules/community/src/Providers/CommunityServiceProvider.php @@ -4,19 +4,14 @@ namespace He4rt\Community\Providers; -use He4rt\Community\Feedback\Filament\Admin\Resources\Feedback\FeedbackResource; -use He4rt\Community\Meeting\Filament\Resources\Meetings\MeetingResource; -use He4rt\Community\Meeting\Filament\Resources\MeetingTypes\MeetingTypeResource; use Illuminate\Support\ServiceProvider; class CommunityServiceProvider extends ServiceProvider { - public function register(): void - { - } + public function register(): void {} public function boot(): void { - $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations'); + $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); } } diff --git a/app-modules/events/src/Models/EventModel.php b/app-modules/events/src/Models/EventModel.php index 00b68bb0..bf7865e1 100644 --- a/app-modules/events/src/Models/EventModel.php +++ b/app-modules/events/src/Models/EventModel.php @@ -4,6 +4,7 @@ namespace He4rt\Events\Models; +use He4rt\Events\Models\Pivot\SponsorAttend; use Carbon\Carbon; use Exception; use He4rt\Events\Database\Factories\EventFactory; @@ -184,7 +185,7 @@ public function agenda(): HasMany public function sponsors(): BelongsToMany { return $this->belongsToMany(Sponsor::class, 'events_sponsors', 'event_id', 'sponsor_id') - ->using(Pivot\SponsorAttend::class) + ->using(SponsorAttend::class) ->withPivot(['level']) ->withTimestamps(); } diff --git a/app-modules/gamification/src/Providers/GamificationServiceProvider.php b/app-modules/gamification/src/Providers/GamificationServiceProvider.php index df95d3f4..531d3eca 100644 --- a/app-modules/gamification/src/Providers/GamificationServiceProvider.php +++ b/app-modules/gamification/src/Providers/GamificationServiceProvider.php @@ -4,22 +4,14 @@ namespace He4rt\Gamification\Providers; -use App\Enums\FilamentPanel; -use Filament\Panel; -use He4rt\Gamification\Badge\Filament\Resources\Badges\BadgeResource; use He4rt\Gamification\Badge\Models\Badge; use He4rt\Gamification\Character\Models\Character; -use He4rt\Gamification\Season\Filament\Admin\Resources\Seasons\SeasonResource; -use He4rt\Gamification\Season\Filament\Shared\Widgets\SeasonStatsOverview; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\ServiceProvider; class GamificationServiceProvider extends ServiceProvider { - public function register(): void - { - - } + public function register(): void {} public function boot(): void { diff --git a/app-modules/identity/src/Providers/IdentityServiceProvider.php b/app-modules/identity/src/Providers/IdentityServiceProvider.php index b6878deb..0f5cb8a6 100644 --- a/app-modules/identity/src/Providers/IdentityServiceProvider.php +++ b/app-modules/identity/src/Providers/IdentityServiceProvider.php @@ -31,8 +31,8 @@ public function register(): void public function boot(): void { - $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations'); - $this->loadViewsFrom(__DIR__ . '/../../resources/views', 'identity'); + $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); + $this->loadViewsFrom(__DIR__.'/../../resources/views', 'identity'); Relation::morphMap([ 'user' => User::class, diff --git a/app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php b/app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php index d657610b..78da6aaf 100644 --- a/app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php +++ b/app-modules/panel-admin/database/migrations/2026_03_22_224033_set_up_panel-admin_module.php @@ -1,21 +1,23 @@ bigIncrements('id'); - // $table->timestamps(); - // $table->softDeletes(); - // }); - } +return new class() extends Migration +{ + public function up(): void + { + // Schema::create('panel-admin', function(Blueprint $table) { + // $table->bigIncrements('id'); + // $table->timestamps(); + // $table->softDeletes(); + // }); + } - public function down(): void - { - // Don't listen to the haters - // Schema::dropIfExists('panel-admin'); - } + public function down(): void + { + // Don't listen to the haters + // Schema::dropIfExists('panel-admin'); + } }; diff --git a/app-modules/panel-admin/routes/panel-admin-routes.php b/app-modules/panel-admin/routes/panel-admin-routes.php index d0c9b831..70fe9d3c 100644 --- a/app-modules/panel-admin/routes/panel-admin-routes.php +++ b/app-modules/panel-admin/routes/panel-admin-routes.php @@ -1,5 +1,7 @@ name('panel-admins.index'); diff --git a/app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php b/app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php index 14b2bbac..e006053f 100644 --- a/app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php +++ b/app-modules/panel-admin/src/Filament/Resources/Feedback/FeedbackResource.php @@ -28,7 +28,7 @@ class FeedbackResource extends Resource public static function getNavigationBadge(): ?string { - return (string) Feedback::whereDoesntHave('review')->count(); + return (string) Feedback::query()->whereDoesntHave('review')->count(); } public static function form(Schema $schema): Schema diff --git a/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/EditSeason.php b/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/EditSeason.php index 7174144c..1071da79 100644 --- a/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/EditSeason.php +++ b/app-modules/panel-admin/src/Filament/Resources/Seasons/Pages/EditSeason.php @@ -43,7 +43,7 @@ protected function getHeaderActions(): array $position = 1; foreach ($characters as $character) { - PastSeason::create([ + PastSeason::query()->create([ 'tenant_id' => $this->record->tenant_id, 'season_id' => $this->record->id, 'character_id' => $character->id, diff --git a/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php b/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php index 461e96ee..859d7c62 100644 --- a/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php +++ b/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php @@ -4,6 +4,7 @@ namespace He4rt\PanelAdmin\Filament\Widgets; +use Illuminate\Support\Facades\Date; use Filament\Widgets\ChartWidget; use He4rt\Activity\Models\Message; use Illuminate\Support\Carbon; @@ -16,10 +17,10 @@ class ActivityChart extends ChartWidget protected function getData(): array { - $days = collect(range(29, 0))->map(fn (int $i) => Carbon::today()->subDays($i)); + $days = collect(range(29, 0))->map(fn (int $i) => Date::today()->subDays($i)); $counts = Message::query() - ->where('sent_at', '>=', Carbon::today()->subDays(30)) + ->where('sent_at', '>=', Date::today()->subDays(30)) ->selectRaw('DATE(sent_at) as date, COUNT(*) as count') ->groupByRaw('DATE(sent_at)') ->pluck('count', 'date'); @@ -31,7 +32,7 @@ protected function getData(): array 'data' => $days->map(fn (Carbon $day) => $counts->get($day->toDateString(), 0))->toArray(), ], ], - 'labels' => $days->map(fn (Carbon $day) => $day->format('M d'))->toArray(), + 'labels' => $days->map(fn (Carbon $day) => $day->format('M d'))->all(), ]; } diff --git a/app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php b/app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php index 71d48a53..d0a8ebd9 100644 --- a/app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php +++ b/app-modules/panel-admin/src/Filament/Widgets/EconomyStatsOverview.php @@ -18,9 +18,9 @@ class EconomyStatsOverview extends StatsOverviewWidget protected function getStats(): array { return [ - Stat::make('Total Coin Balance', Wallet::where('currency', Currency::Coin)->sum('balance')) + Stat::make('Total Coin Balance', Wallet::query()->where('currency', Currency::Coin)->sum('balance')) ->icon(Heroicon::CurrencyDollar), - Stat::make('Transactions Today', Transaction::whereDate('created_at', today())->count()) + Stat::make('Transactions Today', Transaction::query()->whereDate('created_at', today())->count()) ->icon(Heroicon::ReceiptPercent), ]; } diff --git a/app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php b/app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php index 0db31409..87d357e3 100644 --- a/app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php +++ b/app-modules/panel-admin/src/Filament/Widgets/PlatformStatsOverview.php @@ -19,13 +19,13 @@ class PlatformStatsOverview extends StatsOverviewWidget protected function getStats(): array { return [ - Stat::make('Total Users', User::count()) + Stat::make('Total Users', User::query()->count()) ->icon(Heroicon::Users), - Stat::make('Active Tenants', Tenant::where('active', true)->count()) + Stat::make('Active Tenants', Tenant::query()->where('active', true)->count()) ->icon(Heroicon::BuildingOffice), - Stat::make('Total Characters', Character::count()) + Stat::make('Total Characters', Character::query()->count()) ->icon(Heroicon::UserCircle), - Stat::make('Active Events', EventModel::where('active', true)->count()) + Stat::make('Active Events', EventModel::query()->where('active', true)->count()) ->icon(Heroicon::Ticket), ]; } diff --git a/app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php b/app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php index e5e2a57d..87a47779 100644 --- a/app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php +++ b/app-modules/panel-admin/src/Filament/Widgets/SeasonStatsOverview.php @@ -18,12 +18,12 @@ class SeasonStatsOverview extends StatsOverviewWidget protected function getStats(): array { - $currentSeason = Season::whereNull('ended_at')->first(); + $currentSeason = Season::query()->whereNull('ended_at')->first(); return [ Stat::make('Current Season', $currentSeason?->name ?? 'None') ->icon(Heroicon::Flag), - Stat::make('Total XP Distributed', Number::abbreviate(Character::sum('experience'))) + Stat::make('Total XP Distributed', Number::abbreviate(Character::query()->sum('experience'))) ->icon(Heroicon::ArrowTrendingUp), Stat::make('Badges Claimed', DB::table('characters_badges')->count()) ->icon(Heroicon::Star), diff --git a/app-modules/panel-admin/src/PanelAdminServiceProvider.php b/app-modules/panel-admin/src/PanelAdminServiceProvider.php index 31a385d2..665db436 100644 --- a/app-modules/panel-admin/src/PanelAdminServiceProvider.php +++ b/app-modules/panel-admin/src/PanelAdminServiceProvider.php @@ -1,16 +1,14 @@ Date: Sun, 22 Mar 2026 23:25:35 -0300 Subject: [PATCH 6/8] wip --- .husky/pre-commit | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit old mode 100644 new mode 100755 From a947c347e2c7ea02b0faff51a921d0ef25907ff7 Mon Sep 17 00:00:00 2001 From: danielhe4rt Date: Mon, 23 Mar 2026 00:02:57 -0300 Subject: [PATCH 7/8] feat: tests --- .../Admin/Message/CreateMessageTest.php | 46 ----- .../Admin/Message/DeleteMessageTest.php | 25 --- .../Admin/Message/EditMessageTest.php | 49 ----- .../Admin/Message/ListMessageTest.phpTest.php | 16 -- .../Admin/Message/MessageResourceTest.php | 11 -- .../Admin/Feedback/CreateFeedbackTest.php | 35 ---- .../Admin/Feedback/DeleteFeedbackTest.php | 26 --- .../Admin/Feedback/EditFeedbackTest.php | 50 ----- .../Admin/Feedback/FeedbackResourceTest.php | 12 -- .../Admin/Meeting/CreateMeetingTest.php | 52 ----- .../Admin/Meeting/EditMeetingTest.php | 21 -- .../Admin/Meeting/ListMeetingTest.php | 19 -- .../MeetingType/CreateMeetingTypeTest.php | 41 ---- .../Admin/MeetingType/EditMeetingTypeTest.php | 21 -- .../Admin/MeetingType/ListMeetingTypeTest.php | 19 -- app-modules/events/src/Models/EventModel.php | 4 +- .../Event/AttendeesRelationManagerTest.php | 120 ------------ .../Filament/Admin/Event/CreateEventTest.php | 165 ---------------- .../Filament/Admin/Event/EditEventTest.php | 18 -- .../Filament/Admin/Event/ListEventsTest.php | 16 -- .../Admin/Event/TalkRelationManagerTest.php | 179 ------------------ .../Admin/Sponsors/CreateSponsorTest.php | 54 ------ .../Admin/Sponsors/EditSponsorTest.php | 19 -- .../Admin/Sponsors/ListSponsorsTest.php | 17 -- .../Filament/Admin/Talk/CreateTalk.php | 55 ------ .../Feature/Filament/Admin/Talk/EditTalk.php | 18 -- .../Feature/Filament/Admin/Talk/ListTalks.php | 15 -- .../Badge/Filament/Admin/CreateBadgeTest.php | 59 ------ .../Badge/Filament/Admin/EditBadgeTest.php | 20 -- .../Badge/Filament/Admin/ListBadgeTest.php | 17 -- .../Filament/Admin/CreateSeasonTest.php | 55 ------ .../Season/Filament/Admin/EditSeasonTest.php | 21 -- .../Season/Filament/Admin/ListSeasonTest.php | 19 -- ...index_to_messages_external_identity_id.php | 24 +++ .../Resources/Tenant/CreateTenantTest.php | 62 ------ .../Admin/Resources/Tenant/EditTenantTest.php | 61 ------ .../Admin/Resources/Tenant/ListTenantTest.php | 16 -- .../MembersRelationManagerTest.php | 47 ----- .../Resources/Tenant/TenantResourceTest.php | 11 -- .../Admin/Resources/User/CreateUserTest.php | 30 --- .../Admin/Resources/User/EditUserTest.php | 55 ------ .../Admin/Resources/User/ListUsersTest.php | 14 -- .../Admin/Resources/User/UserResourceTest.php | 11 -- .../ExternalIdentityResource.php | 11 ++ .../Pages/ViewExternalIdentity.php | 42 ++++ .../Schemas/ExternalIdentityForm.php | 72 +++++++ .../Tables/ExternalIdentitiesTable.php | 58 +++++- .../src/Filament/Widgets/ActivityChart.php | 2 +- .../Resources/Badges/CreateBadgeTest.php | 51 +++++ .../Resources/Badges/ListBadgesTest.php | 18 ++ .../Characters/ListCharactersTest.php | 18 ++ .../EventModels/CreateEventModelTest.php | 63 ++++++ .../EventModels/ListEventModelsTest.php | 18 ++ .../Resources/Feedback/ListFeedbackTest.php | 18 ++ .../MeetingTypes/CreateMeetingTypeTest.php | 28 +++ .../MeetingTypes/ListMeetingTypesTest.php | 18 ++ .../Resources/Meetings/ListMeetingsTest.php | 18 ++ .../Resources/Messages/ListMessagesTest.php | 24 +++ .../Resources/Seasons/CreateSeasonTest.php | 48 +++++ .../Resources/Seasons/ListSeasonsTest.php | 18 ++ .../Resources/Sponsors/CreateSponsorTest.php | 36 ++++ .../Resources/Sponsors/ListSponsorsTest.php | 18 ++ .../Resources/Tenants/CreateTenantTest.php | 49 +++++ .../Resources/Tenants/EditTenantTest.php | 22 +++ .../Resources/Tenants/ListTenantsTest.php | 18 ++ .../Resources/Tenants/TenantResourceTest.php | 17 ++ .../Resources/Users/CreateUserTest.php | 48 +++++ .../Feature/Resources/Users/EditUserTest.php | 38 ++++ .../Feature/Resources/Users/ListUsersTest.php | 18 ++ .../Resources/Users/UserResourceTest.php | 17 ++ 70 files changed, 822 insertions(+), 1629 deletions(-) delete mode 100644 app-modules/activity/tests/Feature/Filament/Admin/Message/CreateMessageTest.php delete mode 100644 app-modules/activity/tests/Feature/Filament/Admin/Message/DeleteMessageTest.php delete mode 100644 app-modules/activity/tests/Feature/Filament/Admin/Message/EditMessageTest.php delete mode 100644 app-modules/activity/tests/Feature/Filament/Admin/Message/ListMessageTest.phpTest.php delete mode 100644 app-modules/activity/tests/Feature/Filament/Admin/Message/MessageResourceTest.php delete mode 100644 app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/CreateFeedbackTest.php delete mode 100644 app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/DeleteFeedbackTest.php delete mode 100644 app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/EditFeedbackTest.php delete mode 100644 app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/FeedbackResourceTest.php delete mode 100644 app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/CreateMeetingTest.php delete mode 100644 app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/EditMeetingTest.php delete mode 100644 app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/ListMeetingTest.php delete mode 100644 app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/CreateMeetingTypeTest.php delete mode 100644 app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/EditMeetingTypeTest.php delete mode 100644 app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/ListMeetingTypeTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Event/AttendeesRelationManagerTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Event/EditEventTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Event/ListEventsTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Event/TalkRelationManagerTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Sponsors/EditSponsorTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Sponsors/ListSponsorsTest.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Talk/EditTalk.php delete mode 100644 app-modules/events/tests/Feature/Filament/Admin/Talk/ListTalks.php delete mode 100644 app-modules/gamification/tests/Feature/Badge/Filament/Admin/CreateBadgeTest.php delete mode 100644 app-modules/gamification/tests/Feature/Badge/Filament/Admin/EditBadgeTest.php delete mode 100644 app-modules/gamification/tests/Feature/Badge/Filament/Admin/ListBadgeTest.php delete mode 100644 app-modules/gamification/tests/Feature/Season/Filament/Admin/CreateSeasonTest.php delete mode 100644 app-modules/gamification/tests/Feature/Season/Filament/Admin/EditSeasonTest.php delete mode 100644 app-modules/gamification/tests/Feature/Season/Filament/Admin/ListSeasonTest.php create mode 100644 app-modules/identity/database/migrations/2026_03_22_000001_add_index_to_messages_external_identity_id.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/CreateTenantTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/EditTenantTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/ListTenantTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/MembersRelationManagerTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/TenantResourceTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/User/CreateUserTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/User/EditUserTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/User/ListUsersTest.php delete mode 100644 app-modules/identity/tests/Feature/Filament/Admin/Resources/User/UserResourceTest.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ViewExternalIdentity.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Schemas/ExternalIdentityForm.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Badges/CreateBadgeTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Badges/ListBadgesTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Characters/ListCharactersTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/EventModels/CreateEventModelTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/EventModels/ListEventModelsTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Feedback/ListFeedbackTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/CreateMeetingTypeTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/ListMeetingTypesTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Meetings/ListMeetingsTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Messages/ListMessagesTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Seasons/CreateSeasonTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Seasons/ListSeasonsTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Sponsors/CreateSponsorTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Sponsors/ListSponsorsTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Tenants/CreateTenantTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Tenants/EditTenantTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Tenants/ListTenantsTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Tenants/TenantResourceTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Users/CreateUserTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Users/EditUserTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Users/ListUsersTest.php create mode 100644 app-modules/panel-admin/tests/Feature/Resources/Users/UserResourceTest.php diff --git a/app-modules/activity/tests/Feature/Filament/Admin/Message/CreateMessageTest.php b/app-modules/activity/tests/Feature/Filament/Admin/Message/CreateMessageTest.php deleted file mode 100644 index e57ea082..00000000 --- a/app-modules/activity/tests/Feature/Filament/Admin/Message/CreateMessageTest.php +++ /dev/null @@ -1,46 +0,0 @@ -create(); - $provider = ExternalIdentity::factory() - ->recycle($tenant) - ->create(['provider' => IdentityProvider::Discord]); - $season = Season::factory() - ->recycle($tenant) - ->create(); - - $data = [ - 'tenant_id' => $tenant->getKey(), - 'external_identity_id' => $provider->getKey(), - 'channel_id' => 1, - 'provider_message_id' => 'prov-msg-123', - 'content' => 'Mensagem de teste enviada', - 'sent_at' => now(), - 'obtained_experience' => 50, - ]; - - livewire(CreateMessage::class) - ->fillForm($data) - ->call('create') - ->assertHasNoFormErrors() - ->assertNotified(); - - assertDatabaseHas(Message::class, [ - 'tenant_id' => $tenant->getKey(), - 'external_identity_id' => $provider->getKey(), - 'content' => 'Mensagem de teste enviada', - ]); -}); diff --git a/app-modules/activity/tests/Feature/Filament/Admin/Message/DeleteMessageTest.php b/app-modules/activity/tests/Feature/Filament/Admin/Message/DeleteMessageTest.php deleted file mode 100644 index 94b04915..00000000 --- a/app-modules/activity/tests/Feature/Filament/Admin/Message/DeleteMessageTest.php +++ /dev/null @@ -1,25 +0,0 @@ -create(); - - livewire(EditMessage::class, [ - 'record' => $message->getKey(), - ]) - ->callAction(DeleteAction::class) - ->assertNotified() - ->assertRedirect(); - - assertDatabaseMissing(Message::class, [ - 'id' => $message->getKey(), - ]); -}); diff --git a/app-modules/activity/tests/Feature/Filament/Admin/Message/EditMessageTest.php b/app-modules/activity/tests/Feature/Filament/Admin/Message/EditMessageTest.php deleted file mode 100644 index 735a333a..00000000 --- a/app-modules/activity/tests/Feature/Filament/Admin/Message/EditMessageTest.php +++ /dev/null @@ -1,49 +0,0 @@ -create(); - $season = Season::factory()->create(); - - $newData = [ - 'content' => 'Conteúdo atualizado', - 'obtained_experience' => 200, - ]; - - livewire(EditMessage::class, [ - 'record' => $message->getKey(), - ]) - ->fillForm($newData) - ->call('save') - ->assertHasNoFormErrors() - ->assertNotified(); - - assertDatabaseHas(Message::class, [ - 'id' => $message->getKey(), - 'content' => 'Conteúdo atualizado', - 'obtained_experience' => 200, - ]); -}); - -it('can load the edit page', function (): void { - $message = Message::factory()->create(); - - livewire(EditMessage::class, [ - 'record' => $message->getKey(), - ]) - ->assertOk() - ->assertSchemaStateSet([ - 'external_identity_id' => $message->external_identity_id, - 'channel_id' => $message->channel_id, - 'content' => $message->content, - 'provider_message_id' => $message->provider_message_id, - ]); -}); diff --git a/app-modules/activity/tests/Feature/Filament/Admin/Message/ListMessageTest.phpTest.php b/app-modules/activity/tests/Feature/Filament/Admin/Message/ListMessageTest.phpTest.php deleted file mode 100644 index f2b86b39..00000000 --- a/app-modules/activity/tests/Feature/Filament/Admin/Message/ListMessageTest.phpTest.php +++ /dev/null @@ -1,16 +0,0 @@ -count(5)->create(); - - livewire(ListMessages::class) - ->assertOk() - ->assertCanSeeTableRecords($messages); -}); diff --git a/app-modules/activity/tests/Feature/Filament/Admin/Message/MessageResourceTest.php b/app-modules/activity/tests/Feature/Filament/Admin/Message/MessageResourceTest.php deleted file mode 100644 index 00292547..00000000 --- a/app-modules/activity/tests/Feature/Filament/Admin/Message/MessageResourceTest.php +++ /dev/null @@ -1,11 +0,0 @@ -toContain(MessageResource::class); -}); diff --git a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/CreateFeedbackTest.php b/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/CreateFeedbackTest.php deleted file mode 100644 index 6736ddd2..00000000 --- a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/CreateFeedbackTest.php +++ /dev/null @@ -1,35 +0,0 @@ -setCurrentPanel('admin'); - $sender = User::factory()->create(); - $target = User::factory()->create(); - - $tenant = Tenant::factory()->create(); - - $data = [ - 'sender_id' => $sender->getKey(), - 'target_id' => $target->getKey(), - 'tenant_id' => $tenant->getKey(), - 'type' => 'compliment', - 'message' => 'Bom trabalho', - ]; - - livewire(CreateFeedback::class) - ->fillForm($data) - ->call('create') - ->assertHasNoFormErrors() - ->assertNotified(); - - assertDatabaseHas(Feedback::class, $data); -}); diff --git a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/DeleteFeedbackTest.php b/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/DeleteFeedbackTest.php deleted file mode 100644 index b91283ad..00000000 --- a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/DeleteFeedbackTest.php +++ /dev/null @@ -1,26 +0,0 @@ -setCurrentPanel('admin'); - $feedback = Feedback::factory()->create(); - - livewire(EditFeedback::class, [ - 'record' => $feedback->getKey(), - ]) - ->callAction(DeleteAction::class) - ->assertNotified() - ->assertRedirect(); - - assertDatabaseMissing(Feedback::class, [ - 'id' => $feedback->getKey(), - ]); -}); diff --git a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/EditFeedbackTest.php b/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/EditFeedbackTest.php deleted file mode 100644 index c503e938..00000000 --- a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/EditFeedbackTest.php +++ /dev/null @@ -1,50 +0,0 @@ -setCurrentPanel('admin'); - /** @var Feedback $feedback */ - $feedback = Feedback::factory()->create(); - - livewire(EditFeedback::class, [ - 'record' => $feedback->getKey(), - ]) - ->assertOk() - ->assertSchemaStateSet([ - 'sender_id' => $feedback->sender_id, - 'target_id' => $feedback->target_id, - 'type' => $feedback->type, - 'message' => $feedback->message, - ]); -}); - -it('can update feedback', function (): void { - filament()->setCurrentPanel('admin'); - $feedback = Feedback::factory()->create(); - - $newData = [ - 'type' => 'compliment', - 'message' => 'Precisa melhorar', - ]; - - livewire(EditFeedback::class, [ - 'record' => $feedback->getKey(), - ]) - ->fillForm($newData) - ->call('save') - ->assertHasNoFormErrors() - ->assertNotified(); - - assertDatabaseHas(Feedback::class, [ - 'id' => $feedback->getKey(), - 'type' => $newData['type'], - 'message' => $newData['message'], - ]); -}); diff --git a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/FeedbackResourceTest.php b/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/FeedbackResourceTest.php deleted file mode 100644 index 7a7ea8d2..00000000 --- a/app-modules/community/tests/Feature/Feedback/Filament/Admin/Feedback/FeedbackResourceTest.php +++ /dev/null @@ -1,12 +0,0 @@ -setCurrentPanel('admin'); - expect(Filament::getResources()) - ->toContain(FeedbackResource::class); -}); diff --git a/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/CreateMeetingTest.php b/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/CreateMeetingTest.php deleted file mode 100644 index d38998e1..00000000 --- a/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/CreateMeetingTest.php +++ /dev/null @@ -1,52 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - livewire(CreateMeeting::class) - ->assertOk(); -}); - -it('should be able to create a meet', function (): void { - $admin = User::factory()->create(); - $tenant = Tenant::factory()->create(); - $meetingType = MeetingType::factory()->create(); - - livewire(CreateMeeting::class) - ->assertOk() - ->fillForm([ - 'tenant_id' => $tenant->getKey(), - 'admin_id' => $admin->getKey(), - 'content' => 'content', - 'meeting_type_id' => $meetingType->getKey(), - 'starts_at' => Date::yesterday(), - 'ends_at' => Date::tomorrow(), - ]) - ->call('create') - ->assertHasNoFormErrors(); - - assertDatabaseCount(Meeting::class, 1); - assertDatabaseHas(Meeting::class, [ - 'tenant_id' => $tenant->getKey(), - 'admin_id' => $admin->getKey(), - 'meeting_type_id' => $meetingType->getKey(), - ]); -}); diff --git a/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/EditMeetingTest.php b/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/EditMeetingTest.php deleted file mode 100644 index f3fa1f68..00000000 --- a/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/EditMeetingTest.php +++ /dev/null @@ -1,21 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - $meeting = Meeting::factory()->create(); - livewire(EditMeeting::class, ['record' => $meeting->getKey()]) - ->assertOk(); -}); diff --git a/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/ListMeetingTest.php b/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/ListMeetingTest.php deleted file mode 100644 index de28c85f..00000000 --- a/app-modules/community/tests/Feature/Meeting/Filament/Admin/Meeting/ListMeetingTest.php +++ /dev/null @@ -1,19 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - livewire(ListMeetings::class) - ->assertOk(); -}); diff --git a/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/CreateMeetingTypeTest.php b/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/CreateMeetingTypeTest.php deleted file mode 100644 index f17a5897..00000000 --- a/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/CreateMeetingTypeTest.php +++ /dev/null @@ -1,41 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - livewire(CreateMeetingType::class) - ->assertOk(); -}); - -it('should be able to create a meet', function (): void { - livewire(CreateMeetingType::class) - ->assertOk() - ->fillForm([ - 'name' => 'meeting type name', - 'week_day' => 1, - 'start_at' => '01:00:00', - ]) - ->call('create') - ->assertHasNoFormErrors(); - - assertDatabaseCount(MeetingType::class, 1); - assertDatabaseHas(MeetingType::class, [ - 'name' => 'meeting type name', - 'week_day' => 1, - 'start_at' => '01:00:00', - ]); -}); diff --git a/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/EditMeetingTypeTest.php b/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/EditMeetingTypeTest.php deleted file mode 100644 index 5171239e..00000000 --- a/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/EditMeetingTypeTest.php +++ /dev/null @@ -1,21 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - $meetingType = MeetingType::factory()->create(); - livewire(EditMeetingType::class, ['record' => $meetingType->getKey()]) - ->assertOk(); -}); diff --git a/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/ListMeetingTypeTest.php b/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/ListMeetingTypeTest.php deleted file mode 100644 index 33b75053..00000000 --- a/app-modules/community/tests/Feature/Meeting/Filament/Admin/MeetingType/ListMeetingTypeTest.php +++ /dev/null @@ -1,19 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - livewire(ListMeetingTypes::class) - ->assertOk(); -}); diff --git a/app-modules/events/src/Models/EventModel.php b/app-modules/events/src/Models/EventModel.php index bf7865e1..44387e8e 100644 --- a/app-modules/events/src/Models/EventModel.php +++ b/app-modules/events/src/Models/EventModel.php @@ -4,7 +4,6 @@ namespace He4rt\Events\Models; -use He4rt\Events\Models\Pivot\SponsorAttend; use Carbon\Carbon; use Exception; use He4rt\Events\Database\Factories\EventFactory; @@ -12,6 +11,7 @@ use He4rt\Events\Enums\EventTypeEnum; use He4rt\Events\Enums\Talks\TalkStatusEnum; use He4rt\Events\Models\Pivot\EventAttend; +use He4rt\Events\Models\Pivot\SponsorAttend; use He4rt\Identity\Tenant\Models\Tenant; use He4rt\Identity\User\Models\User; use Illuminate\Database\Eloquent\Attributes\Scope; @@ -180,7 +180,7 @@ public function agenda(): HasMany } /** - * @return BelongsToMany + * @return BelongsToMany */ public function sponsors(): BelongsToMany { diff --git a/app-modules/events/tests/Feature/Filament/Admin/Event/AttendeesRelationManagerTest.php b/app-modules/events/tests/Feature/Filament/Admin/Event/AttendeesRelationManagerTest.php deleted file mode 100644 index 41d2affd..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Event/AttendeesRelationManagerTest.php +++ /dev/null @@ -1,120 +0,0 @@ -user = User::factory()->create(); - actingAs($this->user); - $this->tenant = Tenant::factory()->create(); - $this->event = EventModel::factory()->recycle($this->tenant)->create(); - Filament::setCurrentPanel('admin'); -}); - -it('should render', function (): void { - livewire(AttendeesRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ])->assertOk(); -}); - -it('should list event attendees', function (): void { - $attendees = User::factory()->count(5)->create(); - - foreach ($attendees as $attendee) { - $this->event->attendees()->attach($attendee->getKey(), [ - 'status' => AttendingStatusEnum::Attending, - ]); - } - - livewire(AttendeesRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->assertCanSeeTableRecords($attendees) - ->assertCountTableRecords(5); -}); - -it('should display attendee columns correctly', function (): void { - $attendee = User::factory()->create([ - 'username' => 'johndoe', - 'email' => 'john@example.com', - 'is_donator' => true, - ]); - - $this->event->attendees()->attach($attendee->getKey(), [ - 'status' => AttendingStatusEnum::Attending, - ]); - - livewire(AttendeesRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->assertCanSeeTableRecords([$attendee]) - ->assertTableColumnExists('username') - ->assertTableColumnExists('email') - ->assertTableColumnExists('is_donator') - ->assertTableColumnExists('pivot.status'); -}); - -it('should detach attendee using leave method', function (): void { - $attendee = User::factory()->create(); - - $this->event->attendees()->attach($attendee->getKey(), [ - 'status' => AttendingStatusEnum::Attending, - ]); - - $this->event->increment('attendees_count'); - - expect($this->event->fresh()->attendees_count)->toBe(1) - ->and($this->event->attendees()->count())->toBe(1); - - TestAction::make(DetachAction::class)->table(); - - livewire(AttendeesRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->assertCanSeeTableRecords([$attendee]) - ->callTableAction('detach', $attendee); - - expect($this->event->fresh()->attendees_count)->toBe(0) - ->and($this->event->attendees()->count())->toBe(0); -}); - -it('should decrement waitlist_count when detaching waitlisted attendee', function (): void { - $attendee = User::factory()->create(); - - $this->event->attendees()->attach($attendee->getKey(), [ - 'status' => AttendingStatusEnum::Waitlist, - ]); - $this->event->increment('waitlist_count'); - - expect($this->event->fresh()->waitlist_count)->toBe(1); - - TestAction::make(DetachAction::class)->table(); - - livewire(AttendeesRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->callTableAction('detach', $attendee); - - expect($this->event->fresh()->waitlist_count)->toBe(0) - ->and($this->event->attendees()->count())->toBe(0); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php b/app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php deleted file mode 100644 index 5d6b942b..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php +++ /dev/null @@ -1,165 +0,0 @@ -value); - $this->actingAsAdmin(); - $this->tenant = Tenant::query()->first(); -}); - -it('should render', function (): void { - livewire(CreateEvent::class) - ->assertOk(); -}); - -it('should be able to create an event', function (): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'tenant_id' => $this->tenant->getKey(), - 'title' => 'event title', - 'slug' => 'event-slug', - 'description' => 'event description', - 'location' => 'event location', - 'max_attendees' => 5, - 'event_type' => EventTypeEnum::Workshop->value, - 'active' => true, - 'event_at' => today(), - 'start_at' => today(), - 'end_at' => Date::tomorrow(), - ]) - ->call('create') - ->assertHasNoFormErrors(); - - assertDatabaseCount(EventModel::class, 1); - assertDatabaseHas(EventModel::class, [ - 'tenant_id' => $this->tenant->getKey(), - 'title' => 'event title', - 'slug' => 'event-slug', - 'location' => 'event location', - 'max_attendees' => 5, - 'event_type' => EventTypeEnum::Workshop->value, - 'active' => true, - 'event_at' => today(), - 'start_at' => today(), - 'end_at' => Date::tomorrow(), - ]); -}); - -describe('validation tests', function (): void { - - test('title::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'title' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['title' => $rule]); - })->with([ - 'required' => ['', 'required'], - 'min' => ['aa', 'min:5'], - 'max' => [str_repeat('a', 256), 'max:255'], - ]); - test('location::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'location' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['location' => $rule]); - })->with([ - 'required' => ['', 'required'], - 'min' => ['aa', 'min:5'], - 'max' => [str_repeat('a', 256), 'max:255'], - ]); - - test('event_type::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'event_type' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['event_type' => $rule]); - })->with([ - 'required' => ['', 'required'], - 'enum' => ['aa', 'The selected event Type is invalid.'], - ]); - - test('max_attendees::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'max_attendees' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['max_attendees' => $rule]); - })->with([ - 'required' => [null, 'required'], - 'min 1' => [-1, 'min'], - ]); - - test('active::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'active' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['active' => $rule]); - })->with([ - 'required' => [null, 'required'], - ]); - test('event_at::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'event_at' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['event_at' => $rule]); - })->with([ - 'required' => [null, 'required'], - ]); - - test('start_at::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'start_at' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['start_at' => $rule]); - })->with([ - 'required' => [null, 'required'], - ]); - - test('end_at::validations', function ($value, $rule): void { - livewire(CreateEvent::class) - ->assertOk() - ->fillForm([ - 'start_at' => now(), - 'end_at' => $value, - ]) - ->call('create') - ->assertHasFormErrors(['end_at' => $rule]); - })->with([ - 'required' => [null, 'required'], - 'after' => [Date::yesterday(), 'after'], - ]); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Event/EditEventTest.php b/app-modules/events/tests/Feature/Filament/Admin/Event/EditEventTest.php deleted file mode 100644 index 12ba92a8..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Event/EditEventTest.php +++ /dev/null @@ -1,18 +0,0 @@ -value); - $event = EventModel::factory()->createOne(); - $this->actingAsAdmin(); - livewire(EditEvent::class, ['record' => $event->getKey()]) - ->assertOk(); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Event/ListEventsTest.php b/app-modules/events/tests/Feature/Filament/Admin/Event/ListEventsTest.php deleted file mode 100644 index 6db39eb7..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Event/ListEventsTest.php +++ /dev/null @@ -1,16 +0,0 @@ -value); - $this->actingAsAdmin(); - livewire(ListEvents::class) - ->assertOk(); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Event/TalkRelationManagerTest.php b/app-modules/events/tests/Feature/Filament/Admin/Event/TalkRelationManagerTest.php deleted file mode 100644 index 3d05d301..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Event/TalkRelationManagerTest.php +++ /dev/null @@ -1,179 +0,0 @@ -user = User::factory()->create(); - actingAs($this->user); - $this->tenant = Tenant::factory()->create(); - $this->event = EventModel::factory()->recycle($this->tenant)->create(); - Filament::setCurrentPanel('admin'); -}); - -it('should render', function (): void { - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ])->assertOk(); -}); - -it('should list event talks', function (): void { - $talks = EventSubmission::factory() - ->recycle($this->event) - ->recycle($this->tenant) - ->count(5) - ->create(); - - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->assertCanSeeTableRecords($talks) - ->assertCountTableRecords(5); -}); - -it('should have create action', function (): void { - $action = TestAction::make(CreateAction::class)->table(); - - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->assertActionExists($action); -}); - -it('should create a talk for the event', function (): void { - $speaker = User::factory()->create(); - $action = TestAction::make(CreateAction::class)->table(); - - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->mountAction($action) - ->fillForm([ - 'user_id' => $speaker->getKey(), - 'tenant_id' => $this->tenant->getKey(), - 'title' => 'Introduction to Laravel', - 'description' => 'A beginner friendly talk about Laravel', - 'status' => TalkStatusEnum::Accepted->value, - 'field_type' => 'talk', - 'starts_at' => $this->event->start_at, - 'ends_at' => $this->event->start_at->addHour(), - ]) - ->callMountedAction() - ->assertHasNoFormErrors() - ->assertCountTableRecords(1); - - $talk = $this->event->fresh()->talks()->first(); - - expect($talk) - ->title->toBe('Introduction to Laravel') - ->user_id->toBe($speaker->getKey()) - ->event_id->toBe($this->event->getKey()) - ->tenant_id->toBe($this->tenant->getKey()) - ->status->toBe(TalkStatusEnum::Accepted); -}); - -it('should associate talk with event automatically', function (): void { - $speaker = User::factory()->create(); - $action = TestAction::make(CreateAction::class)->table(); - - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->mountAction($action) - ->fillForm([ - 'user_id' => $speaker->getKey(), - 'tenant_id' => $this->tenant->getKey(), - 'title' => 'My EventSubmission', - 'description' => '

EventSubmission description

', - 'status' => TalkStatusEnum::Pending->value, - 'field_type' => 'talk', - 'starts_at' => $this->event->start_at, - 'ends_at' => $this->event->start_at->addHour(), - ]) - ->callMountedAction(); - - $talk = EventSubmission::query()->first(); - - expect($talk->event_id)->toBe($this->event->getKey()); -}); - -it('should validate required fields when creating talk', function (): void { - $action = TestAction::make(CreateAction::class)->table(); - - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->mountAction($action) - ->fillForm([ - 'title' => '', - 'description' => '', - ]) - ->callMountedAction() - ->assertHasFormErrors(['title', 'user_id']); -}); - -it('should list talks with different statuses', function (): void { - $pendingTalk = EventSubmission::factory() - ->recycle($this->event) - ->recycle($this->tenant) - ->create(['status' => TalkStatusEnum::Pending]); - - $acceptedTalk = EventSubmission::factory() - ->recycle($this->event) - ->recycle($this->tenant) - ->create(['status' => TalkStatusEnum::Accepted]); - - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->assertCanSeeTableRecords([$pendingTalk, $acceptedTalk]) - ->assertCountTableRecords(2); -}); - -it('should only show talks belonging to the event', function (): void { - $eventTalks = EventSubmission::factory() - ->recycle($this->event) - ->recycle($this->tenant) - ->count(3) - ->create(); - - $otherEvent = EventModel::factory()->recycle($this->tenant)->create(); - $otherTalks = EventSubmission::factory() - ->recycle($otherEvent) - ->recycle($this->tenant) - ->count(2) - ->create(); - - livewire(TalksRelationManager::class, [ - 'ownerRecord' => $this->event, - 'pageClass' => EditEvent::class, - ]) - ->assertOk() - ->assertCanSeeTableRecords($eventTalks) - ->assertCanNotSeeTableRecords($otherTalks) - ->assertCountTableRecords(3); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php b/app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php deleted file mode 100644 index 4bb0f05e..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php +++ /dev/null @@ -1,54 +0,0 @@ -value); - $this->actingAsAdmin(); - - livewire(CreateSponsor::class) - ->assertOk(); -}); - -it('should be able to register a sponsor', function (): void { - Storage::fake('public'); - $image = UploadedFile::fake()->image('image.jpg'); - Filament::setCurrentPanel(FilamentPanel::Admin->value); - $this->actingAsAdmin(); - - $tenant = Tenant::query()->first(); - - livewire(CreateSponsor::class) - ->assertOk() - ->fillForm([ - 'tenant_id' => $tenant->getKey(), - 'name' => 'sponsor name', - 'receipt' => $image, - 'homepage_url' => 'https://www.google.com', - ]) - ->call('create') - ->assertHasNoFormErrors(); - - assertDatabaseCount(Sponsor::class, 1); - - assertDatabaseHas(Sponsor::class, [ - 'tenant_id' => $tenant->getKey(), - 'name' => 'sponsor name', - 'homepage_url' => 'https://www.google.com', - ]); - - $sponsor = Sponsor::query()->first(); - expect(count($sponsor->getMediaRepository()->all()))->toBe(1); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/EditSponsorTest.php b/app-modules/events/tests/Feature/Filament/Admin/Sponsors/EditSponsorTest.php deleted file mode 100644 index 677b6442..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/EditSponsorTest.php +++ /dev/null @@ -1,19 +0,0 @@ -create(); - Filament::setCurrentPanel(FilamentPanel::Admin->value); - $this->actingAsAdmin(); - - livewire(EditSponsor::class, ['record' => $sponsor->getKey()]) - ->assertOk(); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/ListSponsorsTest.php b/app-modules/events/tests/Feature/Filament/Admin/Sponsors/ListSponsorsTest.php deleted file mode 100644 index a2995a4d..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/ListSponsorsTest.php +++ /dev/null @@ -1,17 +0,0 @@ -value); - $this->actingAsAdmin(); - - livewire(ListSponsors::class) - ->assertOk(); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php b/app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php deleted file mode 100644 index 9576ee2e..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Talk/CreateTalk.php +++ /dev/null @@ -1,55 +0,0 @@ -value); - $this->actingAsAdmin(); - livewire(CreateTalk::class) - ->assertOk(); -}); - -it('should be able to register a talk', function (): void { - Filament::setCurrentPanel(FilamentPanel::Admin->value); - $this->actingAsAdmin(); - $event = EventModel::factory()->create(); - $user = User::factory()->create(); - livewire(CreateTalk::class) - ->assertOk() - ->fillForm([ - 'tenant_id' => 1, - 'user_id' => $user->getKey(), - 'event_id' => $event->getKey(), - 'title' => 'talk title', - 'status' => TalkStatusEnum::Pending->value, - 'field_type' => 'some text right there', - 'description' => 'description you know', - 'starts_at' => now(), - 'ends_at' => now()->addHour(), - ]) - ->call('create') - ->assertHasNoFormErrors(); - - assertDatabaseCount(EventSubmission::class, 1); - assertDatabaseHas(EventSubmission::class, [ - 'tenant_id' => 1, - 'user_id' => $user->getKey(), - 'event_id' => $event->getKey(), - 'title' => 'talk title', - 'status' => TalkStatusEnum::Pending->value, - 'field_type' => 'some text right there', - 'description' => '

description you know

', - ]); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Talk/EditTalk.php b/app-modules/events/tests/Feature/Filament/Admin/Talk/EditTalk.php deleted file mode 100644 index 405b4c48..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Talk/EditTalk.php +++ /dev/null @@ -1,18 +0,0 @@ -create(); - Filament::setCurrentPanel(FilamentPanel::Admin->value); - $this->actingAsAdmin(); - - livewire(EditTalk::class, ['record' => $talk->getKey()]) - ->assertOk(); -}); diff --git a/app-modules/events/tests/Feature/Filament/Admin/Talk/ListTalks.php b/app-modules/events/tests/Feature/Filament/Admin/Talk/ListTalks.php deleted file mode 100644 index a6b7d8b8..00000000 --- a/app-modules/events/tests/Feature/Filament/Admin/Talk/ListTalks.php +++ /dev/null @@ -1,15 +0,0 @@ -value); - $this->actingAsAdmin(); - livewire(ListTalks::class) - ->assertOk(); -}); diff --git a/app-modules/gamification/tests/Feature/Badge/Filament/Admin/CreateBadgeTest.php b/app-modules/gamification/tests/Feature/Badge/Filament/Admin/CreateBadgeTest.php deleted file mode 100644 index 0045c670..00000000 --- a/app-modules/gamification/tests/Feature/Badge/Filament/Admin/CreateBadgeTest.php +++ /dev/null @@ -1,59 +0,0 @@ -createOne()); -}); - -it('should render', function (): void { - livewire(CreateBadge::class) - ->assertOk(); -}); - -it('should be able to create a badge', function (): void { - Storage::fake('public'); - $image = UploadedFile::fake()->image('image.jpg'); - $tenant = Tenant::factory()->create(); - - livewire(CreateBadge::class) - ->assertOk() - ->fillForm([ - 'tenant_id' => $tenant->getKey(), - 'provider' => IdentityProvider::Discord, - 'name' => 'name', - 'description' => 'description', - 'badge' => $image, - 'redeem_code' => 'redeem_code', - 'active' => true, - ]) - ->call('create') - ->assertHasNoFormErrors(); - - assertDatabaseCount(Badge::class, 1); - assertDatabaseHas(Badge::class, [ - 'tenant_id' => $tenant->getKey(), - 'provider' => IdentityProvider::Discord->value, - 'name' => 'name', - 'redeem_code' => 'redeem_code', - 'active' => 1, - ]); - $badge = Badge::query()->first(); - - expect(count($badge->getMediaRepository()->all()))->toBe(1); -}); diff --git a/app-modules/gamification/tests/Feature/Badge/Filament/Admin/EditBadgeTest.php b/app-modules/gamification/tests/Feature/Badge/Filament/Admin/EditBadgeTest.php deleted file mode 100644 index 55bcbe56..00000000 --- a/app-modules/gamification/tests/Feature/Badge/Filament/Admin/EditBadgeTest.php +++ /dev/null @@ -1,20 +0,0 @@ -createOne()); - $badge = Badge::factory()->create(); - - livewire(EditBadge::class, ['record' => $badge->getKey()]) - ->assertOk(); -}); diff --git a/app-modules/gamification/tests/Feature/Badge/Filament/Admin/ListBadgeTest.php b/app-modules/gamification/tests/Feature/Badge/Filament/Admin/ListBadgeTest.php deleted file mode 100644 index 7cb4f6c4..00000000 --- a/app-modules/gamification/tests/Feature/Badge/Filament/Admin/ListBadgeTest.php +++ /dev/null @@ -1,17 +0,0 @@ -createOne()); - livewire(ListBadges::class) - ->assertOk(); -}); diff --git a/app-modules/gamification/tests/Feature/Season/Filament/Admin/CreateSeasonTest.php b/app-modules/gamification/tests/Feature/Season/Filament/Admin/CreateSeasonTest.php deleted file mode 100644 index 32cda1d2..00000000 --- a/app-modules/gamification/tests/Feature/Season/Filament/Admin/CreateSeasonTest.php +++ /dev/null @@ -1,55 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - livewire(CreateSeason::class) - ->assertOk(); -}); - -it('should be able to create a new season', function (): void { - $tenant = Tenant::factory()->create(); - livewire(CreateSeason::class) - ->assertOk() - ->fillForm([ - 'tenant_id' => $tenant->getKey(), - 'name' => 'season 1', - 'description' => 'description da season', - 'started_at' => Date::yesterday(), - 'ended_at' => Date::tomorrow(), - 'messages_count' => 5, - 'participants_count' => 5, - 'meeting_count' => 5, - 'badges_count' => 5, - ]) - ->call('create') - ->assertHasNoFormErrors(); - - assertDatabaseCount(Season::class, 1); - assertDatabaseHas(Season::class, [ - 'tenant_id' => $tenant->getKey(), - 'name' => 'season 1', - 'started_at' => Date::yesterday(), - 'ended_at' => Date::tomorrow(), - 'messages_count' => 5, - 'participants_count' => 5, - 'meeting_count' => 5, - 'badges_count' => 5, - ]); -}); diff --git a/app-modules/gamification/tests/Feature/Season/Filament/Admin/EditSeasonTest.php b/app-modules/gamification/tests/Feature/Season/Filament/Admin/EditSeasonTest.php deleted file mode 100644 index 9af8440e..00000000 --- a/app-modules/gamification/tests/Feature/Season/Filament/Admin/EditSeasonTest.php +++ /dev/null @@ -1,21 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - $season = Season::factory()->create(); - livewire(EditSeason::class, ['record' => $season->getKey()]) - ->assertOk(); -}); diff --git a/app-modules/gamification/tests/Feature/Season/Filament/Admin/ListSeasonTest.php b/app-modules/gamification/tests/Feature/Season/Filament/Admin/ListSeasonTest.php deleted file mode 100644 index 8493f0ee..00000000 --- a/app-modules/gamification/tests/Feature/Season/Filament/Admin/ListSeasonTest.php +++ /dev/null @@ -1,19 +0,0 @@ -value); - $this->actingAsAdmin(); -}); - -it('should render', function (): void { - livewire(ListSeasons::class) - ->assertOk(); -}); diff --git a/app-modules/identity/database/migrations/2026_03_22_000001_add_index_to_messages_external_identity_id.php b/app-modules/identity/database/migrations/2026_03_22_000001_add_index_to_messages_external_identity_id.php new file mode 100644 index 00000000..11988284 --- /dev/null +++ b/app-modules/identity/database/migrations/2026_03_22_000001_add_index_to_messages_external_identity_id.php @@ -0,0 +1,24 @@ +index('external_identity_id'); + }); + } + + public function down(): void + { + Schema::table('messages', function (Blueprint $table): void { + $table->dropIndex(['external_identity_id']); + }); + } +}; diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/CreateTenantTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/CreateTenantTest.php deleted file mode 100644 index 5b5ef91b..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/CreateTenantTest.php +++ /dev/null @@ -1,62 +0,0 @@ -assertOk(); -}); - -it('can create a tenant', function (): void { - $owner = User::factory()->create(); - - livewire(CreateTenant::class) - ->fillForm([ - 'name' => 'My Tenant', - 'slug' => 'my-tenant', - 'domain' => 'my-tenant.test', - 'owner_id' => $owner->id, - 'active' => true, - ]) - ->call('create') - ->assertNotified() - ->assertRedirect(); - - $this->assertDatabaseHas(Tenant::class, [ - 'name' => 'My Tenant', - 'slug' => 'my-tenant', - 'domain' => 'my-tenant.test', - 'owner_id' => $owner->id, - 'active' => true, - ]); -}); - -test('name field should fill slug after updated ', function (): void { - $owner = User::factory()->create(); - - livewire(CreateTenant::class) - ->fillForm([ - 'name' => 'My Tenant', - 'owner_id' => $owner->id, - 'domain' => 'my-tenant.test', - 'active' => true, - ]) - ->assertSchemaComponentStateSet('slug', 'my-tenant') - ->call('create') - ->assertNotified() - ->assertRedirect(); - - $this->assertDatabaseHas(Tenant::class, [ - 'name' => 'My Tenant', - 'slug' => 'my-tenant', - 'domain' => 'my-tenant.test', - 'owner_id' => $owner->id, - 'active' => true, - ]); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/EditTenantTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/EditTenantTest.php deleted file mode 100644 index 5c1510ab..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/EditTenantTest.php +++ /dev/null @@ -1,61 +0,0 @@ -create(); - - livewire(EditTenant::class, [ - 'record' => $tenant->id, - ]) - ->assertOk() - ->assertSchemaStateSet([ - 'name' => $tenant->name, - 'slug' => $tenant->slug, - 'owner_id' => $tenant->owner_id, - 'active' => $tenant->active, - ]); -}); - -it('can update a tenant', function (): void { - $tenant = Tenant::factory()->create(); - $newTenantData = Tenant::factory()->make(); - - livewire(EditTenant::class, [ - 'record' => $tenant->id, - ]) - ->fillForm([ - 'name' => $newTenantData->name, - 'slug' => $newTenantData->slug, - 'domain' => 'my-tenant.test', - 'active' => $newTenantData->active, - ]) - ->call('save') - ->assertNotified(); - - assertDatabaseHas(Tenant::class, [ - 'id' => $tenant->id, - 'name' => $newTenantData->name, - 'slug' => $newTenantData->slug, - ]); -}); - -it('can delete a tenant', function (): void { - $tenant = Tenant::factory()->create(); - - livewire(EditTenant::class, [ - 'record' => $tenant->id, - ]) - ->callAction(DeleteAction::class) - ->assertNotified() - ->assertRedirect(); - - $this->assertSoftDeleted($tenant); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/ListTenantTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/ListTenantTest.php deleted file mode 100644 index 42925acb..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/ListTenantTest.php +++ /dev/null @@ -1,16 +0,0 @@ -count(5)->create(); - - livewire(ListTenants::class) - ->assertOk() - ->assertCanSeeTableRecords($tenants); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/MembersRelationManagerTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/MembersRelationManagerTest.php deleted file mode 100644 index d3bddd58..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/RelationManagers/MembersRelationManagerTest.php +++ /dev/null @@ -1,47 +0,0 @@ -user = User::factory()->create(); - actingAs($this->user); - $this->tenant = Tenant::factory()->create(); - Filament::setCurrentPanel('admin'); -}); - -it('should render', function (): void { - livewire(MembersRelationManager::class, ['ownerRecord' => $this->tenant, 'pageClass' => EditTenant::class]) - ->assertOk(); -}); - -it('should list the tenant members', function (): void { - $users = User::factory()->count(5)->create(); - $this->tenant->members()->attach($users->pluck('id')); - livewire(MembersRelationManager::class, ['ownerRecord' => $this->tenant, 'pageClass' => EditTenant::class]) - ->assertOk() - ->assertCanSeeTableRecords($users) - ->assertCountTableRecords($users->count()); -}); -it('should be able to detach an user', function (): void { - $users = User::factory()->count(5)->create(); - $this->tenant->members()->attach($users->pluck('id')); - - $action = TestAction::make(DetachAction::class)->table(); - livewire(MembersRelationManager::class, ['ownerRecord' => $this->tenant, 'pageClass' => EditTenant::class]) - ->assertOk() - ->selectTableRecords($users->pluck('id')->toArray()) - ->callAction($action->bulk()) - ->assertHasNoFormErrors() - ->assertCountTableRecords(0); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/TenantResourceTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/TenantResourceTest.php deleted file mode 100644 index 33c2a1bd..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/Tenant/TenantResourceTest.php +++ /dev/null @@ -1,11 +0,0 @@ -toContain(TenantResource::class); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/CreateUserTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/CreateUserTest.php deleted file mode 100644 index 24c76853..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/CreateUserTest.php +++ /dev/null @@ -1,30 +0,0 @@ -livewire(CreateUser::class) - ->assertOk(); -}); - -it('can create a user', function (): void { - $this->livewire(CreateUser::class) - ->fillForm([ - 'username' => 'newuser', - 'name' => 'New User', - 'email' => 'emailmaneiro@example.com', - 'password' => 'password', - ]) - ->call('create') - ->assertNotified() - ->assertRedirect(); - - $this->assertDatabaseHas(User::class, [ - 'username' => 'newuser', - 'name' => 'New User', - 'email' => 'emailmaneiro@example.com', - ]); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/EditUserTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/EditUserTest.php deleted file mode 100644 index 1f2937be..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/EditUserTest.php +++ /dev/null @@ -1,55 +0,0 @@ -create(); - - $this->livewire(EditUser::class, [ - 'record' => $user->id, - ]) - ->assertOk() - ->assertSchemaStateSet([ - 'username' => $user->username, - 'email' => $user->email, - ]); -}); - -it('can update a user', function (): void { - $user = User::factory()->create(); - - $this->livewire(EditUser::class, [ - 'record' => $user->id, - ]) - ->fillForm([ - 'username' => 'fulano', - 'email' => 'fulano@email.com', - 'zip_code' => '13000-000', - ]) - ->call('save') - ->assertHasNoFormErrors() - ->assertNotified(); - - $this->assertDatabaseHas(User::class, [ - 'id' => $user->id, - 'username' => 'fulano', - 'email' => 'fulano@email.com', - ]); -}); - -it('can delete a user', function (): void { - $user = User::factory()->create(); - - $this->livewire(EditUser::class, [ - 'record' => $user->id, - ]) - ->callAction(DeleteAction::class) - ->assertNotified() - ->assertRedirect(); - - $this->assertDatabaseMissing($user); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/ListUsersTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/ListUsersTest.php deleted file mode 100644 index f768a36b..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/ListUsersTest.php +++ /dev/null @@ -1,14 +0,0 @@ -count(5)->create(); - - $this->livewire(ListUsers::class) - ->assertOk() - ->assertCanSeeTableRecords($users); -}); diff --git a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/UserResourceTest.php b/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/UserResourceTest.php deleted file mode 100644 index 76d12fac..00000000 --- a/app-modules/identity/tests/Feature/Filament/Admin/Resources/User/UserResourceTest.php +++ /dev/null @@ -1,11 +0,0 @@ -toContain(UserResource::class); -}); diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php index 08e957fa..ab373079 100644 --- a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php @@ -6,10 +6,13 @@ use BackedEnum; use Filament\Resources\Resource; +use Filament\Schemas\Schema; use Filament\Support\Icons\Heroicon; use Filament\Tables\Table; use He4rt\Identity\ExternalIdentity\Models\ExternalIdentity; use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Pages\ListExternalIdentities; +use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Pages\ViewExternalIdentity; +use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Schemas\ExternalIdentityForm; use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Tables\ExternalIdentitiesTable; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; @@ -25,6 +28,13 @@ class ExternalIdentityResource extends Resource protected static ?int $navigationSort = 3; + protected static ?string $recordTitleAttribute = 'external_account_id'; + + public static function form(Schema $schema): Schema + { + return ExternalIdentityForm::configure($schema); + } + public static function table(Table $table): Table { return ExternalIdentitiesTable::configure($table); @@ -45,6 +55,7 @@ public static function getPages(): array { return [ 'index' => ListExternalIdentities::route('/'), + 'edit' => ViewExternalIdentity::route('/{record}/edit'), ]; } diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ViewExternalIdentity.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ViewExternalIdentity.php new file mode 100644 index 00000000..7fbf5d53 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ViewExternalIdentity.php @@ -0,0 +1,42 @@ +label('Disconnect') + ->icon(Heroicon::NoSymbol) + ->color('danger') + ->visible(fn () => $this->record->isConnected()) + ->requiresConfirmation() + ->action(fn () => $this->record->update(['disconnected_at' => now()])) + ->successNotificationTitle('Identity disconnected'), + DeleteAction::make(), + RestoreAction::make(), + ForceDeleteAction::make(), + ]; + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Schemas/ExternalIdentityForm.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Schemas/ExternalIdentityForm.php new file mode 100644 index 00000000..04735504 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Schemas/ExternalIdentityForm.php @@ -0,0 +1,72 @@ +columns(1) + ->components([ + Tabs::make('ExternalIdentity') + ->tabs([ + Tab::make('Identity') + ->icon(Heroicon::Link) + ->schema([ + Placeholder::make('provider') + ->content(fn (?ExternalIdentity $record) => $record?->provider?->getLabel() ?? '-'), + Placeholder::make('type') + ->content(fn (?ExternalIdentity $record) => $record?->type?->getLabel() ?? '-'), + Placeholder::make('credentials_type') + ->label('Credentials Type') + ->content(fn (?ExternalIdentity $record) => $record?->credentials_type?->getLabel() ?? '-'), + Placeholder::make('external_account_id') + ->label('External Account ID') + ->content(fn (?ExternalIdentity $record) => $record?->external_account_id ?? '-'), + Placeholder::make('status') + ->label('Connection Status') + ->content(function (?ExternalIdentity $record): string { + if (! $record instanceof ExternalIdentity) { + return '-'; + } + + if ($record->isConnected()) { + return 'Active (since '.$record->connected_at?->format('Y-m-d H:i').')'; + } + + return 'Disconnected (at '.$record->disconnected_at?->format('Y-m-d H:i').')'; + }), + Placeholder::make('connected_by') + ->label('Connected By') + ->content(fn (?ExternalIdentity $record) => $record?->connectedByUser?->username ?? '-'), + Placeholder::make('created_at') + ->label('Created At') + ->content(fn (?ExternalIdentity $record) => $record?->created_at?->format('Y-m-d H:i') ?? '-'), + ]), + Tab::make('Owner') + ->icon(Heroicon::User) + ->schema([ + Placeholder::make('model_type') + ->label('Owner Type') + ->content(fn (?ExternalIdentity $record) => $record instanceof ExternalIdentity ? class_basename($record->model_type) : '-'), + Placeholder::make('owner_name') + ->label('Name / Username') + ->content(fn (?ExternalIdentity $record) => $record?->user?->username ?? $record?->model?->name ?? '-'), + Placeholder::make('owner_email') + ->label('Email') + ->content(fn (?ExternalIdentity $record) => $record?->user?->email ?? '-'), + ]), + ]), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Tables/ExternalIdentitiesTable.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Tables/ExternalIdentitiesTable.php index 38cba06e..40ffccc2 100644 --- a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Tables/ExternalIdentitiesTable.php +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Tables/ExternalIdentitiesTable.php @@ -8,11 +8,17 @@ use Filament\Actions\DeleteBulkAction; use Filament\Actions\ForceDeleteBulkAction; use Filament\Actions\RestoreBulkAction; +use Filament\Actions\ViewAction; +use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\SelectFilter; +use Filament\Tables\Filters\TernaryFilter; use Filament\Tables\Filters\TrashedFilter; use Filament\Tables\Table; use He4rt\Identity\ExternalIdentity\Enums\IdentityProvider; +use He4rt\Identity\ExternalIdentity\Models\ExternalIdentity; +use He4rt\Identity\Tenant\Models\Tenant; +use He4rt\Identity\User\Models\User; class ExternalIdentitiesTable { @@ -21,28 +27,62 @@ public static function configure(Table $table): Table return $table ->columns([ TextColumn::make('provider') - ->badge(), - TextColumn::make('model_type') ->badge() - ->color('gray') - ->formatStateUsing(fn (string $state) => class_basename($state)), + ->sortable(), + TextColumn::make('user.username') + ->label('Owner') + ->sortable() + ->placeholder('-'), + TextColumn::make('metadata.username') + ->label('Platform User') + ->placeholder('-'), TextColumn::make('external_account_id') ->copyable() + ->searchable() ->label('External ID'), - TextColumn::make('credentials_type') - ->badge(), + TextColumn::make('messages_count') + ->label('Messages') + ->numeric() + ->counts('messages') + ->sortable(), + IconColumn::make('status') + ->label('Status') + ->state(fn (ExternalIdentity $record): string => $record->isConnected() ? 'connected' : 'disconnected') + ->icon(fn (string $state): string => match ($state) { + 'connected' => 'heroicon-o-check-circle', + 'disconnected' => 'heroicon-o-x-circle', + }) + ->color(fn (string $state): string => match ($state) { + 'connected' => 'success', + 'disconnected' => 'danger', + }), TextColumn::make('connected_at') ->dateTime() ->sortable(), - TextColumn::make('disconnected_at') - ->dateTime() - ->placeholder('Active'), + TextColumn::make('connectedByUser.username') + ->label('Connected By') + ->placeholder('-'), ]) ->filters([ SelectFilter::make('provider') ->options(IdentityProvider::class), + SelectFilter::make('model_type') + ->label('Owner Type') + ->options([ + User::class => 'User', + Tenant::class => 'Tenant', + ]), + TernaryFilter::make('connected') + ->label('Connection Status') + ->queries( + true: fn ($query) => $query->whereNotNull('connected_at')->whereNull('disconnected_at'), + false: fn ($query) => $query->whereNotNull('disconnected_at'), + ), TrashedFilter::make(), ]) + ->recordActions([ + ViewAction::make(), + ]) ->toolbarActions([ BulkActionGroup::make([ DeleteBulkAction::make(), diff --git a/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php b/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php index 859d7c62..707f1156 100644 --- a/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php +++ b/app-modules/panel-admin/src/Filament/Widgets/ActivityChart.php @@ -4,10 +4,10 @@ namespace He4rt\PanelAdmin\Filament\Widgets; -use Illuminate\Support\Facades\Date; use Filament\Widgets\ChartWidget; use He4rt\Activity\Models\Message; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Date; class ActivityChart extends ChartWidget { diff --git a/app-modules/panel-admin/tests/Feature/Resources/Badges/CreateBadgeTest.php b/app-modules/panel-admin/tests/Feature/Resources/Badges/CreateBadgeTest.php new file mode 100644 index 00000000..e8f51ea4 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Badges/CreateBadgeTest.php @@ -0,0 +1,51 @@ +value)); + $this->actingAsAdmin(); + $this->tenant = Tenant::query()->first(); +}); + +it('can render', function (): void { + livewire(CreateBadge::class)->assertOk(); +}); + +it('can create a badge', function (): void { + livewire(CreateBadge::class) + ->fillForm([ + 'tenant_id' => $this->tenant->getKey(), + 'name' => 'Test Badge', + 'description' => 'A test badge', + 'redeem_code' => 'TEST123', + 'provider' => IdentityProvider::Discord->value, + 'active' => true, + ]) + ->call('create') + ->assertHasNoFormErrors(); + + $this->assertDatabaseHas(Badge::class, [ + 'name' => 'Test Badge', + 'redeem_code' => 'TEST123', + ]); +}); + +it('validates form data', function (string $field, mixed $value, string $rule): void { + livewire(CreateBadge::class) + ->fillForm([$field => $value]) + ->call('create') + ->assertHasFormErrors([$field => $rule]); +})->with([ + 'name is required' => ['name', '', 'required'], + 'redeem_code is required' => ['redeem_code', '', 'required'], +]); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Badges/ListBadgesTest.php b/app-modules/panel-admin/tests/Feature/Resources/Badges/ListBadgesTest.php new file mode 100644 index 00000000..81467e52 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Badges/ListBadgesTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListBadges::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Characters/ListCharactersTest.php b/app-modules/panel-admin/tests/Feature/Resources/Characters/ListCharactersTest.php new file mode 100644 index 00000000..3f737179 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Characters/ListCharactersTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListCharacters::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/EventModels/CreateEventModelTest.php b/app-modules/panel-admin/tests/Feature/Resources/EventModels/CreateEventModelTest.php new file mode 100644 index 00000000..3e47ac7c --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/EventModels/CreateEventModelTest.php @@ -0,0 +1,63 @@ +value)); + $this->actingAsAdmin(); + $this->tenant = Tenant::query()->first(); +}); + +it('can render', function (): void { + livewire(CreateEventModel::class)->assertOk(); +}); + +it('can create an event', function (): void { + livewire(CreateEventModel::class) + ->fillForm([ + 'tenant_id' => $this->tenant->getKey(), + 'title' => 'event title', + 'slug' => 'event-slug', + 'description' => 'event description', + 'location' => 'event location', + 'max_attendees' => 5, + 'event_type' => EventTypeEnum::Workshop->value, + 'active' => true, + 'event_at' => today(), + 'start_at' => today(), + 'end_at' => Date::tomorrow(), + ]) + ->call('create') + ->assertHasNoFormErrors(); + + $this->assertDatabaseHas(EventModel::class, [ + 'title' => 'event title', + 'slug' => 'event-slug', + ]); +}); + +it('validates form data', function (string $field, mixed $value, string $rule): void { + livewire(CreateEventModel::class) + ->fillForm([$field => $value]) + ->call('create') + ->assertHasFormErrors([$field => $rule]); +})->with([ + 'title is required' => ['title', '', 'required'], + 'title min 5' => ['title', 'ab', 'min'], + 'location is required' => ['location', '', 'required'], + 'location min 5' => ['location', 'ab', 'min'], + 'max_attendees is required' => ['max_attendees', null, 'required'], + 'event_at is required' => ['event_at', null, 'required'], + 'start_at is required' => ['start_at', null, 'required'], + 'end_at is required' => ['end_at', null, 'required'], +]); diff --git a/app-modules/panel-admin/tests/Feature/Resources/EventModels/ListEventModelsTest.php b/app-modules/panel-admin/tests/Feature/Resources/EventModels/ListEventModelsTest.php new file mode 100644 index 00000000..907dd073 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/EventModels/ListEventModelsTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListEventModels::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Feedback/ListFeedbackTest.php b/app-modules/panel-admin/tests/Feature/Resources/Feedback/ListFeedbackTest.php new file mode 100644 index 00000000..9594ff20 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Feedback/ListFeedbackTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListFeedback::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/CreateMeetingTypeTest.php b/app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/CreateMeetingTypeTest.php new file mode 100644 index 00000000..e3e9ff19 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/CreateMeetingTypeTest.php @@ -0,0 +1,28 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(CreateMeetingType::class)->assertOk(); +}); + +it('validates form data', function (string $field, mixed $value, string $rule): void { + livewire(CreateMeetingType::class) + ->fillForm([$field => $value]) + ->call('create') + ->assertHasFormErrors([$field => $rule]); +})->with([ + 'name is required' => ['name', '', 'required'], + 'week_day is required' => ['week_day', null, 'required'], +]); diff --git a/app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/ListMeetingTypesTest.php b/app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/ListMeetingTypesTest.php new file mode 100644 index 00000000..b32b94ac --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/MeetingTypes/ListMeetingTypesTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListMeetingTypes::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Meetings/ListMeetingsTest.php b/app-modules/panel-admin/tests/Feature/Resources/Meetings/ListMeetingsTest.php new file mode 100644 index 00000000..0e42cf02 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Meetings/ListMeetingsTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListMeetings::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Messages/ListMessagesTest.php b/app-modules/panel-admin/tests/Feature/Resources/Messages/ListMessagesTest.php new file mode 100644 index 00000000..5dcec28d --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Messages/ListMessagesTest.php @@ -0,0 +1,24 @@ +value)); + $this->actingAsAdmin(); +}); + +it('is registered in admin panel', function (): void { + expect(Filament::getResources()) + ->toContain(MessageResource::class); +}); + +it('can render', function (): void { + livewire(ListMessages::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Seasons/CreateSeasonTest.php b/app-modules/panel-admin/tests/Feature/Resources/Seasons/CreateSeasonTest.php new file mode 100644 index 00000000..6647650b --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Seasons/CreateSeasonTest.php @@ -0,0 +1,48 @@ +value)); + $this->actingAsAdmin(); + $this->tenant = Tenant::query()->first(); +}); + +it('can render', function (): void { + livewire(CreateSeason::class)->assertOk(); +}); + +it('can create a season', function (): void { + livewire(CreateSeason::class) + ->fillForm([ + 'tenant_id' => $this->tenant->getKey(), + 'name' => 'Season 1', + 'description' => 'First season', + 'started_at' => now(), + 'ended_at' => now()->addMonths(3), + ]) + ->call('create') + ->assertHasNoFormErrors(); + + $this->assertDatabaseHas(Season::class, [ + 'name' => 'Season 1', + ]); +}); + +it('validates form data', function (string $field, mixed $value, string $rule): void { + livewire(CreateSeason::class) + ->fillForm([$field => $value]) + ->call('create') + ->assertHasFormErrors([$field => $rule]); +})->with([ + 'name is required' => ['name', '', 'required'], + 'started_at is required' => ['started_at', null, 'required'], +]); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Seasons/ListSeasonsTest.php b/app-modules/panel-admin/tests/Feature/Resources/Seasons/ListSeasonsTest.php new file mode 100644 index 00000000..224545ea --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Seasons/ListSeasonsTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListSeasons::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Sponsors/CreateSponsorTest.php b/app-modules/panel-admin/tests/Feature/Resources/Sponsors/CreateSponsorTest.php new file mode 100644 index 00000000..5e207089 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Sponsors/CreateSponsorTest.php @@ -0,0 +1,36 @@ +value)); + $this->actingAsAdmin(); + $this->tenant = Tenant::query()->first(); +}); + +it('can render', function (): void { + livewire(CreateSponsor::class)->assertOk(); +}); + +it('can create a sponsor', function (): void { + livewire(CreateSponsor::class) + ->fillForm([ + 'tenant_id' => $this->tenant->getKey(), + 'name' => 'Test Sponsor', + 'homepage_url' => 'https://example.com', + ]) + ->call('create') + ->assertHasNoFormErrors(); + + $this->assertDatabaseHas(Sponsor::class, [ + 'name' => 'Test Sponsor', + ]); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Sponsors/ListSponsorsTest.php b/app-modules/panel-admin/tests/Feature/Resources/Sponsors/ListSponsorsTest.php new file mode 100644 index 00000000..429fb6ff --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Sponsors/ListSponsorsTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListSponsors::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Tenants/CreateTenantTest.php b/app-modules/panel-admin/tests/Feature/Resources/Tenants/CreateTenantTest.php new file mode 100644 index 00000000..a6008fde --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Tenants/CreateTenantTest.php @@ -0,0 +1,49 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(CreateTenant::class)->assertOk(); +}); + +it('can create a tenant', function (): void { + $owner = User::factory()->create(); + + livewire(CreateTenant::class) + ->fillForm([ + 'name' => 'Test Tenant', + 'slug' => 'test-tenant', + 'owner_id' => $owner->getKey(), + 'active' => true, + ]) + ->call('create') + ->assertHasNoFormErrors(); + + $this->assertDatabaseHas(Tenant::class, [ + 'name' => 'Test Tenant', + 'slug' => 'test-tenant', + ]); +}); + +it('validates form data', function (string $field, mixed $value, string $rule): void { + livewire(CreateTenant::class) + ->fillForm([$field => $value]) + ->call('create') + ->assertHasFormErrors([$field => $rule]); +})->with([ + 'name is required' => ['name', '', 'required'], + 'slug is required' => ['slug', '', 'required'], +]); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Tenants/EditTenantTest.php b/app-modules/panel-admin/tests/Feature/Resources/Tenants/EditTenantTest.php new file mode 100644 index 00000000..6cd31023 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Tenants/EditTenantTest.php @@ -0,0 +1,22 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + $tenant = Tenant::query()->first(); + + livewire(EditTenant::class, ['record' => $tenant->getRouteKey()]) + ->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Tenants/ListTenantsTest.php b/app-modules/panel-admin/tests/Feature/Resources/Tenants/ListTenantsTest.php new file mode 100644 index 00000000..4fb114f2 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Tenants/ListTenantsTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListTenants::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Tenants/TenantResourceTest.php b/app-modules/panel-admin/tests/Feature/Resources/Tenants/TenantResourceTest.php new file mode 100644 index 00000000..1399a05f --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Tenants/TenantResourceTest.php @@ -0,0 +1,17 @@ +value)); + $this->actingAsAdmin(); +}); + +it('is registered in admin panel', function (): void { + expect(Filament::getResources()) + ->toContain(TenantResource::class); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Users/CreateUserTest.php b/app-modules/panel-admin/tests/Feature/Resources/Users/CreateUserTest.php new file mode 100644 index 00000000..58626c04 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Users/CreateUserTest.php @@ -0,0 +1,48 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(CreateUser::class)->assertOk(); +}); + +it('can create a user', function (): void { + livewire(CreateUser::class) + ->fillForm([ + 'username' => 'newuser', + 'name' => 'New User', + 'email' => 'test@example.com', + 'password' => 'password123', + ]) + ->call('create') + ->assertHasNoFormErrors(); + + $this->assertDatabaseHas(User::class, [ + 'username' => 'newuser', + 'name' => 'New User', + 'email' => 'test@example.com', + ]); +}); + +it('validates form data', function (string $field, mixed $value, string $rule): void { + livewire(CreateUser::class) + ->fillForm([$field => $value]) + ->call('create') + ->assertHasFormErrors([$field => $rule]); +})->with([ + 'username is required' => ['username', '', 'required'], + 'username min 3' => ['username', 'ab', 'min'], + 'name is required' => ['name', '', 'required'], +]); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Users/EditUserTest.php b/app-modules/panel-admin/tests/Feature/Resources/Users/EditUserTest.php new file mode 100644 index 00000000..abc564a6 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Users/EditUserTest.php @@ -0,0 +1,38 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + $user = User::factory()->create(); + + livewire(EditUser::class, ['record' => $user->getRouteKey()]) + ->assertOk(); +}); + +it('can update a user', function (): void { + $user = User::factory()->create(); + + livewire(EditUser::class, ['record' => $user->getRouteKey()]) + ->fillForm([ + 'username' => 'updated-user', + 'name' => 'Updated Name', + ]) + ->call('save') + ->assertHasNoFormErrors(); + + expect($user->fresh()) + ->username->toBe('updated-user') + ->name->toBe('Updated Name'); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Users/ListUsersTest.php b/app-modules/panel-admin/tests/Feature/Resources/Users/ListUsersTest.php new file mode 100644 index 00000000..69e6d6fd --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Users/ListUsersTest.php @@ -0,0 +1,18 @@ +value)); + $this->actingAsAdmin(); +}); + +it('can render', function (): void { + livewire(ListUsers::class)->assertOk(); +}); diff --git a/app-modules/panel-admin/tests/Feature/Resources/Users/UserResourceTest.php b/app-modules/panel-admin/tests/Feature/Resources/Users/UserResourceTest.php new file mode 100644 index 00000000..c6d79ff9 --- /dev/null +++ b/app-modules/panel-admin/tests/Feature/Resources/Users/UserResourceTest.php @@ -0,0 +1,17 @@ +value)); + $this->actingAsAdmin(); +}); + +it('is registered in admin panel', function (): void { + expect(Filament::getResources()) + ->toContain(UserResource::class); +}); From 623e6e2057c54465837ade29a30de38f256579c1 Mon Sep 17 00:00:00 2001 From: danielhe4rt Date: Mon, 23 Mar 2026 00:24:53 -0300 Subject: [PATCH 8/8] wip --- .../ExternalIdentityResource.php | 16 +++++- .../Pages/ListExternalIdentities.php | 11 ++++ .../MessagesRelationManager.php | 34 +++++++++++++ .../Widgets/ExternalIdentityStatsOverview.php | 51 +++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/RelationManagers/MessagesRelationManager.php create mode 100644 app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Widgets/ExternalIdentityStatsOverview.php diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php index ab373079..cd4f79d6 100644 --- a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/ExternalIdentityResource.php @@ -12,8 +12,10 @@ use He4rt\Identity\ExternalIdentity\Models\ExternalIdentity; use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Pages\ListExternalIdentities; use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Pages\ViewExternalIdentity; +use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\RelationManagers\MessagesRelationManager; use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Schemas\ExternalIdentityForm; use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Tables\ExternalIdentitiesTable; +use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Widgets\ExternalIdentityStatsOverview; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; use UnitEnum; @@ -40,12 +42,24 @@ public static function table(Table $table): Table return ExternalIdentitiesTable::configure($table); } + /** + * @return array + */ + public static function getWidgets(): array + { + return [ + ExternalIdentityStatsOverview::class, + ]; + } + /** * @return array */ public static function getRelations(): array { - return []; + return [ + MessagesRelationManager::class, + ]; } /** diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php index 56f2c31f..9bf312b9 100644 --- a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Pages/ListExternalIdentities.php @@ -5,9 +5,20 @@ namespace He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Pages; use Filament\Resources\Pages\ListRecords; +use Filament\Support\Enums\Width; use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\ExternalIdentityResource; +use He4rt\PanelAdmin\Filament\Resources\ExternalIdentities\Widgets\ExternalIdentityStatsOverview; class ListExternalIdentities extends ListRecords { protected static string $resource = ExternalIdentityResource::class; + + protected Width|string|null $maxContentWidth = Width::ScreenTwoExtraLarge; + + protected function getHeaderWidgets(): array + { + return [ + ExternalIdentityStatsOverview::class, + ]; + } } diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/RelationManagers/MessagesRelationManager.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/RelationManagers/MessagesRelationManager.php new file mode 100644 index 00000000..950e4879 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/RelationManagers/MessagesRelationManager.php @@ -0,0 +1,34 @@ +defaultSort('sent_at', 'desc') + ->columns([ + TextColumn::make('content') + ->limit(60) + ->tooltip(fn ($record) => $record->content), + TextColumn::make('channel_id') + ->label('Channel') + ->copyable(), + TextColumn::make('obtained_experience') + ->label('XP') + ->numeric(0), + TextColumn::make('created_at') + ->dateTime() + ->sortable(), + ]); + } +} diff --git a/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Widgets/ExternalIdentityStatsOverview.php b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Widgets/ExternalIdentityStatsOverview.php new file mode 100644 index 00000000..6fc013d3 --- /dev/null +++ b/app-modules/panel-admin/src/Filament/Resources/ExternalIdentities/Widgets/ExternalIdentityStatsOverview.php @@ -0,0 +1,51 @@ +count()) + ->icon(Heroicon::Link), + Stat::make('Active Connections', ExternalIdentity::query() + ->whereNotNull('connected_at') + ->whereNull('disconnected_at') + ->count()) + ->icon(Heroicon::CheckCircle) + ->color('success'), + Stat::make('Disconnected', ExternalIdentity::query() + ->whereNotNull('disconnected_at') + ->count()) + ->icon(Heroicon::XCircle) + ->color('danger'), + Stat::make('Discord', ExternalIdentity::query() + ->where('provider', IdentityProvider::Discord) + ->count()) + ->icon('heroicon-o-chat-bubble-left-right') + ->color('info'), + Stat::make('Twitch', ExternalIdentity::query() + ->where('provider', IdentityProvider::Twitch) + ->count()) + ->icon('heroicon-o-video-camera') + ->color('purple'), + Stat::make('Total Messages', Message::query() + ->whereNotNull('external_identity_id') + ->count()) + ->icon(Heroicon::ChatBubbleLeftEllipsis) + ->color('gray'), + ]; + } +}