From 7c5055075bee545e2e09378970f56c8ece98b158 Mon Sep 17 00:00:00 2001 From: phuongtc Date: Fri, 1 May 2026 12:54:12 +0000 Subject: [PATCH] colorful --- .../Contracts/Schemas/ContractForm.php | 2 -- .../Feedback/Schemas/FeedbackForm.php | 15 ++++++++---- .../Feedback/Tables/FeedbackTable.php | 8 ++++++- .../Schemas/FeedbackChannelForm.php | 3 +++ .../Tables/FeedbackChannelsTable.php | 16 ++++++++++++- .../FeedbackTags/Schemas/FeedbackTagForm.php | 20 ++++++++++++---- .../FeedbackTags/Tables/FeedbackTagsTable.php | 24 ++++++++++++++----- app/Models/Contract.php | 9 +++++++ app/Models/FeedbackChannel.php | 2 +- ...4_add_color_to_feedback_channels_table.php | 22 +++++++++++++++++ database/seeders/AfterSalesSeeder.php | 10 ++++---- public/css/filament-custom.css | 23 ++++++++++++++++++ 12 files changed, 128 insertions(+), 26 deletions(-) create mode 100644 database/migrations/2026_05_01_000004_add_color_to_feedback_channels_table.php diff --git a/app/Filament/Resources/Contracts/Schemas/ContractForm.php b/app/Filament/Resources/Contracts/Schemas/ContractForm.php index 549dc361..99286f58 100644 --- a/app/Filament/Resources/Contracts/Schemas/ContractForm.php +++ b/app/Filament/Resources/Contracts/Schemas/ContractForm.php @@ -21,12 +21,10 @@ class ContractForm Select::make('product_id') ->relationship('product', 'name') ->searchable() - ->preload() ->required(), Select::make('customer_id') ->relationship('customer', 'name') ->searchable() - ->preload() ->required(), Select::make('type') ->options(ContractType::options()) diff --git a/app/Filament/Resources/Feedback/Schemas/FeedbackForm.php b/app/Filament/Resources/Feedback/Schemas/FeedbackForm.php index f110c671..57255358 100644 --- a/app/Filament/Resources/Feedback/Schemas/FeedbackForm.php +++ b/app/Filament/Resources/Feedback/Schemas/FeedbackForm.php @@ -4,6 +4,7 @@ namespace App\Filament\Resources\Feedback\Schemas; use App\Models\CustomerProduct; use App\Models\Department; +use Filament\Forms\Components\ColorPicker; use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\Select; use Filament\Forms\Components\Textarea; @@ -23,7 +24,6 @@ class FeedbackForm Select::make('customer_id') ->relationship('customer', 'name') ->searchable() - ->preload() ->required() ->live(), @@ -34,20 +34,26 @@ class FeedbackForm Select::make('customer_product_id') ->label('Product') - ->options(function ($get): array { + ->searchable() + ->getSearchResultsUsing(function (string $search, $get): array { $customerId = $get('customer_id'); if (! $customerId) { return []; } + $keyword = mb_strtolower($search); return CustomerProduct::where('customer_id', $customerId) + ->whereHas('product', fn ($q) => $q->whereRaw('LOWER(name) LIKE ?', ["%{$keyword}%"])) ->with('product') + ->limit(50) ->get() ->pluck('product.name', 'id') ->toArray(); }) + ->getOptionLabelUsing(fn ($value): ?string => + CustomerProduct::find($value)?->product?->name + ) ->visible(fn ($get): bool => ! $get('is_general')) ->nullable() - ->searchable() ->live(), Select::make('contract_id') @@ -135,7 +141,7 @@ class FeedbackForm ->createOptionForm([ TextInput::make('name')->required(), TextInput::make('slug')->required(), - TextInput::make('color')->type('color'), + ColorPicker::make('color')->default('#3b82f6'), ]), Select::make('status') @@ -151,7 +157,6 @@ class FeedbackForm Select::make('assigned_to') ->relationship('assignedTo', 'name') ->searchable() - ->preload() ->nullable(), Select::make('current_department_id') diff --git a/app/Filament/Resources/Feedback/Tables/FeedbackTable.php b/app/Filament/Resources/Feedback/Tables/FeedbackTable.php index 02cc6e74..ac9a8cda 100644 --- a/app/Filament/Resources/Feedback/Tables/FeedbackTable.php +++ b/app/Filament/Resources/Feedback/Tables/FeedbackTable.php @@ -39,7 +39,13 @@ class FeedbackTable ->placeholder('-') ->toggleable(), TextColumn::make('feedbackChannel.name') - ->label('Channel'), + ->label('Channel') + ->formatStateUsing(fn ($state, $record) => sprintf( + '%s', + $record->feedbackChannel?->color ?: '#6b7280', + e($state) + )) + ->html(), TextColumn::make('tags.name') ->badge() ->separator(','), diff --git a/app/Filament/Resources/FeedbackChannels/Schemas/FeedbackChannelForm.php b/app/Filament/Resources/FeedbackChannels/Schemas/FeedbackChannelForm.php index c13ff50d..af8d4a3c 100644 --- a/app/Filament/Resources/FeedbackChannels/Schemas/FeedbackChannelForm.php +++ b/app/Filament/Resources/FeedbackChannels/Schemas/FeedbackChannelForm.php @@ -2,6 +2,7 @@ namespace App\Filament\Resources\FeedbackChannels\Schemas; +use Filament\Forms\Components\ColorPicker; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; use Filament\Schemas\Components\Section; @@ -25,6 +26,8 @@ class FeedbackChannelForm TextInput::make('icon') ->maxLength(255) ->hint('Heroicon name or emoji'), + ColorPicker::make('color') + ->label('Color'), Toggle::make('is_active') ->default(true), ]) diff --git a/app/Filament/Resources/FeedbackChannels/Tables/FeedbackChannelsTable.php b/app/Filament/Resources/FeedbackChannels/Tables/FeedbackChannelsTable.php index 6959c4c0..c1988d36 100644 --- a/app/Filament/Resources/FeedbackChannels/Tables/FeedbackChannelsTable.php +++ b/app/Filament/Resources/FeedbackChannels/Tables/FeedbackChannelsTable.php @@ -17,9 +17,23 @@ class FeedbackChannelsTable ->columns([ TextColumn::make('name') ->searchable() - ->sortable(), + ->sortable() + ->formatStateUsing(fn ($state, $record) => sprintf( + '%s', + $record->color ?: '#6b7280', + e($state) + )) + ->html(), TextColumn::make('slug') ->searchable(), + TextColumn::make('color') + ->label('Color') + ->formatStateUsing(fn ($state) => sprintf( + '', + $state ?: '#6b7280', + $state + )) + ->html(), IconColumn::make('is_active') ->boolean() ->label('Active'), diff --git a/app/Filament/Resources/FeedbackTags/Schemas/FeedbackTagForm.php b/app/Filament/Resources/FeedbackTags/Schemas/FeedbackTagForm.php index d5c7e049..c0a831cb 100644 --- a/app/Filament/Resources/FeedbackTags/Schemas/FeedbackTagForm.php +++ b/app/Filament/Resources/FeedbackTags/Schemas/FeedbackTagForm.php @@ -2,7 +2,9 @@ namespace App\Filament\Resources\FeedbackTags\Schemas; +use Filament\Forms\Components\ColorPicker; use Filament\Forms\Components\TextInput; +use Filament\Schemas\Components\Section; use Filament\Schemas\Schema; class FeedbackTagForm @@ -11,11 +13,19 @@ class FeedbackTagForm { return $schema ->components([ - TextInput::make('name') - ->required(), - TextInput::make('slug') - ->required(), - TextInput::make('color'), + Section::make() + ->schema([ + TextInput::make('name') + ->required() + ->maxLength(255), + TextInput::make('slug') + ->required() + ->maxLength(255), + ColorPicker::make('color') + ->label('Color') + ->default('#3b82f6'), + ]) + ->columns(2), ]); } } diff --git a/app/Filament/Resources/FeedbackTags/Tables/FeedbackTagsTable.php b/app/Filament/Resources/FeedbackTags/Tables/FeedbackTagsTable.php index 4fbd0d7c..ab5db0f3 100644 --- a/app/Filament/Resources/FeedbackTags/Tables/FeedbackTagsTable.php +++ b/app/Filament/Resources/FeedbackTags/Tables/FeedbackTagsTable.php @@ -5,6 +5,7 @@ namespace App\Filament\Resources\FeedbackTags\Tables; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; +use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; @@ -15,19 +16,30 @@ class FeedbackTagsTable return $table ->columns([ TextColumn::make('name') - ->searchable(), + ->searchable() + ->formatStateUsing(fn ($state, $record) => sprintf( + '%s', + $record->color ?: '#6b7280', + e($state) + )) + ->html(), TextColumn::make('slug') ->searchable(), TextColumn::make('color') - ->searchable(), + ->label('Color') + ->formatStateUsing(fn ($state) => sprintf( + '', + $state ?: '#6b7280', + $state + )) + ->html(), + TextColumn::make('feedbacks_count') + ->counts('feedbacks') + ->label('Used'), TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), - TextColumn::make('updated_at') - ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ // diff --git a/app/Models/Contract.php b/app/Models/Contract.php index f504447c..059eb768 100644 --- a/app/Models/Contract.php +++ b/app/Models/Contract.php @@ -10,6 +10,15 @@ use Illuminate\Database\Eloquent\Relations\HasMany; #[Fillable(['product_id', 'customer_id', 'type', 'start_date', 'end_date', 'status', 'printed_at', 'signed_status'])] class Contract extends Model { + protected function casts(): array + { + return [ + 'start_date' => 'date', + 'end_date' => 'date', + 'printed_at' => 'date', + ]; + } + public function product(): BelongsTo { return $this->belongsTo(Product::class); diff --git a/app/Models/FeedbackChannel.php b/app/Models/FeedbackChannel.php index b2270866..a45abd57 100644 --- a/app/Models/FeedbackChannel.php +++ b/app/Models/FeedbackChannel.php @@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; -#[Fillable(['name', 'slug', 'icon', 'is_active'])] +#[Fillable(['name', 'slug', 'icon', 'color', 'is_active'])] class FeedbackChannel extends Model { protected function casts(): array diff --git a/database/migrations/2026_05_01_000004_add_color_to_feedback_channels_table.php b/database/migrations/2026_05_01_000004_add_color_to_feedback_channels_table.php new file mode 100644 index 00000000..017f2352 --- /dev/null +++ b/database/migrations/2026_05_01_000004_add_color_to_feedback_channels_table.php @@ -0,0 +1,22 @@ +string('color')->nullable()->after('icon'); + }); + } + + public function down(): void + { + Schema::table('feedback_channels', function (Blueprint $table) { + $table->dropColumn('color'); + }); + } +}; diff --git a/database/seeders/AfterSalesSeeder.php b/database/seeders/AfterSalesSeeder.php index e1504638..40052b81 100644 --- a/database/seeders/AfterSalesSeeder.php +++ b/database/seeders/AfterSalesSeeder.php @@ -49,11 +49,11 @@ class AfterSalesSeeder extends Seeder $depPhaply = Department::create(['name' => 'Phòng Pháp lý', 'manager_id' => null]); $channels = [ - ['name' => 'Email', 'slug' => 'email', 'icon' => 'heroicon-o-envelope'], - ['name' => 'Zalo', 'slug' => 'zalo', 'icon' => 'heroicon-o-chat-bubble-left'], - ['name' => 'Phone', 'slug' => 'phone', 'icon' => 'heroicon-o-phone'], - ['name' => 'Document', 'slug' => 'document', 'icon' => 'heroicon-o-document-text'], - ['name' => 'In Person', 'slug' => 'in-person', 'icon' => 'heroicon-o-user'], + ['name' => 'Email', 'slug' => 'email', 'icon' => 'heroicon-o-envelope', 'color' => '#3b82f6'], + ['name' => 'Zalo', 'slug' => 'zalo', 'icon' => 'heroicon-o-chat-bubble-left', 'color' => '#10b981'], + ['name' => 'Phone', 'slug' => 'phone', 'icon' => 'heroicon-o-phone', 'color' => '#f59e0b'], + ['name' => 'Document', 'slug' => 'document', 'icon' => 'heroicon-o-document-text', 'color' => '#8b5cf6'], + ['name' => 'In Person', 'slug' => 'in-person', 'icon' => 'heroicon-o-user', 'color' => '#ec4899'], ]; foreach ($channels as $channel) { diff --git a/public/css/filament-custom.css b/public/css/filament-custom.css index 86e233a7..3f048923 100644 --- a/public/css/filament-custom.css +++ b/public/css/filament-custom.css @@ -488,6 +488,29 @@ select { background-color: var(--crm-surface-container-lowest) !important; } +/* ---------- FIX: Icon sizing ---------- */ +svg.fi-icon, +.fi-icon svg, +.fi-btn svg.fi-icon, +.fi-icon-btn svg, +.fi-input-wrp svg, +.fi-select svg, +.fi-fo-field-wrp svg, +svg[class*="fi-icon"] { + width: 1.25rem !important; + height: 1.25rem !important; + max-width: 1.25rem !important; + max-height: 1.25rem !important; + flex-shrink: 0 !important; +} + +/* Smaller icons in table cells and badges */ +.fi-ta-cell svg.fi-icon, +.fi-badge svg { + width: 1rem !important; + height: 1rem !important; +} + /* ---------- Similar Cases footer panel ---------- */ .fi-footer { margin-top: 2rem;