diff --git a/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php b/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php index 6269957..52a09e1 100644 --- a/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php +++ b/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php @@ -6,6 +6,10 @@ use Filament\Forms\Components\Select; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; +use Filament\Forms\Components\FileUpload; +use Filament\Forms\Components\DateTimePicker; +use Filament\Forms\Components\DatePicker; +use Filament\Forms\Components\Repeater; use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Set; @@ -54,6 +58,9 @@ class SettingForm 'float' => __('settings.type_float'), 'array' => __('settings.type_array'), 'json' => __('settings.type_json'), + 'file' => __('settings.type_file'), + 'date' => __('settings.type_date'), + 'datetime' => __('settings.type_datetime'), ]) ->live() ->afterStateUpdated(fn (Set $set) => $set('value', null)), @@ -78,10 +85,10 @@ class SettingForm ->label(__('settings.value')) ->helperText(__('settings.value_helper')) ->required() - ->visible(fn (Get $get) => !in_array($get('type'), ['boolean'])) + ->visible(fn (Get $get) => !in_array($get('type'), ['boolean', 'file', 'date', 'datetime', 'array'])) ->rows(fn (Get $get) => $get('type') === 'text' ? 5 : 3) ->formatStateUsing(function ($state, $record) { - if ($record && $record->type !== 'boolean') { + if ($record && !in_array($record->type, ['boolean', 'file', 'date', 'datetime', 'array'])) { return $record->value; } return $state; @@ -101,6 +108,91 @@ class SettingForm }) ->columnSpanFull(), + FileUpload::make('value_file') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'file') + ->disk('public') + ->directory('settings') + ->acceptedFileTypes(['image/*', 'application/pdf', 'text/*']) + ->maxSize(10240) // 10MB + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'file') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + DatePicker::make('value_date') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'date') + ->displayFormat('d/m/Y') + ->format('Y-m-d') + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'date') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + DateTimePicker::make('value_datetime') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'datetime') + ->displayFormat('d/m/Y H:i') + ->format('Y-m-d H:i:s') + ->seconds(false) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'datetime') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + Repeater::make('value_array') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'array') + ->schema([ + TextInput::make('key') + ->label(__('settings.array_key')) + ->required() + ->placeholder(__('settings.array_key_placeholder')), + TextInput::make('value') + ->label(__('settings.array_value')) + ->required() + ->placeholder(__('settings.array_value_placeholder')), + Textarea::make('description') + ->label(__('settings.array_description')) + ->placeholder(__('settings.array_description_placeholder')) + ->rows(2), + Toggle::make('active') + ->label(__('settings.array_active')) + ->default(true), + ]) + ->columns(2) + ->defaultItems(1) + ->addActionLabel(__('settings.array_add_item')) + ->reorderable() + ->collapsible() + ->itemLabel(fn (array $state): ?string => $state['key'] ?? null) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'array') { + $decoded = json_decode($record->value, true); + return is_array($decoded) ? $decoded : []; + } + return is_array($state) ? $state : []; + }) + ->columnSpanFull(), + Toggle::make('is_active') ->label(__('settings.is_active')) ->helperText(__('settings.is_active_helper')) diff --git a/app/Models/Setting.php b/app/Models/Setting.php index 569bb53..eec21c2 100644 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -15,6 +15,10 @@ class Setting extends Model 'value', 'value_text', 'value_boolean', + 'value_file', + 'value_date', + 'value_datetime', + 'value_array', 'type', 'group', 'label', @@ -50,6 +54,38 @@ class Setting extends Model $this->attributes['value'] = $value ? '1' : '0'; } + /** + * Set value from different field names + */ + public function setValueFileAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from different field names + */ + public function setValueDateAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from different field names + */ + public function setValueDatetimeAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from different field names + */ + public function setValueArrayAttribute($value) + { + $this->attributes['value'] = is_array($value) ? json_encode($value) : $value; + } + /** * Get setting by key */ @@ -91,6 +127,9 @@ class Setting extends Model 'integer' => (int) $value, 'float' => (float) $value, 'array', 'json' => json_decode($value, true), + 'file' => $value, // File path as string + 'date' => $value, // Date as string (Y-m-d format) + 'datetime' => $value, // DateTime as string (Y-m-d H:i:s format) default => $value, }; } diff --git a/database/migrations/2025_10_23_181906_add_file_type_to_settings_table.php b/database/migrations/2025_10_23_181906_add_file_type_to_settings_table.php new file mode 100644 index 0000000..babec9b --- /dev/null +++ b/database/migrations/2025_10_23_181906_add_file_type_to_settings_table.php @@ -0,0 +1,28 @@ +enum('type', ['string', 'text', 'boolean', 'integer', 'float', 'array', 'json', 'file'])->default('string')->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('settings', function (Blueprint $table) { + $table->enum('type', ['string', 'text', 'boolean', 'integer', 'float', 'array', 'json'])->default('string')->change(); + }); + } +}; diff --git a/database/migrations/2025_10_23_182459_add_date_datetime_types_to_settings_table.php b/database/migrations/2025_10_23_182459_add_date_datetime_types_to_settings_table.php new file mode 100644 index 0000000..fe31a22 --- /dev/null +++ b/database/migrations/2025_10_23_182459_add_date_datetime_types_to_settings_table.php @@ -0,0 +1,28 @@ +enum('type', ['string', 'text', 'boolean', 'integer', 'float', 'array', 'json', 'file', 'date', 'datetime'])->default('string')->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('settings', function (Blueprint $table) { + $table->enum('type', ['string', 'text', 'boolean', 'integer', 'float', 'array', 'json', 'file'])->default('string')->change(); + }); + } +}; diff --git a/lang/en/settings.php b/lang/en/settings.php index d64d7cd..b983bae 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -59,6 +59,9 @@ return [ 'type_float' => 'Float', 'type_array' => 'Array', 'type_json' => 'JSON', + 'type_file' => 'File', + 'type_date' => 'Date', + 'type_datetime' => 'Date & Time', // Groups 'group_general' => 'General', @@ -78,6 +81,16 @@ return [ 'type_required' => 'Type field is required.', 'label_required' => 'Label field is required.', + // Array type specific + 'array_key' => 'Key', + 'array_key_placeholder' => 'Array key (e.g: name, email)', + 'array_value' => 'Value', + 'array_value_placeholder' => 'Array value', + 'array_description' => 'Description', + 'array_description_placeholder' => 'Description for this item', + 'array_active' => 'Active', + 'array_add_item' => 'Add Item', + // Filters 'filter_group' => 'By Group', 'filter_type' => 'By Type', diff --git a/lang/tr/settings.php b/lang/tr/settings.php index 4861cfa..6c472ff 100644 --- a/lang/tr/settings.php +++ b/lang/tr/settings.php @@ -59,6 +59,9 @@ return [ 'type_float' => 'Ondalıklı Sayı', 'type_array' => 'Dizi', 'type_json' => 'JSON', + 'type_file' => 'Dosya', + 'type_date' => 'Tarih', + 'type_datetime' => 'Tarih ve Saat', // Groups 'group_general' => 'Genel', @@ -78,6 +81,16 @@ return [ 'type_required' => 'Tip alanı zorunludur.', 'label_required' => 'Etiket alanı zorunludur.', + // Array type specific + 'array_key' => 'Anahtar', + 'array_key_placeholder' => 'Dizi anahtarı (örn: name, email)', + 'array_value' => 'Değer', + 'array_value_placeholder' => 'Dizi değeri', + 'array_description' => 'Açıklama', + 'array_description_placeholder' => 'Bu öğe için açıklama', + 'array_active' => 'Aktif', + 'array_add_item' => 'Öğe Ekle', + // Filters 'filter_group' => 'Gruba Göre', 'filter_type' => 'Tipe Göre',