Refactor form components across multiple pages: enforce required validation on various text inputs and file uploads in HomePageSettings, ManagePortfolio, ManageSite, ManageSiteSocialSettings, ManageSolutions, ManageSuccess, and update the news index view to display dynamic content.

This commit is contained in:
2025-07-28 17:14:40 +05:00
parent 1ceccb0d79
commit bae4204d44
29 changed files with 360 additions and 50 deletions

View File

@@ -3,14 +3,13 @@
namespace App\Filament\Pages;
use App\Settings\HomeSettings;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Pages\Page;
use Filament\Pages\SettingsPage;
use Illuminate\Contracts\Support\Htmlable;
@@ -81,19 +80,19 @@ class HomePageSettings extends SettingsPage
->label('Projects Number')
->numeric()
->required(),
])->columns(2),
Grid::make()->schema([
TextInput::make('about_members_text')
->label('Members Text')
->maxLength(100)
->required(),
TextInput::make('about_members_number')
->label('Members Number')
->numeric()
->required(),
])->columns(2),
Grid::make()->schema([
@@ -106,7 +105,7 @@ class HomePageSettings extends SettingsPage
->label('Reviews Number')
->numeric()
->required(),
])->columns(2),
Grid::make()->schema([
TextInput::make('about_button_text')
@@ -148,7 +147,7 @@ class HomePageSettings extends SettingsPage
->url()
->required(),
]),
Section::make('Industry Area')
->description('Manage the content for the industry area section.')
->icon('heroicon-o-building-office')

View File

@@ -3,11 +3,11 @@
namespace App\Filament\Pages;
use App\Settings\PortfolioSettings;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Form;
use Filament\Pages\SettingsPage;
use Illuminate\Contracts\Support\Htmlable;
@@ -33,9 +33,11 @@ class ManagePortfolio extends SettingsPage
Grid::make()->schema([
TextInput::make('portfolio_button_text')
->label('Button Text')
->required()
->maxLength(50),
TextInput::make('portfolio_button_url')
->label('Button URL')
->required()
->maxLength(255)
->url(),
])->columns(2),
@@ -49,7 +51,8 @@ class ManagePortfolio extends SettingsPage
->schema([
FileUpload::make('image')
->label('Image (700x525)')
->image() ->maxSize(2048)
->image()
->maxSize(2048)
->disk('public')
->directory('portfolio-images')
->required(),
@@ -103,4 +106,4 @@ class ManagePortfolio extends SettingsPage
{
return 'Manage the portfolio section content, including items, categories, and titles.';
}
}
}

View File

@@ -38,10 +38,12 @@ class ManageSite extends SettingsPage
->maxLength(100),
Forms\Components\TextInput::make('tagline')
->label('Site Tagline')
->required()
->helperText('A short phrase describing your site')
->maxLength(150),
Forms\Components\Textarea::make('description')
->label('Site Description')
->required()
->helperText('A detailed description of your website')
->rows(3)
->maxLength(500),
@@ -65,13 +67,16 @@ class ManageSite extends SettingsPage
->maxLength(100),
Forms\Components\TextInput::make('company_phone')
->label('Company Phone')
->required()
->maxLength(20),
Forms\Components\TextInput::make('company_phone_2')
->label('Company Additional Phone')
->required()
->maxLength(20),
])->columns(2),
Forms\Components\Textarea::make('company_address')
->label('Company Address')
->required()
->rows(2)
->maxLength(200),
]),
@@ -94,17 +99,20 @@ class ManageSite extends SettingsPage
->schema([
Forms\Components\TextInput::make('copyright_text')
->label('Copyright Text')
->required()
->maxLength(200),
Forms\Components\Grid::make()->schema([
Forms\Components\TextInput::make('terms_url')
->label('Terms & Conditions URL')
->required()
->maxLength(100)
->prefix(function (Forms\Get $get) {
return url('/');
}),
Forms\Components\TextInput::make('privacy_url')
->label('Privacy Policy URL')
->required()
->maxLength(100)
->prefix(function (Forms\Get $get) {
return url('/');
@@ -120,10 +128,12 @@ class ManageSite extends SettingsPage
Forms\Components\Grid::make()->schema([
Forms\Components\Textarea::make('custom_404_message')
->label('404 Not Found Message')
->required()
->rows(2)
->maxLength(500),
Forms\Components\Textarea::make('custom_500_message')
->label('500 Server Error Message')
->required()
->rows(2)
->maxLength(500),
])->columns(2),

View File

@@ -28,18 +28,22 @@ class ManageSiteSocialSettings extends SettingsPage
Forms\Components\Grid::make()->schema([
Forms\Components\TextInput::make('facebook_url')
->label('Facebook URL')
->required()
->prefix('https://')
->helperText('e.g., facebook.com/yourpage'),
Forms\Components\TextInput::make('twitter_url')
->label('Twitter/X URL')
->required()
->prefix('https://')
->helperText('e.g., twitter.com/yourusername'),
Forms\Components\TextInput::make('instagram_url')
->label('Instagram URL')
->required()
->prefix('https://')
->helperText('e.g., instagram.com/yourusername'),
Forms\Components\TextInput::make('linkedin_url')
->label('LinkedIn URL')
->required()
->prefix('https://')
->helperText('e.g., linkedin.com/company/yourcompany'),
])->columns(2),

View File

@@ -4,12 +4,10 @@ namespace App\Filament\Pages;
use App\Settings\SolutionSettings;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Form;
use Filament\Pages\Page;
use Filament\Pages\SettingsPage;
use Illuminate\Contracts\Support\Htmlable;
@@ -29,6 +27,7 @@ class ManageSolutions extends SettingsPage
->schema([
TextInput::make('solutions_subtitle')
->label('Subtitle')
->required()
->maxLength(100),
TextInput::make('solutions_header')
->label('Header')
@@ -37,9 +36,11 @@ class ManageSolutions extends SettingsPage
Grid::make()->schema([
TextInput::make('solutions_button_text')
->label('Button Text')
->required()
->maxLength(50),
TextInput::make('solutions_button_url')
->label('Button URL')
->required()
->maxLength(255)
->url(),
])->columns(2),
@@ -103,4 +104,4 @@ class ManageSolutions extends SettingsPage
{
return 'Manage the solutions section content, including individual solution items.';
}
}
}

View File

@@ -4,10 +4,10 @@ namespace App\Filament\Pages;
use App\Settings\SuccessSettings;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Pages\SettingsPage;
use Illuminate\Contracts\Support\Htmlable;
@@ -28,6 +28,7 @@ class ManageSuccess extends SettingsPage
->schema([
TextInput::make('success_subtitle')
->label('Subtitle')
->required()
->maxLength(100),
TextInput::make('success_header')
->label('Header')
@@ -35,14 +36,17 @@ class ManageSuccess extends SettingsPage
->maxLength(255),
Textarea::make('success_paragraph')
->label('Paragraph')
->required()
->rows(3)
->maxLength(65535),
Grid::make()->schema([
TextInput::make('success_button_text')
->label('Button Text')
->required()
->maxLength(50),
TextInput::make('success_button_url')
->label('Button URL')
->required()
->maxLength(255)
->url(),
])->columns(2),
@@ -101,4 +105,4 @@ class ManageSuccess extends SettingsPage
{
return 'Manage the success section content, including text, button, and skill bars.';
}
}
}

View File

@@ -3,9 +3,7 @@
namespace App\Filament\Resources;
use App\Filament\Resources\BrandResource\Pages;
use App\Filament\Resources\BrandResource\RelationManagers;
use App\Models\Brand;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
@@ -16,8 +14,6 @@ use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class BrandResource extends Resource
{
@@ -36,12 +32,12 @@ class BrandResource extends Resource
FileUpload::make('image')
->image()
->imageEditor()
->rules(['required', 'image',]),
->rules(['required', 'image']),
Toggle::make('active')
->label('Is active')
->onColor('success')
->offColor('danger')
->offColor('danger'),
]);
}

View File

@@ -0,0 +1,114 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\NewsResource\Pages;
use App\Models\News;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Table;
use Illuminate\Support\Str;
class NewsResource extends Resource
{
protected static ?string $model = News::class;
protected static ?string $navigationIcon = 'heroicon-o-newspaper';
protected static ?string $navigationGroup = 'CMS';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Card::make()
->schema([
TextInput::make('title')
->required()
->maxLength(255)
->reactive()
->afterStateUpdated(fn (string $operation, $state, Forms\Set $set) => $operation === 'create' ? $set('slug', Str::slug($state)) : null),
TextInput::make('slug')
->required()
->maxLength(255)
->disabled()
->dehydrated()
->unique(News::class, 'slug', ignoreRecord: true),
FileUpload::make('image')
->image()
->directory('news')
->nullable()
->columnSpanFull(),
RichEditor::make('content')
->required()
->columnSpanFull(),
DateTimePicker::make('published_at')
->required()
->default(now()),
])
->columns(2),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
ImageColumn::make('image')
->square()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('title')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('slug')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('published_at')
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListNews::route('/'),
'create' => Pages\CreateNews::route('/create'),
'edit' => Pages\EditNews::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\NewsResource\Pages;
use App\Filament\Resources\NewsResource;
use Filament\Resources\Pages\CreateRecord;
class CreateNews extends CreateRecord
{
protected static string $resource = NewsResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\NewsResource\Pages;
use App\Filament\Resources\NewsResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditNews extends EditRecord
{
protected static string $resource = NewsResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\NewsResource\Pages;
use App\Filament\Resources\NewsResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListNews extends ListRecords
{
protected static string $resource = NewsResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}