Neuordnung des SuperAdminBackends
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2025-12-31 10:06:21 +01:00
parent d7c2f85eeb
commit 8e4d4c2ff6
34 changed files with 526 additions and 131 deletions

View File

@@ -2,33 +2,30 @@
namespace App\Filament\Blog\Resources; namespace App\Filament\Blog\Resources;
use Illuminate\Support\Facades\Log;
use App\Filament\Blog\Resources\CategoryResource\Pages; use App\Filament\Blog\Resources\CategoryResource\Pages;
use App\Filament\Blog\Traits\HasContentEditor; use App\Filament\Blog\Traits\HasContentEditor;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Models\BlogCategory; use App\Models\BlogCategory;
use Filament\Forms;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Infolists\Components\TextEntry;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Actions\BulkActionGroup; use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction; use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction; use Filament\Actions\EditAction;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Infolists\Components\TextEntry;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
class CategoryResource extends Resource class CategoryResource extends Resource
{ {
@@ -36,7 +33,9 @@ class CategoryResource extends Resource
protected static ?string $model = BlogCategory::class; protected static ?string $model = BlogCategory::class;
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-list-bullet'; protected static ?string $cluster = RareAdminCluster::class;
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-list-bullet';
protected static ?string $navigationLabel = 'Kategorien'; protected static ?string $navigationLabel = 'Kategorien';
@@ -46,7 +45,7 @@ class CategoryResource extends Resource
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return 'Content & Bibliothek'; return __('admin.nav.content');
} }
public static function form(Schema $schema): Schema public static function form(Schema $schema): Schema
@@ -159,7 +158,6 @@ class CategoryResource extends Resource
return $transformed; return $transformed;
} }
public static function table(Table $table): Table public static function table(Table $table): Table
{ {
return $table return $table

View File

@@ -4,46 +4,43 @@ namespace App\Filament\Blog\Resources;
use App\Filament\Blog\Resources\PostResource\Pages; use App\Filament\Blog\Resources\PostResource\Pages;
use App\Filament\Blog\Traits\HasContentEditor; use App\Filament\Blog\Traits\HasContentEditor;
use App\Models\BlogPost; use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Models\BlogCategory; use App\Models\BlogCategory;
use Filament\Forms; use App\Models\BlogPost;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Forms\Components\DateTimePicker; use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\MarkdownEditor; use Filament\Forms\Components\MarkdownEditor;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set; use Filament\Schemas\Components\Utilities\Set;
use Filament\Infolists\Components\TextEntry;
use Filament\Resources\Resource;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TernaryFilter; use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Arr;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
class PostResource extends Resource class PostResource extends Resource
{ {
use HasContentEditor; use HasContentEditor;
protected static ?string $model = BlogPost::class; protected static ?string $model = BlogPost::class;
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-document-text'; protected static ?string $cluster = RareAdminCluster::class;
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-document-text';
protected static ?string $navigationLabel = 'Beiträge'; protected static ?string $navigationLabel = 'Beiträge';
@@ -53,7 +50,7 @@ class PostResource extends Resource
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return 'Content & Bibliothek'; return __('admin.nav.content');
} }
public static function form(Schema $schema): Schema public static function form(Schema $schema): Schema

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Clusters\DailyOps;
use BackedEnum;
use Filament\Clusters\Cluster;
use Filament\Pages\Enums\SubNavigationPosition;
use Filament\Support\Icons\Heroicon;
class DailyOpsCluster extends Cluster
{
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedBolt;
protected static ?int $navigationSort = 10;
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
public static function getNavigationLabel(): string
{
return __('admin.nav.daily_ops');
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Clusters\RareAdmin;
use BackedEnum;
use Filament\Clusters\Cluster;
use Filament\Pages\Enums\SubNavigationPosition;
use Filament\Support\Icons\Heroicon;
class RareAdminCluster extends Cluster
{
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedShieldExclamation;
protected static ?int $navigationSort = 30;
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
public static function getNavigationLabel(): string
{
return __('admin.nav.rare_admin');
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Clusters\WeeklyOps;
use BackedEnum;
use Filament\Clusters\Cluster;
use Filament\Pages\Enums\SubNavigationPosition;
use Filament\Support\Icons\Heroicon;
class WeeklyOpsCluster extends Cluster
{
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCalendarDays;
protected static ?int $navigationSort = 20;
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
public static function getNavigationLabel(): string
{
return __('admin.nav.weekly_ops');
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources\Coupons; namespace App\Filament\Resources\Coupons;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\Coupons\Pages\CreateCoupon; use App\Filament\Resources\Coupons\Pages\CreateCoupon;
use App\Filament\Resources\Coupons\Pages\EditCoupon; use App\Filament\Resources\Coupons\Pages\EditCoupon;
use App\Filament\Resources\Coupons\Pages\ListCoupons; use App\Filament\Resources\Coupons\Pages\ListCoupons;
@@ -24,6 +25,8 @@ class CouponResource extends Resource
{ {
protected static ?string $model = Coupon::class; protected static ?string $model = Coupon::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedTicket; protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedTicket;
protected static ?int $navigationSort = 60; protected static ?int $navigationSort = 60;
@@ -32,7 +35,7 @@ class CouponResource extends Resource
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return __('Billing & Finanzen'); return __('admin.nav.commercial');
} }
public static function form(Schema $schema): Schema public static function form(Schema $schema): Schema

View File

@@ -2,34 +2,38 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\EmotionResource\Pages; use App\Filament\Resources\EmotionResource\Pages;
use App\Models\Emotion; use App\Models\Emotion;
use BackedEnum;
use Filament\Actions; use Filament\Actions;
use Filament\Forms\Components\KeyValue; use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Forms\Form; use Filament\Resources\Resource;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Schemas\Schema;
use Filament\Schemas\Components\Tabs as SchemaTabs; use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Resources\Resource; use Filament\Schemas\Schema;
use Filament\Tables; use Filament\Tables;
use Filament\Tables\Table; use Filament\Tables\Table;
use UnitEnum; use UnitEnum;
use BackedEnum;
class EmotionResource extends Resource class EmotionResource extends Resource
{ {
protected static ?string $model = Emotion::class; protected static ?string $model = Emotion::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-face-smile'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-face-smile';
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.tasks_emotions'); return __('admin.nav.curation');
} }
protected static ?int $navigationSort = 10; protected static ?int $navigationSort = 10;
public static function form(Schema $form): Schema public static function form(Schema $form): Schema
@@ -87,8 +91,10 @@ class EmotionResource extends Resource
$value = $record->name; $value = $record->name;
if (is_array($value)) { if (is_array($value)) {
$loc = app()->getLocale(); $loc = app()->getLocale();
return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? '')); return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? ''));
} }
return (string) $value; return (string) $value;
}) })
->searchable(['name->de', 'name->en']) ->searchable(['name->de', 'name->en'])

View File

@@ -2,36 +2,35 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Exports\EventPurchaseExporter;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\EventPurchaseResource\Pages; use App\Filament\Resources\EventPurchaseResource\Pages;
use App\Models\EventPurchase; use App\Models\EventPurchase;
use App\Exports\EventPurchaseExporter;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Schemas\Schema;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Actions\Action; use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup; use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction; use Filament\Actions\DeleteBulkAction;
use Filament\Actions\ExportBulkAction; use Filament\Actions\ExportBulkAction;
use Filament\Actions\ViewAction; use Filament\Actions\ViewAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter; use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\TernaryFilter; use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use BackedEnum;
use UnitEnum;
class EventPurchaseResource extends Resource class EventPurchaseResource extends Resource
{ {
protected static ?string $model = EventPurchase::class; protected static ?string $model = EventPurchase::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
public static function shouldRegisterNavigation(): bool public static function shouldRegisterNavigation(): bool
{ {
return false; return false;
@@ -39,7 +38,7 @@ class EventPurchaseResource extends Resource
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return 'Billing & Finanzen'; return __('admin.nav.commercial');
} }
public static function form(Schema $schema): Schema public static function form(Schema $schema): Schema
@@ -99,7 +98,7 @@ class EventPurchaseResource extends Resource
TextColumn::make('package_id') TextColumn::make('package_id')
->label('Paket') ->label('Paket')
->badge() ->badge()
->color(fn (string $state): string => match($state) { ->color(fn (string $state): string => match ($state) {
'starter_pack' => 'info', 'starter_pack' => 'info',
'pro_pack' => 'success', 'pro_pack' => 'success',
'lifetime_unlimited' => 'danger', 'lifetime_unlimited' => 'danger',
@@ -112,7 +111,7 @@ class EventPurchaseResource extends Resource
->sortable(), ->sortable(),
TextColumn::make('platform') TextColumn::make('platform')
->badge() ->badge()
->color(fn (string $state): string => match($state) { ->color(fn (string $state): string => match ($state) {
'ios' => 'info', 'ios' => 'info',
'android' => 'success', 'android' => 'success',
'web' => 'warning', 'web' => 'warning',
@@ -174,7 +173,7 @@ class EventPurchaseResource extends Resource
->visible(fn (EventPurchase $record): bool => $record->transaction_id && is_null($record->refunded_at)) ->visible(fn (EventPurchase $record): bool => $record->transaction_id && is_null($record->refunded_at))
->action(function (EventPurchase $record) { ->action(function (EventPurchase $record) {
$record->update(['refunded_at' => now()]); $record->update(['refunded_at' => now()]);
Log::info('Refund processed for purchase ID: ' . $record->id); Log::info('Refund processed for purchase ID: '.$record->id);
}), }),
]) ])
->bulkActions([ ->bulkActions([

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Resources\EventResource\Pages; use App\Filament\Resources\EventResource\Pages;
use App\Filament\Resources\EventResource\RelationManagers\EventPackagesRelationManager; use App\Filament\Resources\EventResource\RelationManagers\EventPackagesRelationManager;
use App\Models\Event; use App\Models\Event;
@@ -27,6 +28,8 @@ class EventResource extends Resource
{ {
protected static ?string $model = Event::class; protected static ?string $model = Event::class;
protected static ?string $cluster = DailyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-calendar'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-calendar';
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
@@ -35,7 +38,7 @@ class EventResource extends Resource
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.event_management'); return __('admin.nav.events');
} }
public static function form(Schema $form): Schema public static function form(Schema $form): Schema

View File

@@ -2,31 +2,37 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\EventTypeResource\Pages; use App\Filament\Resources\EventTypeResource\Pages;
use App\Models\EventType; use App\Models\EventType;
use BackedEnum;
use Filament\Actions;
use Filament\Forms\Components\KeyValue; use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema; use Filament\Resources\Resource;
use Filament\Schemas\Components\Tabs as SchemaTabs; use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Resources\Resource; use Filament\Schemas\Schema;
use Filament\Tables; use Filament\Tables;
use Filament\Actions;
use Filament\Tables\Table; use Filament\Tables\Table;
use UnitEnum; use UnitEnum;
use BackedEnum;
class EventTypeResource extends Resource class EventTypeResource extends Resource
{ {
protected static ?string $model = EventType::class; protected static ?string $model = EventType::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-swatch'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-swatch';
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.event_management'); return __('admin.nav.events');
} }
protected static ?int $navigationSort = 20; protected static ?int $navigationSort = 20;
public static function form(Schema $form): Schema public static function form(Schema $form): Schema
@@ -76,8 +82,10 @@ class EventTypeResource extends Resource
$value = $record->name; $value = $record->name;
if (is_array($value)) { if (is_array($value)) {
$loc = app()->getLocale(); $loc = app()->getLocale();
return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? '')); return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? ''));
} }
return (string) $value; return (string) $value;
}) })
->searchable(['name->de', 'name->en']) ->searchable(['name->de', 'name->en'])

View File

@@ -2,34 +2,37 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\GiftVoucherResource\Pages; use App\Filament\Resources\GiftVoucherResource\Pages;
use App\Models\GiftVoucher; use App\Models\GiftVoucher;
use App\Services\GiftVouchers\GiftVoucherService; use App\Services\GiftVouchers\GiftVoucherService;
use BackedEnum; use BackedEnum;
use Carbon\Carbon; use Carbon\Carbon;
use Filament\Forms\Components\Textarea;
use Filament\Actions\Action; use Filament\Actions\Action;
use Filament\Actions\ExportAction;
use Filament\Forms\Components\DateTimePicker; use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Textarea;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Tables\Columns\BadgeColumn; use Filament\Tables\Columns\BadgeColumn;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table; use Filament\Tables\Table;
use Filament\Tables\Actions\ExportAction;
use UnitEnum; use UnitEnum;
class GiftVoucherResource extends Resource class GiftVoucherResource extends Resource
{ {
protected static ?string $model = GiftVoucher::class; protected static ?string $model = GiftVoucher::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-gift'; protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-gift';
protected static ?int $navigationSort = 12; protected static ?int $navigationSort = 12;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.billing'); return __('admin.nav.commercial');
} }
public static function table(Table $table): Table public static function table(Table $table): Table

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources\InfrastructureActionLogs; namespace App\Filament\Resources\InfrastructureActionLogs;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Filament\Resources\InfrastructureActionLogs\Pages\ManageInfrastructureActionLogs; use App\Filament\Resources\InfrastructureActionLogs\Pages\ManageInfrastructureActionLogs;
use App\Models\InfrastructureActionLog; use App\Models\InfrastructureActionLog;
use BackedEnum; use BackedEnum;
@@ -16,12 +17,19 @@ class InfrastructureActionLogResource extends Resource
{ {
protected static ?string $model = InfrastructureActionLog::class; protected static ?string $model = InfrastructureActionLog::class;
protected static ?string $cluster = RareAdminCluster::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack; protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
protected static string|UnitEnum|null $navigationGroup = 'Platform'; protected static string|UnitEnum|null $navigationGroup = null;
protected static ?int $navigationSort = 90; protected static ?int $navigationSort = 90;
public static function getNavigationGroup(): UnitEnum|string|null
{
return __('admin.nav.infrastructure');
}
public static function table(Table $table): Table public static function table(Table $table): Table
{ {
return $table return $table

View File

@@ -2,33 +2,39 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Filament\Resources\LegalPageResource\Pages; use App\Filament\Resources\LegalPageResource\Pages;
use App\Models\LegalPage; use App\Models\LegalPage;
use Filament\Resources\Resource; use BackedEnum;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Actions; use Filament\Actions;
use Filament\Schemas\Schema; use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\KeyValue; use Filament\Resources\Resource;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Schemas\Components\Tabs as SchemaTabs; use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Table;
use UnitEnum; use UnitEnum;
use BackedEnum;
class LegalPageResource extends Resource class LegalPageResource extends Resource
{ {
protected static ?string $model = LegalPage::class; protected static ?string $model = LegalPage::class;
protected static ?string $cluster = RareAdminCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-scale'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-scale';
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.content_library'); return __('admin.nav.content');
} }
protected static ?int $navigationSort = 40; protected static ?int $navigationSort = 40;
public static function form(Schema $form): Schema public static function form(Schema $form): Schema

View File

@@ -2,8 +2,10 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Filament\Resources\MediaStorageTargetResource\Pages; use App\Filament\Resources\MediaStorageTargetResource\Pages;
use App\Models\MediaStorageTarget; use App\Models\MediaStorageTarget;
use BackedEnum;
use Filament\Actions; use Filament\Actions;
use Filament\Forms\Components\KeyValue; use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
@@ -14,19 +16,20 @@ use Filament\Schemas\Schema;
use Filament\Tables; use Filament\Tables;
use Filament\Tables\Table; use Filament\Tables\Table;
use UnitEnum; use UnitEnum;
use BackedEnum;
class MediaStorageTargetResource extends Resource class MediaStorageTargetResource extends Resource
{ {
protected static ?string $model = MediaStorageTarget::class; protected static ?string $model = MediaStorageTarget::class;
protected static ?string $cluster = RareAdminCluster::class;
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-server'; protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-server';
protected static string|UnitEnum|null $navigationGroup = null; protected static string|UnitEnum|null $navigationGroup = null;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.platform_management'); return __('admin.nav.storage');
} }
protected static ?int $navigationSort = 60; protected static ?int $navigationSort = 60;

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\PackageAddonResource\Pages; use App\Filament\Resources\PackageAddonResource\Pages;
use App\Jobs\SyncPackageAddonToPaddle; use App\Jobs\SyncPackageAddonToPaddle;
use App\Models\PackageAddon; use App\Models\PackageAddon;
@@ -21,13 +22,15 @@ class PackageAddonResource extends Resource
{ {
protected static ?string $model = PackageAddon::class; protected static ?string $model = PackageAddon::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static \BackedEnum|string|null $navigationIcon = 'heroicon-o-plus-circle'; protected static \BackedEnum|string|null $navigationIcon = 'heroicon-o-plus-circle';
protected static ?int $navigationSort = 6; protected static ?int $navigationSort = 6;
public static function getNavigationGroup(): \BackedEnum|string|null public static function getNavigationGroup(): \BackedEnum|string|null
{ {
return __('admin.nav.platform_management'); return __('admin.nav.commercial');
} }
public static function form(Schema $schema): Schema public static function form(Schema $schema): Schema

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\PackageResource\Pages; use App\Filament\Resources\PackageResource\Pages;
use App\Jobs\PullPackageFromPaddle; use App\Jobs\PullPackageFromPaddle;
use App\Jobs\SyncPackageToPaddle; use App\Jobs\SyncPackageToPaddle;
@@ -11,9 +12,9 @@ use Filament\Actions;
use Filament\Actions\BulkActionGroup; use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteAction; use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction; use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ForceDeleteAction; use Filament\Actions\ForceDeleteAction;
use Filament\Actions\ForceDeleteBulkAction; use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\RestoreAction; use Filament\Actions\RestoreAction;
use Filament\Actions\RestoreBulkAction; use Filament\Actions\RestoreBulkAction;
use Filament\Actions\ViewAction; use Filament\Actions\ViewAction;
@@ -45,13 +46,15 @@ class PackageResource extends Resource
{ {
protected static ?string $model = Package::class; protected static ?string $model = Package::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-cube'; protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-cube';
protected static string|UnitEnum|null $navigationGroup = null; protected static string|UnitEnum|null $navigationGroup = null;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.platform_management'); return __('admin.nav.commercial');
} }
protected static ?int $navigationSort = 5; protected static ?int $navigationSort = 5;

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Resources\PhotoResource\Pages; use App\Filament\Resources\PhotoResource\Pages;
use App\Models\Event; use App\Models\Event;
use App\Models\Photo; use App\Models\Photo;
@@ -11,7 +12,6 @@ use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\KeyValue; use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Tables; use Filament\Tables;
@@ -22,6 +22,8 @@ class PhotoResource extends Resource
{ {
protected static ?string $model = Photo::class; protected static ?string $model = Photo::class;
protected static ?string $cluster = DailyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-photo'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-photo';
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
@@ -30,7 +32,7 @@ class PhotoResource extends Resource
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.event_management'); return __('admin.nav.events');
} }
public static function form(Schema $form): Schema public static function form(Schema $form): Schema

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources\PhotoboothSettings; namespace App\Filament\Resources\PhotoboothSettings;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Filament\Resources\PhotoboothSettings\Pages\EditPhotoboothSetting; use App\Filament\Resources\PhotoboothSettings\Pages\EditPhotoboothSetting;
use App\Filament\Resources\PhotoboothSettings\Pages\ListPhotoboothSettings; use App\Filament\Resources\PhotoboothSettings\Pages\ListPhotoboothSettings;
use App\Filament\Resources\PhotoboothSettings\Schemas\PhotoboothSettingForm; use App\Filament\Resources\PhotoboothSettings\Schemas\PhotoboothSettingForm;
@@ -20,6 +21,8 @@ class PhotoboothSettingResource extends Resource
{ {
protected static ?string $model = PhotoboothSetting::class; protected static ?string $model = PhotoboothSetting::class;
protected static ?string $cluster = RareAdminCluster::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack; protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
@@ -28,7 +31,7 @@ class PhotoboothSettingResource extends Resource
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.platform_management'); return __('admin.nav.storage');
} }
public static function form(Schema $schema): Schema public static function form(Schema $schema): Schema

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources\PhotoboothSettings\Tables; namespace App\Filament\Resources\PhotoboothSettings\Tables;
use Filament\Actions\EditAction;
use Filament\Tables; use Filament\Tables;
use Filament\Tables\Table; use Filament\Tables\Table;
@@ -28,7 +29,7 @@ class PhotoboothSettingsTable
->label(__('Aktualisiert')), ->label(__('Aktualisiert')),
]) ])
->recordActions([ ->recordActions([
Tables\Actions\EditAction::make(), EditAction::make(),
]) ])
->headerActions([]) ->headerActions([])
->bulkActions([]); ->bulkActions([]);

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Exports\PurchaseHistoryExporter; use App\Exports\PurchaseHistoryExporter;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\PurchaseHistoryResource\Pages; use App\Filament\Resources\PurchaseHistoryResource\Pages;
use App\Models\PurchaseHistory; use App\Models\PurchaseHistory;
use BackedEnum; use BackedEnum;
@@ -21,13 +22,15 @@ class PurchaseHistoryResource extends Resource
{ {
protected static ?string $model = PurchaseHistory::class; protected static ?string $model = PurchaseHistory::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-receipt-refund'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-receipt-refund';
protected static ?int $navigationSort = 20; protected static ?int $navigationSort = 20;
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return __('admin.nav.billing'); return __('admin.nav.commercial');
} }
public static function form(Schema $form): Schema public static function form(Schema $form): Schema

View File

@@ -2,8 +2,12 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Resources\PurchaseResource\Pages; use App\Filament\Resources\PurchaseResource\Pages;
use App\Models\PackagePurchase; use App\Models\PackagePurchase;
use App\Notifications\Customer\RefundReceipt;
use App\Notifications\Ops\RefundProcessed;
use App\Services\Paddle\PaddleTransactionService;
use BackedEnum; use BackedEnum;
use Filament\Actions\Action; use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup; use Filament\Actions\BulkActionGroup;
@@ -26,19 +30,18 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Notification;
use App\Notifications\Ops\RefundProcessed;
use App\Notifications\Customer\RefundReceipt;
use App\Services\Paddle\PaddleTransactionService;
class PurchaseResource extends Resource class PurchaseResource extends Resource
{ {
protected static ?string $model = PackagePurchase::class; protected static ?string $model = PackagePurchase::class;
protected static ?string $cluster = DailyOpsCluster::class;
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-shopping-cart'; protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-shopping-cart';
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return 'Billing & Finanzen'; return __('admin.nav.billing');
} }
protected static ?int $navigationSort = 10; protected static ?int $navigationSort = 10;

View File

@@ -2,33 +2,38 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\TaskResource\Pages; use App\Filament\Resources\TaskResource\Pages;
use App\Models\Task; use App\Models\Task;
use Filament\Forms\Components\KeyValue; use BackedEnum;
use Filament\Actions;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\MarkdownEditor; use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Schemas\Components\Tabs as SchemaTabs; use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Resources\Resource; use Filament\Schemas\Schema;
use Filament\Tables; use Filament\Tables;
use Filament\Tables\Table; use Filament\Tables\Table;
use Filament\Actions;
use UnitEnum; use UnitEnum;
use BackedEnum;
class TaskResource extends Resource class TaskResource extends Resource
{ {
protected static ?string $model = Task::class; protected static ?string $model = Task::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-clipboard-document-check'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-clipboard-document-check';
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
protected static ?int $navigationSort = 30; protected static ?int $navigationSort = 30;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.tasks_emotions'); return __('admin.nav.curation');
} }
public static function getNavigationLabel(): string public static function getNavigationLabel(): string
@@ -106,8 +111,10 @@ class TaskResource extends Resource
$value = $record->title; $value = $record->title;
if (is_array($value)) { if (is_array($value)) {
$loc = app()->getLocale(); $loc = app()->getLocale();
return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? '')); return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? ''));
} }
return (string) $value; return (string) $value;
}) })
->limit(60) ->limit(60)
@@ -119,8 +126,10 @@ class TaskResource extends Resource
$value = optional($record->emotion)->name; $value = optional($record->emotion)->name;
if (is_array($value)) { if (is_array($value)) {
$loc = app()->getLocale(); $loc = app()->getLocale();
return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? '')); return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? ''));
} }
return (string) ($value ?? ''); return (string) ($value ?? '');
}) })
->sortable() ->sortable()
@@ -132,8 +141,10 @@ class TaskResource extends Resource
$value = optional($record->eventType)->name; $value = optional($record->eventType)->name;
if (is_array($value)) { if (is_array($value)) {
$loc = app()->getLocale(); $loc = app()->getLocale();
return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? '')); return $value[$loc] ?? ($value['de'] ?? ($value['en'] ?? ''));
} }
return (string) ($value ?? ''); return (string) ($value ?? '');
}) })
->toggleable(), ->toggleable(),

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Resources\TenantFeedbackResource\Pages\ListTenantFeedback; use App\Filament\Resources\TenantFeedbackResource\Pages\ListTenantFeedback;
use App\Filament\Resources\TenantFeedbackResource\Pages\ViewTenantFeedback; use App\Filament\Resources\TenantFeedbackResource\Pages\ViewTenantFeedback;
use App\Filament\Resources\TenantFeedbackResource\Schemas\TenantFeedbackForm; use App\Filament\Resources\TenantFeedbackResource\Schemas\TenantFeedbackForm;
@@ -19,6 +20,8 @@ class TenantFeedbackResource extends Resource
{ {
protected static ?string $model = TenantFeedback::class; protected static ?string $model = TenantFeedback::class;
protected static ?string $cluster = DailyOpsCluster::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedChatBubbleBottomCenterText; protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedChatBubbleBottomCenterText;
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
@@ -47,7 +50,7 @@ class TenantFeedbackResource extends Resource
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('Feedback & Support'); return __('admin.nav.feedback_support');
} }
public static function getRelations(): array public static function getRelations(): array

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Resources\TenantFeedbackResource\Tables; namespace App\Filament\Resources\TenantFeedbackResource\Tables;
use App\Models\TenantFeedback; use App\Models\TenantFeedback;
use Filament\Actions\ViewAction;
use Filament\Tables; use Filament\Tables;
use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table; use Filament\Tables\Table;
@@ -69,7 +70,7 @@ class TenantFeedbackTable
->toArray()), ->toArray()),
]) ])
->recordActions([ ->recordActions([
Tables\Actions\ViewAction::make(), ViewAction::make(),
]) ])
->bulkActions([]); ->bulkActions([]);
} }

View File

@@ -2,12 +2,12 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\TenantPackageResource\Pages; use App\Filament\Resources\TenantPackageResource\Pages;
use App\Models\TenantPackage; use App\Models\TenantPackage;
use BackedEnum; use BackedEnum;
use Filament\Actions\ActionGroup; use Filament\Actions\ActionGroup;
use Filament\Actions\BulkActionGroup; use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction; use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction; use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction; use Filament\Actions\EditAction;
@@ -15,26 +15,25 @@ use Filament\Actions\ViewAction;
use Filament\Forms\Components\DateTimePicker; use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table; use Filament\Tables\Table;
use UnitEnum;
class TenantPackageResource extends Resource class TenantPackageResource extends Resource
{ {
protected static ?string $model = TenantPackage::class; protected static ?string $model = TenantPackage::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-shopping-bag'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-shopping-bag';
protected static ?string $slug = 'tenant-packages'; protected static ?string $slug = 'tenant-packages';
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return 'Billing & Finanzen'; return __('admin.nav.commercial');
} }
public static function form(Schema $form): Schema public static function form(Schema $form): Schema

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Resources\TenantResource\Pages; use App\Filament\Resources\TenantResource\Pages;
use App\Filament\Resources\TenantResource\RelationManagers\PackagePurchasesRelationManager; use App\Filament\Resources\TenantResource\RelationManagers\PackagePurchasesRelationManager;
use App\Filament\Resources\TenantResource\RelationManagers\TenantPackagesRelationManager; use App\Filament\Resources\TenantResource\RelationManagers\TenantPackagesRelationManager;
@@ -13,7 +14,6 @@ use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Tables; use Filament\Tables;
@@ -25,13 +25,15 @@ class TenantResource extends Resource
{ {
protected static ?string $model = Tenant::class; protected static ?string $model = Tenant::class;
protected static ?string $cluster = DailyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-building-office'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-building-office';
protected static UnitEnum|string|null $navigationGroup = null; protected static UnitEnum|string|null $navigationGroup = null;
public static function getNavigationGroup(): UnitEnum|string|null public static function getNavigationGroup(): UnitEnum|string|null
{ {
return __('admin.nav.platform_management'); return __('admin.nav.tenants');
} }
protected static ?int $navigationSort = 10; protected static ?int $navigationSort = 10;

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Filament\Resources\UserResource\Pages; use App\Filament\Resources\UserResource\Pages;
use App\Models\User; use App\Models\User;
use BackedEnum; use BackedEnum;
@@ -10,29 +11,28 @@ use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction; use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction; use Filament\Actions\EditAction;
use Filament\Actions\ViewAction; use Filament\Actions\ViewAction;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table; use Filament\Tables\Table;
use UnitEnum;
class UserResource extends Resource class UserResource extends Resource
{ {
protected static ?string $model = User::class; protected static ?string $model = User::class;
protected static ?string $cluster = WeeklyOpsCluster::class;
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-user-circle'; protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-user-circle';
protected static ?string $slug = 'users'; protected static ?string $slug = 'users';
public static function getNavigationGroup(): string public static function getNavigationGroup(): string
{ {
return 'Plattform-Verwaltung'; return __('admin.nav.platform');
} }
public static function form(Schema $form): Schema public static function form(Schema $form): Schema

View File

@@ -2,6 +2,7 @@
namespace App\Filament\SuperAdmin\Pages; namespace App\Filament\SuperAdmin\Pages;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Models\InfrastructureActionLog; use App\Models\InfrastructureActionLog;
use App\Services\Dokploy\DokployClient; use App\Services\Dokploy\DokployClient;
use BackedEnum; use BackedEnum;
@@ -17,6 +18,10 @@ class DokployDeployments extends Page
protected static ?string $title = 'Infrastructure Controls'; protected static ?string $title = 'Infrastructure Controls';
protected static null|string|\UnitEnum $navigationGroup = null;
protected static ?string $cluster = RareAdminCluster::class;
protected string $view = 'filament.super-admin.pages.dokploy-deployments'; protected string $view = 'filament.super-admin.pages.dokploy-deployments';
public array $composes = []; public array $composes = [];
@@ -25,6 +30,11 @@ class DokployDeployments extends Page
public ?string $dokployWebUrl = null; public ?string $dokployWebUrl = null;
public static function getNavigationGroup(): \UnitEnum|string|null
{
return __('admin.nav.infrastructure');
}
public function mount(DokployClient $client): void public function mount(DokployClient $client): void
{ {
$this->dokployWebUrl = config('dokploy.web_url'); $this->dokployWebUrl = config('dokploy.web_url');

View File

@@ -2,6 +2,7 @@
namespace App\Filament\SuperAdmin\Pages; namespace App\Filament\SuperAdmin\Pages;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Models\WatermarkSetting; use App\Models\WatermarkSetting;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Form; use Filament\Forms\Form;
@@ -12,12 +13,19 @@ class WatermarkSettingsPage extends Page
{ {
protected static null|string|\BackedEnum $navigationIcon = 'heroicon-o-sparkles'; protected static null|string|\BackedEnum $navigationIcon = 'heroicon-o-sparkles';
protected static ?string $cluster = RareAdminCluster::class;
protected string $view = 'filament.super-admin.pages.watermark-settings-page'; protected string $view = 'filament.super-admin.pages.watermark-settings-page';
protected static null|string|\UnitEnum $navigationGroup = 'Branding'; protected static null|string|\UnitEnum $navigationGroup = null;
protected static ?int $navigationSort = 20; protected static ?int $navigationSort = 20;
public static function getNavigationGroup(): \UnitEnum|string|null
{
return __('admin.nav.branding');
}
public ?string $asset = null; public ?string $asset = null;
public string $position = 'bottom-right'; public string $position = 'bottom-right';

View File

@@ -2,10 +2,6 @@
namespace App\Providers\Filament; namespace App\Providers\Filament;
use App\Filament\Blog\Resources\CategoryResource;
use App\Filament\Blog\Resources\PostResource;
use App\Filament\Resources\InfrastructureActionLogs\InfrastructureActionLogResource;
use App\Filament\Resources\LegalPageResource;
use App\Filament\Widgets\DokployPlatformHealth; use App\Filament\Widgets\DokployPlatformHealth;
use App\Filament\Widgets\PlatformStatsWidget; use App\Filament\Widgets\PlatformStatsWidget;
use App\Filament\Widgets\RevenueTrendWidget; use App\Filament\Widgets\RevenueTrendWidget;
@@ -15,6 +11,7 @@ use Boquizo\FilamentLogViewer\FilamentLogViewerPlugin;
use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents; use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent; use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Navigation\NavigationGroup;
use Filament\Pages; use Filament\Pages;
use Filament\Panel; use Filament\Panel;
use Filament\PanelProvider; use Filament\PanelProvider;
@@ -38,18 +35,45 @@ class SuperAdminPanelProvider extends PanelProvider
->default() ->default()
->id('superadmin') ->id('superadmin')
->path('super-admin') ->path('super-admin')
->topNavigation()
->colors([ ->colors([
'primary' => Color::Pink, 'primary' => Color::Pink,
]) ])
->plugins([ ->plugins([
FilamentLogViewerPlugin::make() FilamentLogViewerPlugin::make()
->navigationGroup('Platform') ->navigationGroup(__('admin.nav.infrastructure'))
->navigationLabel('Log Viewer') ->navigationLabel('Log Viewer')
->navigationIcon(Heroicon::OutlinedDocumentText) ->navigationIcon(Heroicon::OutlinedDocumentText)
->navigationSort(20), ->navigationSort(20),
]) ])
->navigationGroups([
NavigationGroup::make()
->label(__('admin.nav.curation')),
NavigationGroup::make()
->label(__('admin.nav.events')),
NavigationGroup::make()
->label(__('admin.nav.tenants')),
NavigationGroup::make()
->label(__('admin.nav.billing')),
NavigationGroup::make()
->label(__('admin.nav.feedback_support')),
NavigationGroup::make()
->label(__('admin.nav.platform')),
NavigationGroup::make()
->label(__('admin.nav.commercial')),
NavigationGroup::make()
->label(__('admin.nav.infrastructure')),
NavigationGroup::make()
->label(__('admin.nav.storage')),
NavigationGroup::make()
->label(__('admin.nav.content')),
NavigationGroup::make()
->label(__('admin.nav.branding')),
])
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources') ->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverResources(in: app_path('Filament/Blog/Resources'), for: 'App\\Filament\\Blog\\Resources')
->discoverPages(in: app_path('Filament/SuperAdmin/Pages'), for: 'App\\Filament\\SuperAdmin\\Pages') ->discoverPages(in: app_path('Filament/SuperAdmin/Pages'), for: 'App\\Filament\\SuperAdmin\\Pages')
->discoverClusters(in: app_path('Filament/Clusters'), for: 'App\\Filament\\Clusters')
->pages([ ->pages([
Pages\Dashboard::class, Pages\Dashboard::class,
]) ])
@@ -84,18 +108,6 @@ class SuperAdminPanelProvider extends PanelProvider
->authMiddleware([ ->authMiddleware([
Authenticate::class, Authenticate::class,
]) ])
->resources([
\App\Filament\Resources\EventResource::class,
\App\Filament\Resources\PhotoResource::class,
\App\Filament\Resources\UserResource::class,
\App\Filament\Resources\TenantPackageResource::class,
\App\Filament\Resources\TaskResource::class,
\App\Filament\Resources\MediaStorageTargetResource::class,
PostResource::class,
CategoryResource::class,
LegalPageResource::class,
InfrastructureActionLogResource::class,
])
->pages([ ->pages([
Pages\Dashboard::class, Pages\Dashboard::class,
\App\Filament\SuperAdmin\Pages\WatermarkSettingsPage::class, \App\Filament\SuperAdmin\Pages\WatermarkSettingsPage::class,

View File

@@ -5,8 +5,22 @@ return [
'platform' => 'Plattform', 'platform' => 'Plattform',
'library' => 'Bibliothek', 'library' => 'Bibliothek',
'content' => 'Inhalte', 'content' => 'Inhalte',
'daily_ops' => 'Täglicher Betrieb',
'weekly_ops' => 'Wöchentliche Aufgaben',
'rare_admin' => 'Selten / Admin',
'platform_management' => 'Plattformverwaltung', 'platform_management' => 'Plattformverwaltung',
'events' => 'Events',
'tenants' => 'Mandanten',
'curation' => 'Kuration',
'event_management' => 'Event-Management',
'tasks_emotions' => 'Aufgaben & Emotionen',
'content_library' => 'Content & Bibliothek',
'billing' => 'Billing & Finanzen', 'billing' => 'Billing & Finanzen',
'commercial' => 'Kommerziell',
'infrastructure' => 'Infrastruktur',
'storage' => 'Speicher',
'feedback_support' => 'Feedback & Support',
'branding' => 'Branding',
'security' => 'Sicherheit', 'security' => 'Sicherheit',
], ],

View File

@@ -5,8 +5,22 @@ return [
'platform' => 'Platform', 'platform' => 'Platform',
'library' => 'Library', 'library' => 'Library',
'content' => 'Content', 'content' => 'Content',
'daily_ops' => 'Daily Ops',
'weekly_ops' => 'Weekly Ops',
'rare_admin' => 'Rare / Admin',
'platform_management' => 'Platform Management', 'platform_management' => 'Platform Management',
'events' => 'Events',
'tenants' => 'Tenants',
'curation' => 'Curation',
'event_management' => 'Event Management',
'tasks_emotions' => 'Tasks & Emotions',
'content_library' => 'Content & Library',
'billing' => 'Billing & Finance', 'billing' => 'Billing & Finance',
'commercial' => 'Commercial',
'infrastructure' => 'Infrastructure',
'storage' => 'Storage',
'feedback_support' => 'Feedback & Support',
'branding' => 'Branding',
'security' => 'Security', 'security' => 'Security',
], ],

View File

@@ -0,0 +1,110 @@
<?php
namespace Tests\Feature;
use Filament\Clusters\Cluster;
use Filament\Facades\Filament;
use Filament\Pages\Page as FilamentPage;
use Filament\Resources\Pages\PageRegistration;
use Filament\Resources\Resource;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;
class FilamentPanelNavigationTest extends TestCase
{
use RefreshDatabase;
public function test_all_panel_resources_and_pages_build_navigation_items(): void
{
$panels = Filament::getPanels();
$this->assertNotEmpty($panels);
foreach ($panels as $panel) {
Filament::setCurrentPanel($panel);
Filament::bootCurrentPanel();
if ($panel->hasTenancy()) {
$tenantModel = $panel->getTenantModel();
$this->assertNotNull($tenantModel, $panel->getId());
$userModel = \App\Models\User::class;
$user = $userModel::factory()->create();
Filament::auth()->login($user);
$tenant = $tenantModel::factory()->create();
Filament::setTenant($tenant);
}
foreach ($panel->getResources() as $resource) {
$this->assertTrue(is_subclass_of($resource, Resource::class), $resource);
$this->assertIsArray($resource::getPages(), $resource);
$this->assertIsArray($resource::getNavigationItems(), $resource);
}
foreach ($panel->getPages() as $page) {
if (! is_subclass_of($page, FilamentPage::class)) {
continue;
}
if (! $page::shouldRegisterNavigation()) {
continue;
}
if (str_contains($page::getRoutePath($panel), '{')) {
continue;
}
$this->assertIsArray($page::getNavigationItems(), $page);
}
foreach ($panel->getClusters() as $cluster) {
$this->assertTrue(is_subclass_of($cluster, Cluster::class), $cluster);
$this->assertIsArray($cluster::getNavigationItems(), $cluster);
}
Filament::setTenant(null, true);
}
}
public function test_all_resource_index_pages_render_without_errors(): void
{
$panels = Filament::getPanels();
$this->assertNotEmpty($panels);
foreach ($panels as $panel) {
Filament::setCurrentPanel($panel);
Filament::bootCurrentPanel();
$userModel = \App\Models\User::class;
$user = $userModel::factory()->create();
Filament::auth()->login($user);
if ($panel->hasTenancy()) {
$tenantModel = $panel->getTenantModel();
$this->assertNotNull($tenantModel, $panel->getId());
$tenant = $tenantModel::factory()->create();
Filament::setTenant($tenant);
}
foreach ($panel->getResources() as $resource) {
$resource::skipAuthorization();
$pages = $resource::getPages();
$this->assertNotEmpty($pages, $resource);
$registration = $pages['index'] ?? reset($pages);
$pageClass = $registration instanceof PageRegistration ? $registration->getPage() : $registration;
Livewire::test($pageClass)
->assertStatus(200);
}
Filament::auth()->logout();
Filament::setTenant(null, true);
}
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Tests\Unit;
use App\Filament\Clusters\DailyOps\DailyOpsCluster;
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
use App\Providers\Filament\SuperAdminPanelProvider;
use Filament\Pages\Enums\SubNavigationPosition;
use Filament\Panel;
use Tests\TestCase;
class SuperAdminNavigationGroupsTest extends TestCase
{
public function test_super_admin_navigation_groups_use_translated_labels(): void
{
app()->setLocale('en');
$expectations = [
\App\Filament\Resources\EventResource::class => 'admin.nav.events',
\App\Filament\Resources\EventTypeResource::class => 'admin.nav.events',
\App\Filament\Resources\PhotoResource::class => 'admin.nav.events',
\App\Filament\Resources\TaskResource::class => 'admin.nav.curation',
\App\Filament\Resources\EmotionResource::class => 'admin.nav.curation',
\App\Filament\Resources\LegalPageResource::class => 'admin.nav.content',
\App\Filament\Blog\Resources\PostResource::class => 'admin.nav.content',
\App\Filament\Blog\Resources\CategoryResource::class => 'admin.nav.content',
\App\Filament\Resources\UserResource::class => 'admin.nav.platform',
\App\Filament\Resources\TenantResource::class => 'admin.nav.tenants',
\App\Filament\Resources\MediaStorageTargetResource::class => 'admin.nav.storage',
\App\Filament\Resources\PackageAddonResource::class => 'admin.nav.commercial',
\App\Filament\Resources\PackageResource::class => 'admin.nav.commercial',
\App\Filament\Resources\PhotoboothSettings\PhotoboothSettingResource::class => 'admin.nav.storage',
\App\Filament\Resources\PurchaseResource::class => 'admin.nav.billing',
\App\Filament\Resources\PurchaseHistoryResource::class => 'admin.nav.commercial',
\App\Filament\Resources\EventPurchaseResource::class => 'admin.nav.commercial',
\App\Filament\Resources\TenantPackageResource::class => 'admin.nav.commercial',
\App\Filament\Resources\Coupons\CouponResource::class => 'admin.nav.commercial',
\App\Filament\Resources\GiftVoucherResource::class => 'admin.nav.commercial',
\App\Filament\Resources\TenantFeedbackResource::class => 'admin.nav.feedback_support',
\App\Filament\Resources\InfrastructureActionLogs\InfrastructureActionLogResource::class => 'admin.nav.infrastructure',
\App\Filament\SuperAdmin\Pages\WatermarkSettingsPage::class => 'admin.nav.branding',
\App\Filament\SuperAdmin\Pages\DokployDeployments::class => 'admin.nav.infrastructure',
];
foreach ($expectations as $resourceClass => $key) {
$this->assertSame(__($key), $resourceClass::getNavigationGroup(), $resourceClass);
}
$clusterExpectations = [
\App\Filament\Resources\EventResource::class => DailyOpsCluster::class,
\App\Filament\Resources\PhotoResource::class => DailyOpsCluster::class,
\App\Filament\Resources\TenantResource::class => DailyOpsCluster::class,
\App\Filament\Resources\PurchaseResource::class => DailyOpsCluster::class,
\App\Filament\Resources\TenantFeedbackResource::class => DailyOpsCluster::class,
\App\Filament\Resources\TaskResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\EmotionResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\EventTypeResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\UserResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\PackageResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\PackageAddonResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\TenantPackageResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\Coupons\CouponResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\GiftVoucherResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\PurchaseHistoryResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\EventPurchaseResource::class => WeeklyOpsCluster::class,
\App\Filament\Resources\InfrastructureActionLogs\InfrastructureActionLogResource::class => RareAdminCluster::class,
\App\Filament\Resources\MediaStorageTargetResource::class => RareAdminCluster::class,
\App\Filament\Resources\PhotoboothSettings\PhotoboothSettingResource::class => RareAdminCluster::class,
\App\Filament\Resources\LegalPageResource::class => RareAdminCluster::class,
\App\Filament\Blog\Resources\PostResource::class => RareAdminCluster::class,
\App\Filament\Blog\Resources\CategoryResource::class => RareAdminCluster::class,
\App\Filament\SuperAdmin\Pages\WatermarkSettingsPage::class => RareAdminCluster::class,
\App\Filament\SuperAdmin\Pages\DokployDeployments::class => RareAdminCluster::class,
];
foreach ($clusterExpectations as $resourceClass => $clusterClass) {
$this->assertSame($clusterClass, $resourceClass::getCluster(), $resourceClass);
}
$this->assertSame(SubNavigationPosition::Top, DailyOpsCluster::getSubNavigationPosition());
$this->assertSame(SubNavigationPosition::Top, WeeklyOpsCluster::getSubNavigationPosition());
$this->assertSame(SubNavigationPosition::Top, RareAdminCluster::getSubNavigationPosition());
}
public function test_super_admin_panel_uses_top_navigation(): void
{
$provider = new SuperAdminPanelProvider(app());
$panel = $provider->panel(Panel::make());
$this->assertTrue($panel->hasTopNavigation());
}
}