diff --git a/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php b/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php index 52a09e1..bf7ac58 100644 --- a/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php +++ b/app/Filament/Admin/Resources/Settings/Schemas/SettingForm.php @@ -10,6 +10,17 @@ use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\DateTimePicker; use Filament\Forms\Components\DatePicker; use Filament\Forms\Components\Repeater; +use Filament\Forms\Components\ColorPicker; +use Filament\Forms\Components\CodeEditor; +use Filament\Forms\Components\CodeEditor\Enums\Language as CodeEditorLanguage; +use Filament\Forms\Components\RichEditor; +use Filament\Forms\Components\MarkdownEditor; +use Filament\Forms\Components\TagsInput; +use Filament\Forms\Components\CheckboxList; +use Filament\Forms\Components\Radio; +use Filament\Forms\Components\ToggleButtons; +use Filament\Forms\Components\Slider; +use Filament\Forms\Components\KeyValue; use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Set; @@ -61,6 +72,16 @@ class SettingForm 'file' => __('settings.type_file'), 'date' => __('settings.type_date'), 'datetime' => __('settings.type_datetime'), + 'color_picker' => __('settings.type_color_picker'), + 'code_editor' => __('settings.type_code_editor'), + 'rich_editor' => __('settings.type_rich_editor'), + 'markdown_editor' => __('settings.type_markdown_editor'), + 'tags_input' => __('settings.type_tags_input'), + 'checkbox_list' => __('settings.type_checkbox_list'), + 'radio' => __('settings.type_radio'), + 'toggle_buttons' => __('settings.type_toggle_buttons'), + 'slider' => __('settings.type_slider'), + 'key_value' => __('settings.type_key_value'), ]) ->live() ->afterStateUpdated(fn (Set $set) => $set('value', null)), @@ -85,10 +106,10 @@ class SettingForm ->label(__('settings.value')) ->helperText(__('settings.value_helper')) ->required() - ->visible(fn (Get $get) => !in_array($get('type'), ['boolean', 'file', 'date', 'datetime', 'array'])) + ->visible(fn (Get $get) => in_array($get('type'), ['string', 'text', 'json'])) ->rows(fn (Get $get) => $get('type') === 'text' ? 5 : 3) ->formatStateUsing(function ($state, $record) { - if ($record && !in_array($record->type, ['boolean', 'file', 'date', 'datetime', 'array'])) { + if ($record && in_array($record->type, ['string', 'text', 'json'])) { return $record->value; } return $state; @@ -193,6 +214,176 @@ class SettingForm }) ->columnSpanFull(), + ColorPicker::make('value_color_picker') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'color_picker') + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'color_picker') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + CodeEditor::make('value_code_editor') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'code_editor') + ->language(CodeEditorLanguage::Php) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'code_editor') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + RichEditor::make('value_rich_editor') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'rich_editor') + ->fileAttachmentsDisk('public') + ->fileAttachmentsDirectory('settings') + ->toolbarButtons([ + 'attachFiles', + 'blockquote', + 'bold', + 'bulletList', + 'codeBlock', + 'h2', + 'h3', + 'italic', + 'link', + 'orderedList', + 'redo', + 'strike', + 'underline', + 'undo', + ]) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'rich_editor') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + MarkdownEditor::make('value_markdown_editor') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'markdown_editor') + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'markdown_editor') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + TagsInput::make('value_tags_input') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'tags_input') + ->separator(',') + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'tags_input') { + $decoded = json_decode($record->value, true); + return is_array($decoded) ? $decoded : []; + } + return is_array($state) ? $state : []; + }) + ->columnSpanFull(), + + CheckboxList::make('value_checkbox_list') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'checkbox_list') + ->options(fn () => [ + 'option1' => __('settings.checkbox_option_1'), + 'option2' => __('settings.checkbox_option_2'), + 'option3' => __('settings.checkbox_option_3'), + ]) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'checkbox_list') { + $decoded = json_decode($record->value, true); + return is_array($decoded) ? $decoded : []; + } + return is_array($state) ? $state : []; + }) + ->columnSpanFull(), + + Radio::make('value_radio') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'radio') + ->options(fn () => [ + 'option1' => __('settings.radio_option_1'), + 'option2' => __('settings.radio_option_2'), + 'option3' => __('settings.radio_option_3'), + ]) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'radio') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + ToggleButtons::make('value_toggle_buttons') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'toggle_buttons') + ->options(fn () => [ + 'option1' => __('settings.toggle_option_1'), + 'option2' => __('settings.toggle_option_2'), + 'option3' => __('settings.toggle_option_3'), + ]) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'toggle_buttons') { + return $record->value; + } + return $state; + }) + ->columnSpanFull(), + + Slider::make('value_slider') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'slider') + ->range(minValue: 0, maxValue: 100) + ->step(1) + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'slider') { + return (int) $record->value; + } + return $state ?? 0; + }) + ->columnSpanFull(), + + KeyValue::make('value_key_value') + ->label(__('settings.value')) + ->helperText(__('settings.value_helper')) + ->required() + ->visible(fn (Get $get) => $get('type') === 'key_value') + ->formatStateUsing(function ($state, $record) { + if ($record && $record->type === 'key_value') { + $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/Filament/Admin/Resources/Settings/Tables/SettingsTable.php b/app/Filament/Admin/Resources/Settings/Tables/SettingsTable.php index 1f5bd10..ae1b375 100644 --- a/app/Filament/Admin/Resources/Settings/Tables/SettingsTable.php +++ b/app/Filament/Admin/Resources/Settings/Tables/SettingsTable.php @@ -111,6 +111,19 @@ class SettingsTable 'float' => __('settings.type_float'), 'array' => __('settings.type_array'), 'json' => __('settings.type_json'), + 'file' => __('settings.type_file'), + 'date' => __('settings.type_date'), + 'datetime' => __('settings.type_datetime'), + 'color_picker' => __('settings.type_color_picker'), + 'code_editor' => __('settings.type_code_editor'), + 'rich_editor' => __('settings.type_rich_editor'), + 'markdown_editor' => __('settings.type_markdown_editor'), + 'tags_input' => __('settings.type_tags_input'), + 'checkbox_list' => __('settings.type_checkbox_list'), + 'radio' => __('settings.type_radio'), + 'toggle_buttons' => __('settings.type_toggle_buttons'), + 'slider' => __('settings.type_slider'), + 'key_value' => __('settings.type_key_value'), ]), TernaryFilter::make('is_active') diff --git a/app/Models/Setting.php b/app/Models/Setting.php index eec21c2..4ad7442 100644 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -19,6 +19,16 @@ class Setting extends Model 'value_date', 'value_datetime', 'value_array', + 'value_color_picker', + 'value_code_editor', + 'value_rich_editor', + 'value_markdown_editor', + 'value_tags_input', + 'value_checkbox_list', + 'value_radio', + 'value_toggle_buttons', + 'value_slider', + 'value_key_value', 'type', 'group', 'label', @@ -86,6 +96,86 @@ class Setting extends Model $this->attributes['value'] = is_array($value) ? json_encode($value) : $value; } + /** + * Set value from color picker + */ + public function setValueColorPickerAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from code editor + */ + public function setValueCodeEditorAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from rich editor + */ + public function setValueRichEditorAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from markdown editor + */ + public function setValueMarkdownEditorAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from tags input + */ + public function setValueTagsInputAttribute($value) + { + $this->attributes['value'] = is_array($value) ? json_encode($value) : $value; + } + + /** + * Set value from checkbox list + */ + public function setValueCheckboxListAttribute($value) + { + $this->attributes['value'] = is_array($value) ? json_encode($value) : $value; + } + + /** + * Set value from radio + */ + public function setValueRadioAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from toggle buttons + */ + public function setValueToggleButtonsAttribute($value) + { + $this->attributes['value'] = $value; + } + + /** + * Set value from slider + */ + public function setValueSliderAttribute($value) + { + $this->attributes['value'] = (string) $value; + } + + /** + * Set value from key value + */ + public function setValueKeyValueAttribute($value) + { + $this->attributes['value'] = is_array($value) ? json_encode($value) : $value; + } + /** * Get setting by key */ @@ -126,10 +216,17 @@ class Setting extends Model 'boolean' => filter_var($value, FILTER_VALIDATE_BOOLEAN), 'integer' => (int) $value, 'float' => (float) $value, - 'array', 'json' => json_decode($value, true), + 'array', 'json', 'tags_input', 'checkbox_list', 'key_value' => 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) + 'color_picker' => $value, // Color as hex string + 'code_editor' => $value, // Code as string + 'rich_editor' => $value, // HTML as string + 'markdown_editor' => $value, // Markdown as string + 'radio' => $value, // Radio selection as string + 'toggle_buttons' => $value, // Toggle selection as string + 'slider' => (int) $value, // Slider value as integer default => $value, }; } diff --git a/database/migrations/2025_10_29_183814_add_filament_form_types_to_settings_table.php b/database/migrations/2025_10_29_183814_add_filament_form_types_to_settings_table.php new file mode 100644 index 0000000..eb05baf --- /dev/null +++ b/database/migrations/2025_10_29_183814_add_filament_form_types_to_settings_table.php @@ -0,0 +1,60 @@ +enum('type', [ + 'string', + 'text', + 'boolean', + 'integer', + 'float', + 'array', + 'json', + 'file', + 'date', + 'datetime', + 'color_picker', + 'code_editor', + 'rich_editor', + 'markdown_editor', + 'tags_input', + 'checkbox_list', + 'radio', + 'toggle_buttons', + 'slider', + 'key_value', + ])->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', + 'date', + 'datetime', + ])->default('string')->change(); + }); + } +}; diff --git a/lang/en/settings.php b/lang/en/settings.php index b983bae..54135cb 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -62,6 +62,16 @@ return [ 'type_file' => 'File', 'type_date' => 'Date', 'type_datetime' => 'Date & Time', + 'type_color_picker' => 'Color Picker', + 'type_code_editor' => 'Code Editor', + 'type_rich_editor' => 'Rich Text Editor', + 'type_markdown_editor' => 'Markdown Editor', + 'type_tags_input' => 'Tags Input', + 'type_checkbox_list' => 'Checkbox List', + 'type_radio' => 'Radio Button', + 'type_toggle_buttons' => 'Toggle Buttons', + 'type_slider' => 'Slider', + 'type_key_value' => 'Key-Value Pairs', // Groups 'group_general' => 'General', @@ -91,6 +101,21 @@ return [ 'array_active' => 'Active', 'array_add_item' => 'Add Item', + // Checkbox options (placeholder, can be customized per setting) + 'checkbox_option_1' => 'Option 1', + 'checkbox_option_2' => 'Option 2', + 'checkbox_option_3' => 'Option 3', + + // Radio options (placeholder, can be customized per setting) + 'radio_option_1' => 'Option 1', + 'radio_option_2' => 'Option 2', + 'radio_option_3' => 'Option 3', + + // Toggle options (placeholder, can be customized per setting) + 'toggle_option_1' => 'Option 1', + 'toggle_option_2' => 'Option 2', + 'toggle_option_3' => 'Option 3', + // Filters 'filter_group' => 'By Group', 'filter_type' => 'By Type', diff --git a/lang/tr/settings.php b/lang/tr/settings.php index 6c472ff..07c4095 100644 --- a/lang/tr/settings.php +++ b/lang/tr/settings.php @@ -62,6 +62,16 @@ return [ 'type_file' => 'Dosya', 'type_date' => 'Tarih', 'type_datetime' => 'Tarih ve Saat', + 'type_color_picker' => 'Renk Seçici', + 'type_code_editor' => 'Kod Editörü', + 'type_rich_editor' => 'Zengin Metin Editörü', + 'type_markdown_editor' => 'Markdown Editörü', + 'type_tags_input' => 'Etiket Girişi', + 'type_checkbox_list' => 'Çoklu Seçim', + 'type_radio' => 'Radio Buton', + 'type_toggle_buttons' => 'Toggle Butonları', + 'type_slider' => 'Kaydırıcı', + 'type_key_value' => 'Anahtar-Değer Çiftleri', // Groups 'group_general' => 'Genel', @@ -91,6 +101,21 @@ return [ 'array_active' => 'Aktif', 'array_add_item' => 'Öğe Ekle', + // Checkbox options (placeholder, can be customized per setting) + 'checkbox_option_1' => 'Seçenek 1', + 'checkbox_option_2' => 'Seçenek 2', + 'checkbox_option_3' => 'Seçenek 3', + + // Radio options (placeholder, can be customized per setting) + 'radio_option_1' => 'Seçenek 1', + 'radio_option_2' => 'Seçenek 2', + 'radio_option_3' => 'Seçenek 3', + + // Toggle options (placeholder, can be customized per setting) + 'toggle_option_1' => 'Seçenek 1', + 'toggle_option_2' => 'Seçenek 2', + 'toggle_option_3' => 'Seçenek 3', + // Filters 'filter_group' => 'Gruba Göre', 'filter_type' => 'Tipe Göre',