From 40aa5fc18885a427e760a1a8fffe9634d867bf65 Mon Sep 17 00:00:00 2001 From: SEB Fotografie - soeren Date: Wed, 10 Sep 2025 19:28:16 +0200 Subject: [PATCH] fixed filament resource forms --- .gitignore | 1 + app/Filament/Resources/EmotionResource.php | 30 +++++++++- app/Filament/Resources/EventResource.php | 48 ++++++++++++++++ app/Filament/Resources/EventTypeResource.php | 21 ++++++- app/Filament/Resources/LegalPageResource.php | 59 +++++++++++++++++++- app/Filament/Resources/PhotoResource.php | 37 +++++++++++- app/Filament/Resources/TaskResource.php | 51 +++++++++++++++-- app/Filament/Resources/TenantResource.php | 36 +++++++++++- app/Models/Photo.php | 28 ++++++++++ app/Models/PhotoLike.php | 18 ++++++ 10 files changed, 317 insertions(+), 12 deletions(-) create mode 100644 app/Models/PhotoLike.php diff --git a/.gitignore b/.gitignore index c625a11..3911ddb 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ yarn-error.log /.nova /.vscode /.zed +tools/git-askpass.ps1 diff --git a/app/Filament/Resources/EmotionResource.php b/app/Filament/Resources/EmotionResource.php index b580791..d1a90b2 100644 --- a/app/Filament/Resources/EmotionResource.php +++ b/app/Filament/Resources/EmotionResource.php @@ -10,7 +10,10 @@ use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; use Filament\Forms\Form; +use Filament\Forms\Components\MarkdownEditor; use Filament\Schemas\Schema; +use Filament\Schemas\Components\Tabs as SchemaTabs; +use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; @@ -27,10 +30,33 @@ class EmotionResource extends Resource public static function form(Schema $form): Schema { return $form->schema([ - KeyValue::make('name')->label('Name (de/en)')->keyLabel('locale')->valueLabel('value')->default(['de' => '', 'en' => ''])->required(), + SchemaTabs::make('content_tabs') + ->label('Content Localization') + ->tabs([ + SchemaTab::make('German') + ->icon('heroicon-o-language') + ->schema([ + TextInput::make('name.de') + ->label('Name (German)') + ->required(), + MarkdownEditor::make('description.de') + ->label('Description (German)') + ->columnSpanFull(), + ]), + SchemaTab::make('English') + ->icon('heroicon-o-language') + ->schema([ + TextInput::make('name.en') + ->label('Name (English)') + ->required(), + MarkdownEditor::make('description.en') + ->label('Description (English)') + ->columnSpanFull(), + ]), + ]) + ->columnSpanFull(), TextInput::make('icon')->label('Icon/Emoji')->maxLength(50), TextInput::make('color')->maxLength(7)->helperText('#RRGGBB'), - KeyValue::make('description')->label('Description (de/en)')->keyLabel('locale')->valueLabel('value'), TextInput::make('sort_order')->numeric()->default(0), Toggle::make('is_active')->default(true), Select::make('eventTypes') diff --git a/app/Filament/Resources/EventResource.php b/app/Filament/Resources/EventResource.php index ce8e4e2..f5bd734 100644 --- a/app/Filament/Resources/EventResource.php +++ b/app/Filament/Resources/EventResource.php @@ -4,10 +4,20 @@ namespace App\Filament\Resources; use App\Filament\Resources\EventResource\Pages; use App\Models\Event; +use App\Models\Tenant; +use App\Models\EventType; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; use Filament\Actions; +use Filament\Forms; +use Filament\Forms\Form; +use Filament\Schemas\Schema; +use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\DatePicker; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Toggle; +use Filament\Forms\Components\KeyValue; use UnitEnum; use BackedEnum; @@ -18,6 +28,44 @@ class EventResource extends Resource protected static UnitEnum|string|null $navigationGroup = 'Platform'; protected static ?int $navigationSort = 20; + public static function form(Schema $form): Schema + { + return $form->schema([ + Select::make('tenant_id') + ->label('Tenant') + ->options(Tenant::all()->pluck('name', 'id')) + ->searchable() + ->required(), + TextInput::make('name') + ->label('Event Name') + ->required() + ->maxLength(255), + TextInput::make('slug') + ->label('Slug') + ->required() + ->unique(ignoreRecord: true) + ->maxLength(255), + DatePicker::make('date') + ->label('Event Date') + ->required(), + Select::make('event_type_id') + ->label('Event Type') + ->options(EventType::all()->pluck('name', 'id')) + ->searchable(), + TextInput::make('default_locale') + ->label('Default Locale') + ->default('de') + ->maxLength(5), + Toggle::make('is_active') + ->label('Is Active') + ->default(true), + KeyValue::make('settings') + ->label('Settings') + ->keyLabel('Key') + ->valueLabel('Value'), + ])->columns(2); + } + public static function table(Table $table): Table { return $table diff --git a/app/Filament/Resources/EventTypeResource.php b/app/Filament/Resources/EventTypeResource.php index e21ec70..80c0f9c 100644 --- a/app/Filament/Resources/EventTypeResource.php +++ b/app/Filament/Resources/EventTypeResource.php @@ -8,6 +8,8 @@ use Filament\Forms\Components\KeyValue; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; +use Filament\Schemas\Components\Tabs as SchemaTabs; +use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use Filament\Resources\Resource; use Filament\Tables; use Filament\Actions; @@ -25,7 +27,24 @@ class EventTypeResource extends Resource public static function form(Schema $form): Schema { return $form->schema([ - KeyValue::make('name')->label('Name (de/en)')->default(['de' => '', 'en' => ''])->required(), + SchemaTabs::make('name_tabs') + ->label('Name Localization') + ->tabs([ + SchemaTab::make('German') + ->icon('heroicon-o-language') + ->schema([ + TextInput::make('name.de') + ->label('Name (German)') + ->required(), + ]), + SchemaTab::make('English') + ->icon('heroicon-o-language') + ->schema([ + TextInput::make('name.en') + ->label('Name (English)') + ->required(), + ]), + ]), TextInput::make('slug')->required()->unique(ignoreRecord: true), TextInput::make('icon')->maxLength(64), KeyValue::make('settings')->label('Settings')->keyLabel('key')->valueLabel('value'), diff --git a/app/Filament/Resources/LegalPageResource.php b/app/Filament/Resources/LegalPageResource.php index 9cef3fb..5ecf105 100644 --- a/app/Filament/Resources/LegalPageResource.php +++ b/app/Filament/Resources/LegalPageResource.php @@ -7,9 +7,17 @@ use App\Models\LegalPage; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Filament\Actions; +use Filament\Schemas\Schema; +use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\Toggle; +use Filament\Forms\Components\KeyValue; +use Filament\Forms\Components\DatePicker; +use Filament\Forms\Components\MarkdownEditor; +use Filament\Schemas\Components\Tabs as SchemaTabs; +use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use UnitEnum; use BackedEnum; -use Filament\Actions; class LegalPageResource extends Resource { @@ -18,6 +26,55 @@ class LegalPageResource extends Resource protected static UnitEnum|string|null $navigationGroup = 'Platform'; protected static ?int $navigationSort = 40; + public static function form(Schema $form): Schema + { + return $form->schema([ + TextInput::make('slug') + ->label('Slug') + ->required() + ->unique(ignoreRecord: true) + ->maxLength(255), + KeyValue::make('title') + ->label('Title (de/en)') + ->keyLabel('locale') + ->valueLabel('value') + ->default(['de' => '', 'en' => '']) + ->required(), + SchemaTabs::make('content_tabs') + ->label('Content Localization') + ->tabs([ + SchemaTab::make('German') + ->icon('heroicon-o-language') + ->schema([ + MarkdownEditor::make('body_markdown.de') + ->label('Content (German)') + ->required() + ->columnSpanFull(), + ]), + SchemaTab::make('English') + ->icon('heroicon-o-language') + ->schema([ + MarkdownEditor::make('body_markdown.en') + ->label('Content (English)') + ->required() + ->columnSpanFull(), + ]), + ]) + ->columnSpanFull(), + Toggle::make('is_published') + ->label('Is Published') + ->default(true), + DatePicker::make('effective_from') + ->label('Effective From') + ->required(), + TextInput::make('version') + ->label('Version') + ->required() + ->default('1.0') + ->maxLength(20), + ])->columns(2); + } + public static function table(Table $table): Table { return $table diff --git a/app/Filament/Resources/PhotoResource.php b/app/Filament/Resources/PhotoResource.php index e67b6cd..466e74d 100644 --- a/app/Filament/Resources/PhotoResource.php +++ b/app/Filament/Resources/PhotoResource.php @@ -4,12 +4,21 @@ namespace App\Filament\Resources; use App\Filament\Resources\PhotoResource\Pages; use App\Models\Photo; +use App\Models\Event; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Filament\Actions; +use Filament\Forms; +use Filament\Forms\Form; +use Filament\Schemas\Schema; +use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Toggle; +use Filament\Forms\Components\FileUpload; +use Filament\Forms\Components\KeyValue; use UnitEnum; use BackedEnum; -use Filament\Actions; class PhotoResource extends Resource { @@ -18,11 +27,35 @@ class PhotoResource extends Resource protected static UnitEnum|string|null $navigationGroup = 'Content'; protected static ?int $navigationSort = 30; + public static function form(Schema $form): Schema + { + return $form->schema([ + Select::make('event_id') + ->label('Event') + ->options(Event::all()->pluck('name', 'id')) + ->searchable() + ->required(), + FileUpload::make('image_path') + ->label('Photo') + ->image() + ->directory('photos') + ->required() + ->visibility('public'), + Toggle::make('is_featured') + ->label('Is Featured') + ->default(false), + KeyValue::make('metadata') + ->label('Metadata') + ->keyLabel('Key') + ->valueLabel('Value'), + ])->columns(2); + } + public static function table(Table $table): Table { return $table ->columns([ - Tables\Columns\ImageColumn::make('thumbnail_path')->label('Thumb')->circular(), + Tables\Columns\ImageColumn::make('image_path')->label('Photo')->disk('public')->visibility('public'), Tables\Columns\TextColumn::make('id')->sortable(), Tables\Columns\TextColumn::make('event_id')->label('Event'), Tables\Columns\TextColumn::make('likes_count')->label('Likes'), diff --git a/app/Filament/Resources/TaskResource.php b/app/Filament/Resources/TaskResource.php index b0fea38..db227f4 100644 --- a/app/Filament/Resources/TaskResource.php +++ b/app/Filament/Resources/TaskResource.php @@ -8,7 +8,10 @@ use Filament\Forms\Components\KeyValue; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; +use Filament\Forms\Components\MarkdownEditor; use Filament\Schemas\Schema; +use Filament\Schemas\Components\Tabs as SchemaTabs; +use Filament\Schemas\Components\Tabs\Tab as SchemaTab; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; @@ -26,16 +29,54 @@ class TaskResource extends Resource public static function form(Schema $form): Schema { return $form->schema([ - Select::make('emotion_id')->relationship('emotion', 'name')->required()->searchable()->preload(), - Select::make('event_type_id')->relationship('eventType', 'name')->searchable()->preload()->label('Event Type (optional)'), - KeyValue::make('title')->label('Title (de/en)')->default(['de' => '', 'en' => ''])->required(), - KeyValue::make('description')->label('Description (de/en)'), + Select::make('emotion_id') + ->relationship('emotion', 'name') + ->getOptionLabelFromRecordUsing(fn ($record) => is_array($record->name) ? ($record->name['de'] ?? $record->name['en'] ?? 'Unnamed') : $record->name) + ->required() + ->searchable() + ->preload(), + Select::make('event_type_id') + ->relationship('eventType', 'name') + ->getOptionLabelFromRecordUsing(fn ($record) => is_array($record->name) ? ($record->name['de'] ?? $record->name['en'] ?? 'Unnamed') : $record->name) + ->searchable() + ->preload() + ->label('Event Type (optional)'), + SchemaTabs::make('content_tabs') + ->label('Content Localization') + ->tabs([ + SchemaTab::make('German') + ->icon('heroicon-o-language') + ->schema([ + TextInput::make('title.de') + ->label('Title (German)') + ->required(), + MarkdownEditor::make('description.de') + ->label('Description (German)') + ->columnSpanFull(), + MarkdownEditor::make('example_text.de') + ->label('Example Text (German)') + ->columnSpanFull(), + ]), + SchemaTab::make('English') + ->icon('heroicon-o-language') + ->schema([ + TextInput::make('title.en') + ->label('Title (English)') + ->required(), + MarkdownEditor::make('description.en') + ->label('Description (English)') + ->columnSpanFull(), + MarkdownEditor::make('example_text.en') + ->label('Example Text (English)') + ->columnSpanFull(), + ]), + ]) + ->columnSpanFull(), Select::make('difficulty')->options([ 'easy' => 'Easy', 'medium' => 'Medium', 'hard' => 'Hard', ])->default('easy'), - KeyValue::make('example_text')->label('Example (de/en)'), TextInput::make('sort_order')->numeric()->default(0), Toggle::make('is_active')->default(true), ])->columns(2); diff --git a/app/Filament/Resources/TenantResource.php b/app/Filament/Resources/TenantResource.php index 3b052b2..005717f 100644 --- a/app/Filament/Resources/TenantResource.php +++ b/app/Filament/Resources/TenantResource.php @@ -7,9 +7,15 @@ use App\Models\Tenant; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Filament\Actions; +use Filament\Forms; +use Filament\Forms\Form; +use Filament\Schemas\Schema; +use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\Toggle; +use Filament\Forms\Components\KeyValue; use UnitEnum; use BackedEnum; -use Filament\Actions; class TenantResource extends Resource { @@ -18,6 +24,34 @@ class TenantResource extends Resource protected static UnitEnum|string|null $navigationGroup = 'Platform'; protected static ?int $navigationSort = 10; + public static function form(Schema $form): Schema + { + return $form->schema([ + TextInput::make('name') + ->label('Tenant Name') + ->required() + ->maxLength(255), + TextInput::make('slug') + ->label('Slug') + ->required() + ->unique(ignoreRecord: true) + ->maxLength(255), + TextInput::make('contact_email') + ->label('Contact Email') + ->email() + ->required() + ->maxLength(255), + TextInput::make('event_credits_balance') + ->label('Event Credits Balance') + ->numeric() + ->default(0), + KeyValue::make('features') + ->label('Features') + ->keyLabel('Key') + ->valueLabel('Value'), + ])->columns(2); + } + public static function table(Table $table): Table { return $table diff --git a/app/Models/Photo.php b/app/Models/Photo.php index cce939a..55a05c4 100644 --- a/app/Models/Photo.php +++ b/app/Models/Photo.php @@ -4,6 +4,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; class Photo extends Model { @@ -14,9 +15,36 @@ class Photo extends Model 'metadata' => 'array', ]; + // Accessor für die Kompatibilität mit der PhotoResource + public function getImagePathAttribute() + { + return $this->file_path; + } + + // Mutator für die Kompatibilität mit der PhotoResource + public function setImagePathAttribute($value) + { + $this->attributes['file_path'] = $value; + } + public function event(): BelongsTo { return $this->belongsTo(Event::class); } + + public function emotion() + { + return $this->belongsTo(Emotion::class); + } + + public function task() + { + return $this->belongsTo(Task::class); + } + + public function likes(): HasMany + { + return $this->hasMany(\App\Models\PhotoLike::class); + } } diff --git a/app/Models/PhotoLike.php b/app/Models/PhotoLike.php new file mode 100644 index 0000000..d4c801e --- /dev/null +++ b/app/Models/PhotoLike.php @@ -0,0 +1,18 @@ +belongsTo(Photo::class); + } +} \ No newline at end of file