feat: add Website Settings, Imap Settings and Configuration Settings via inerba/filament-db-config

This commit is contained in:
idevakk
2025-11-16 10:56:48 -08:00
parent 4615d384be
commit e3da8cf950
9 changed files with 506 additions and 1 deletions

View File

@@ -0,0 +1,163 @@
<?php
namespace App\Filament\Pages;
use BackedEnum;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Illuminate\Support\Str;
use Inerba\DbConfig\AbstractPageSettings;
class ConfigurationSettings extends AbstractPageSettings
{
/**
* @var array<string, mixed> | 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<string, mixed>
*/
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');
}
}

View File

@@ -0,0 +1,95 @@
<?php
namespace App\Filament\Pages;
use BackedEnum;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Inerba\DbConfig\AbstractPageSettings;
class ImapSettings extends AbstractPageSettings
{
/**
* @var array<string, mixed> | 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<string, mixed>
*/
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');
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace App\Filament\Pages;
use BackedEnum;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Inerba\DbConfig\AbstractPageSettings;
class WebsiteSettings extends AbstractPageSettings
{
/**
* @var array<string, mixed> | 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<string, mixed>
*/
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');
}
}

View File

@@ -10,6 +10,7 @@
"ext-imap": "*", "ext-imap": "*",
"ddeboer/imap": "^1.14", "ddeboer/imap": "^1.14",
"filament/filament": "~4.0", "filament/filament": "~4.0",
"inerba/filament-db-config": "^1.2",
"laravel/cashier": "^15.6", "laravel/cashier": "^15.6",
"laravel/framework": "^12.0", "laravel/framework": "^12.0",
"laravel/sanctum": "^4.0", "laravel/sanctum": "^4.0",

71
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "4cdd6fb15d89efed5ce17b76086a103a", "content-hash": "ec08282da6aabd8a7f1ca24cc7603372",
"packages": [ "packages": [
{ {
"name": "anourvalar/eloquent-serialize", "name": "anourvalar/eloquent-serialize",
@@ -2096,6 +2096,75 @@
], ],
"time": "2025-08-22T14:27:06+00:00" "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", "name": "kirschbaum-development/eloquent-power-joins",
"version": "4.2.10", "version": "4.2.10",

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
$tableName = config('db-config.table_name', 'db_config');
Schema::create($tableName, function (Blueprint $table) {
$table->id();
$table->string('group');
$table->string('key');
$table->json('settings')->nullable();
$table->unique(['group', 'key']);
$table->timestamps();
});
}
};

View File

@@ -0,0 +1,14 @@
<x-filament-panels::page>
<form wire:submit="save" class="fi-page-content">
{{ $this->form }}
<div class="mt-6 flex items-end justify-between">
<x-filament::button type="submit">
{{ __('db-config::db-config.save') }}
</x-filament::button>
<small class="text-success">
{{ __('db-config::db-config.last_updated') }}:
{{ $this->lastUpdatedAt(timezone: 'UTC', format: 'F j, Y, H:i:s') . ' UTC' ?? 'Never' }}
</small>
</div>
</form>
</x-filament-panels::page>

View File

@@ -0,0 +1,14 @@
<x-filament-panels::page>
<form wire:submit="save" class="fi-page-content">
{{ $this->form }}
<div class="mt-6 flex items-end justify-between">
<x-filament::button type="submit">
{{ __('db-config::db-config.save') }}
</x-filament::button>
<small class="text-success">
{{ __('db-config::db-config.last_updated') }}:
{{ $this->lastUpdatedAt(timezone: 'UTC', format: 'F j, Y, H:i:s') . ' UTC' ?? 'Never' }}
</small>
</div>
</form>
</x-filament-panels::page>

View File

@@ -0,0 +1,14 @@
<x-filament-panels::page>
<form wire:submit="save" class="fi-page-content">
{{ $this->form }}
<div class="mt-6 flex items-end justify-between">
<x-filament::button type="submit">
{{ __('db-config::db-config.save') }}
</x-filament::button>
<small class="text-success">
{{ __('db-config::db-config.last_updated') }}:
{{ $this->lastUpdatedAt(timezone: 'UTC', format: 'F j, Y, H:i:s') . ' UTC' ?? 'Never' }}
</small>
</div>
</form>
</x-filament-panels::page>