From e3da8cf950bd068739e66b893f706a2588164515 Mon Sep 17 00:00:00 2001 From: idevakk <219866223+idevakk@users.noreply.github.com> Date: Sun, 16 Nov 2025 10:56:48 -0800 Subject: [PATCH] feat: add Website Settings, Imap Settings and Configuration Settings via inerba/filament-db-config --- app/Filament/Pages/ConfigurationSettings.php | 163 ++++++++++++++++++ app/Filament/Pages/ImapSettings.php | 95 ++++++++++ app/Filament/Pages/WebsiteSettings.php | 108 ++++++++++++ composer.json | 1 + composer.lock | 71 +++++++- ...25_11_16_103033_create_db_config_table.php | 27 +++ .../pages/configuration-settings.blade.php | 14 ++ .../filament/pages/imap-settings.blade.php | 14 ++ .../filament/pages/website-settings.blade.php | 14 ++ 9 files changed, 506 insertions(+), 1 deletion(-) create mode 100644 app/Filament/Pages/ConfigurationSettings.php create mode 100644 app/Filament/Pages/ImapSettings.php create mode 100644 app/Filament/Pages/WebsiteSettings.php create mode 100644 database/migrations/2025_11_16_103033_create_db_config_table.php create mode 100644 resources/views/filament/pages/configuration-settings.blade.php create mode 100644 resources/views/filament/pages/imap-settings.blade.php create mode 100644 resources/views/filament/pages/website-settings.blade.php diff --git a/app/Filament/Pages/ConfigurationSettings.php b/app/Filament/Pages/ConfigurationSettings.php new file mode 100644 index 0000000..b0629c2 --- /dev/null +++ b/app/Filament/Pages/ConfigurationSettings.php @@ -0,0 +1,163 @@ + | null + */ + public ?array $data = []; + + protected static ?string $title = 'Configuration Settings'; + + protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-wrench-screwdriver'; // Uncomment if you want to set a custom navigation icon + + // protected ?string $subheading = ''; // Uncomment if you want to set a custom subheading + + // protected static ?string $slug = 'configuration-settings'; // Uncomment if you want to set a custom slug + + protected string $view = 'filament.pages.configuration-settings'; + + protected function settingName(): string + { + return 'configuration'; + } + + /** + * Provide default values. + * + * @return array + */ + public function getDefaultData(): array + { + return [ + 'enable_masking_external_link' => true, + 'enable_create_from_url' => true, + 'font_family' => [ + 'head' => 'Poppins', + 'body' => 'Poppins', + ], + 'default_language' => 'en', + 'fetch_seconds' => 15, + 'email_limit' => 10, + 'fetch_messages_limit' => 15, + 'cron_password' => Str::random(20), + 'date_format' => 'd M Y h:i A', + 'custom_username_length_min' => 3, + 'custom_username_length_max' => 20, + 'random_username_length_min' => 0, + 'random_username_length_max' => 0, + 'after_last_email_delete' => 'redirect_to_homepage', + + ]; + } + + public function form(Schema $schema): Schema + { + return $schema + ->components([ + Section::make('General Configuration') + ->schema([ + Checkbox::make('enable_masking_external_link') + ->label('Enable URL Masking of External URL') + ->default(false) + ->columnSpan(1) + ->helperText('If you enable this, then we will use href.li to remove your site footprint being passed-on to external link.'), + Checkbox::make('disable_mailbox_slug') + ->label('Disable Mailbox Slug') + ->default(false) + ->columnSpan(1) + ->helperText('If you enable this, then we will disable mailbox slug.'), + Checkbox::make('enable_create_from_url') + ->label('Enable Mail ID Creation from URL') + ->default(true) + ->columnSpan(1) + ->helperText('If you enable this, then users will be able to create email ID from URL.'), + Checkbox::make('enable_ad_block_detector') + ->label('Enable Ad Block Detector') + ->default(true) + ->columnSpan(1) + ->helperText('If you enable this, then we block all the users from using when that have Ad Blocker enabled.'), + KeyValue::make('font_family') + ->label('Font Family') + ->columnSpan(2) + ->helperText('Use Google Fonts with exact name.'), + ]), + + Select::make('default_language')->options([ + 'ar' => 'Arabic', + 'de' => 'German', + 'en' => 'English', + 'fr' => 'French', + 'hi' => 'Hindi', + 'pl' => 'Polish', + 'ru' => 'Russian', + 'es' => 'Spanish', + 'vi' => 'Viet', + 'tr' => 'Turkish', + 'no' => 'Norwegian', + 'id' => 'Indonesian', + ]), + + Section::make('Mailbox Configuration') + ->collapsed() + ->schema([ + Checkbox::make('add_mail_in_title')->label('Add Mail In Title')->default(false)->required()->helperText('If you enable this, then we will automatically add the created temp mail to the page title.'), + Checkbox::make('disable_used_email')->label('Disable Used Email')->default(false)->required()->helperText('If you enable this, same email address cannot be created by user from different IP for one week.'), + TextInput::make('fetch_seconds')->label('Fetch Seconds')->numeric()->required(), + TextInput::make('email_limit')->label('Email Limit')->numeric()->required()->helperText('Limit on number of email ids that can be created per IP address in 24 hours. Recommended - 5.'), + TextInput::make('fetch_messages_limit')->label('Fetch Messages Limit')->numeric()->required()->helperText('Limit of messages retrieved at a time. Keep it to as low as possible. Default - 15.'), + TextInput::make('cron_password')->label('Cron Password')->required(), + TextInput::make('date_format')->label('Date Format')->placeholder('d M Y h:i A')->required(), + Section::make('Custom Username Lengths') + ->description('Username length for custom input') + ->columns(2) + ->schema([ + TextInput::make('custom_username_length_min')->numeric()->minValue(3)->label('Custom Username Min Length')->required(), + TextInput::make('custom_username_length_max')->numeric()->minValue(3)->label('Custom Username Max Length')->required(), + ]), + Section::make('Random Username Lengths') + ->description('Username length for random username') + ->columns(2) + ->schema([ + TextInput::make('random_username_length_min')->numeric()->minValue(0)->label('Random Username Min Length')->required(), + TextInput::make('random_username_length_max')->numeric()->minValue(0)->label('Random Username Max Length')->required(), + ]), + Select::make('after_last_email_delete')->options([ + 'redirect_to_homepage' => 'Redirect to homepage', + 'create_new_email' => 'Create new Email', + ])->required(), + ]), + Section::make('Forbidden Username & Blocked Domains') + ->columns(2) + ->collapsed() + ->schema([ + Repeater::make('forbidden_ids') + ->statePath('forbidden_ids') + ->columnSpan(1) + ->schema([ + TextInput::make('forbidden_id')->label('Forbidden IDs')->required()->maxLength(30), + ]), + Repeater::make('blocked_domains') + ->statePath('blocked_domains') + ->columnSpan(1) + ->schema([ + TextInput::make('blocked_domain')->label('Blocked Domain')->required()->maxLength(30), + ]), + ]), + ]) + ->statePath('data'); + } +} diff --git a/app/Filament/Pages/ImapSettings.php b/app/Filament/Pages/ImapSettings.php new file mode 100644 index 0000000..e7a45a9 --- /dev/null +++ b/app/Filament/Pages/ImapSettings.php @@ -0,0 +1,95 @@ + | null + */ + public ?array $data = []; + + protected static ?string $title = 'Imap Settings'; + + protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedEnvelope; // Uncomment if you want to set a custom navigation icon + + // protected ?string $subheading = ''; // Uncomment if you want to set a custom subheading + + // protected static ?string $slug = 'imap-settings'; // Uncomment if you want to set a custom slug + + protected string $view = 'filament.pages.imap-settings'; + + protected function settingName(): string + { + return 'imap'; + } + + /** + * Provide default values. + * + * @return array + */ + public function getDefaultData(): array + { + return [ + 'public.default_account' => 'default', + 'public.protocol' => 'imap', + 'premium.default_email' => 'default', + 'premium.protocol' => 'imap', + ]; + } + + public function form(Schema $schema): Schema + { + return $schema + ->components([ + Section::make('Public Mailbox Imap') + ->description('Enter your imap server') + ->collapsible() + ->schema([ + TextInput::make('public.host')->label('Hostname')->required(), + TextInput::make('public.port')->label('Port')->required(), + Select::make('public.encryption')->options([ + 'none' => 'None', + 'ssl' => 'SSL', + 'tls' => 'TLS', + ]), + Checkbox::make('public.validate_cert')->label('Validate Encryption Certificate')->default(false), + TextInput::make('public.username')->label('Username')->required(), + TextInput::make('public.password')->label('Password')->required(), + TextInput::make('public.default_account')->label('Default Account')->placeholder('default'), + TextInput::make('public.protocol')->label('Protocol')->placeholder('imap'), + Checkbox::make('public.cc_check')->label('Check CC Field')->default(false)->helperText('If enabled, we will check the CC field as well while fetching mails.'), + ]), + + Section::make('Premium Mailbox Imap') + ->description('Enter your imap server') + ->collapsed() + ->schema([ + TextInput::make('premium.host')->label('Hostname')->required(), + TextInput::make('premium.port')->label('Port')->required(), + Select::make('premium.encryption')->options([ + 'none' => 'None', + 'ssl' => 'SSL', + 'tls' => 'TLS', + ]), + Checkbox::make('premium.validate_cert')->label('Validate Encryption Certificate')->default(false), + TextInput::make('premium.username')->label('Username')->required(), + TextInput::make('premium.password')->label('Password')->required(), + TextInput::make('premium.default_account')->label('Default Account')->placeholder('default'), + TextInput::make('premium.protocol')->label('Protocol')->placeholder('imap'), + Checkbox::make('premium.cc_check')->label('Check CC Field')->default(false)->helperText('If enabled, we will check the CC field as well while fetching mails.'), + ]), + ]) + ->statePath('data'); + } +} diff --git a/app/Filament/Pages/WebsiteSettings.php b/app/Filament/Pages/WebsiteSettings.php new file mode 100644 index 0000000..715509e --- /dev/null +++ b/app/Filament/Pages/WebsiteSettings.php @@ -0,0 +1,108 @@ + | null + */ + public ?array $data = []; + + protected static ?string $title = 'Website Settings'; + + protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCog6Tooth; // Uncomment if you want to set a custom navigation icon + + // protected ?string $subheading = ''; // Uncomment if you want to set a custom subheading + + // protected static ?string $slug = 'website-settings'; // Uncomment if you want to set a custom slug + + protected string $view = 'filament.pages.website-settings'; + + protected function settingName(): string + { + return 'website'; + } + + /** + * Provide default values. + * + * @return array + */ + public function getDefaultData(): array + { + return []; + } + + public function form(Schema $schema): Schema + { + return $schema + ->components([ + Section::make('Website Information') + ->description('Change Basic Website Information') + ->collapsible() + ->schema([ + TextInput::make('app_name')->label('Website Name')->required(), + TextInput::make('app_version')->label('Website Version')->required(), + TextInput::make('app_base_url')->label('Base URL')->required(), + TextInput::make('app_admin')->label('Website Admin')->email()->required(), + TextInput::make('app_contact')->label('Contact Email')->email()->required(), + ]), + Section::make('Custom Codes') + ->description('Add custom codes to header and footer') + ->collapsed() + ->columns(2) + ->schema([ + Textarea::make('app_header')->label('Custom Header')->rows(6)->columnSpan(1), + Textarea::make('app_footer')->label('Custom Footer')->rows(6)->columnSpan(1), + ]), + Section::make('Meta Information') + ->description('Change Website Meta Information') + ->collapsed() + ->schema([ + TextInput::make('app_title')->label('Title')->required(), + Textarea::make('app_description')->label('Description')->rows(3), + TextInput::make('app_keyword')->label('Keyword'), + KeyValue::make('app_meta') + ->label('Meta (Optional)') + ->keyPlaceholder('Name') + ->valuePlaceholder('Content'), + ]), + Section::make('Social Links') + ->description('Enter your social links') + ->collapsed() + ->schema([ + + Repeater::make('app_social') + ->statePath('app_social') + ->schema([ + TextInput::make('icon')->label('Icon')->required()->maxLength(100), + TextInput::make('url')->label('URL')->url()->required()->maxLength(255), + ]), + + ]), + Section::make('Ad Spaces') + ->description('You can setup your Ad Codes here for various Ad Spaces') + ->collapsed() + ->schema([ + Textarea::make('ads_settings.one')->label('Ad Space 1')->rows(4), + Textarea::make('ads_settings.two')->label('Ad Space 2')->rows(4), + Textarea::make('ads_settings.three')->label('Ad Space 3')->rows(4), + Textarea::make('ads_settings.four')->label('Ad Space 4')->rows(4), + Textarea::make('ads_settings.five')->label('Ad Space 5')->rows(4), + ]), + + ]) + ->statePath('data'); + } +} diff --git a/composer.json b/composer.json index 667c22e..b330988 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ "ext-imap": "*", "ddeboer/imap": "^1.14", "filament/filament": "~4.0", + "inerba/filament-db-config": "^1.2", "laravel/cashier": "^15.6", "laravel/framework": "^12.0", "laravel/sanctum": "^4.0", diff --git a/composer.lock b/composer.lock index ad76bbd..970a90f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4cdd6fb15d89efed5ce17b76086a103a", + "content-hash": "ec08282da6aabd8a7f1ca24cc7603372", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -2096,6 +2096,75 @@ ], "time": "2025-08-22T14:27:06+00:00" }, + { + "name": "inerba/filament-db-config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/inerba/filament-db-config.git", + "reference": "cc30fe46cc9342f54a536c4cdb35f84f84b67fef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/inerba/filament-db-config/zipball/cc30fe46cc9342f54a536c4cdb35f84f84b67fef", + "reference": "cc30fe46cc9342f54a536c4cdb35f84f84b67fef", + "shasum": "" + }, + "require": { + "filament/filament": "^4.0", + "php": "^8.2", + "spatie/laravel-package-tools": "^1.15.0" + }, + "require-dev": { + "laravel/pint": "^1.14", + "orchestra/testbench": "^10.0", + "pestphp/pest": "^4.0", + "phpstan/phpstan": "^2.1" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "DbConfig": "Inerba\\DbConfig\\Facades\\DbConfig" + }, + "providers": [ + "Inerba\\DbConfig\\DbConfigServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Inerba\\DbConfig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Francesco Apruzzese", + "email": "inerba@gmail.com", + "role": "Developer" + } + ], + "description": "A Filament plugin for database-backed application settings and editable content, with caching and easy page generation.", + "homepage": "https://github.com/inerba/filament-db-config", + "keywords": [ + "filament", + "filament-plugin", + "laravel", + "laravel-filament" + ], + "support": { + "issues": "https://github.com/inerba/filament-db-config/issues", + "source": "https://github.com/inerba/filament-db-config" + }, + "time": "2025-10-26T10:16:05+00:00" + }, { "name": "kirschbaum-development/eloquent-power-joins", "version": "4.2.10", diff --git a/database/migrations/2025_11_16_103033_create_db_config_table.php b/database/migrations/2025_11_16_103033_create_db_config_table.php new file mode 100644 index 0000000..9b33914 --- /dev/null +++ b/database/migrations/2025_11_16_103033_create_db_config_table.php @@ -0,0 +1,27 @@ +id(); + + $table->string('group'); + + $table->string('key'); + + $table->json('settings')->nullable(); + + $table->unique(['group', 'key']); + + $table->timestamps(); + }); + } +}; diff --git a/resources/views/filament/pages/configuration-settings.blade.php b/resources/views/filament/pages/configuration-settings.blade.php new file mode 100644 index 0000000..ed480d1 --- /dev/null +++ b/resources/views/filament/pages/configuration-settings.blade.php @@ -0,0 +1,14 @@ + +
+ {{ $this->form }} +
+ + {{ __('db-config::db-config.save') }} + + + {{ __('db-config::db-config.last_updated') }}: + {{ $this->lastUpdatedAt(timezone: 'UTC', format: 'F j, Y, H:i:s') . ' UTC' ?? 'Never' }} + +
+
+
\ No newline at end of file diff --git a/resources/views/filament/pages/imap-settings.blade.php b/resources/views/filament/pages/imap-settings.blade.php new file mode 100644 index 0000000..ed480d1 --- /dev/null +++ b/resources/views/filament/pages/imap-settings.blade.php @@ -0,0 +1,14 @@ + +
+ {{ $this->form }} +
+ + {{ __('db-config::db-config.save') }} + + + {{ __('db-config::db-config.last_updated') }}: + {{ $this->lastUpdatedAt(timezone: 'UTC', format: 'F j, Y, H:i:s') . ' UTC' ?? 'Never' }} + +
+
+
\ No newline at end of file diff --git a/resources/views/filament/pages/website-settings.blade.php b/resources/views/filament/pages/website-settings.blade.php new file mode 100644 index 0000000..ed480d1 --- /dev/null +++ b/resources/views/filament/pages/website-settings.blade.php @@ -0,0 +1,14 @@ + +
+ {{ $this->form }} +
+ + {{ __('db-config::db-config.save') }} + + + {{ __('db-config::db-config.last_updated') }}: + {{ $this->lastUpdatedAt(timezone: 'UTC', format: 'F j, Y, H:i:s') . ' UTC' ?? 'Never' }} + +
+
+
\ No newline at end of file