From f4f7262cca4e5c3a1b45c443750621484b0b383e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20Ioni=C8=9B=C4=83?= Date: Thu, 14 Dec 2023 20:01:10 +0000 Subject: [PATCH] wip --- .../Resources/CommunityProfileResource.php | 102 ++++++++++++++++++ .../Pages/EditCommunityProfile.php | 55 ---------- .../Resources/CommunityResource.php | 28 ++--- app/Models/CommunityProfile.php | 15 +++ app/Models/ServicePivot.php | 36 +++++++ app/Tables/Columns/ServiceChipsColumn.php | 32 ++++++ .../factories/CommunityProfileFactory.php | 14 +++ ...023_11_28_124405_create_services_table.php | 4 +- ...144514_create_community_profiles_table.php | 1 + lang/ro/community.php | 32 ++++++ lang/ro/placeholder.php | 2 + .../css/filament/common/tailwind.config.js | 1 + resources/views/components/chip.blade.php | 29 +++++ .../columns/service-chips-column.blade.php | 14 +++ 14 files changed, 297 insertions(+), 68 deletions(-) create mode 100644 app/Models/ServicePivot.php create mode 100644 app/Tables/Columns/ServiceChipsColumn.php create mode 100644 lang/ro/community.php create mode 100644 resources/views/components/chip.blade.php create mode 100644 resources/views/tables/columns/service-chips-column.blade.php diff --git a/app/Filament/Organizations/Resources/CommunityProfileResource.php b/app/Filament/Organizations/Resources/CommunityProfileResource.php index 92dacc64..8c49a47a 100644 --- a/app/Filament/Organizations/Resources/CommunityProfileResource.php +++ b/app/Filament/Organizations/Resources/CommunityProfileResource.php @@ -6,6 +6,17 @@ use App\Filament\Organizations\Resources\CommunityProfileResource\Pages; use App\Models\CommunityProfile; +use App\Models\Service; +use Awcodes\FilamentTableRepeater\Components\TableRepeater; +use Filament\Forms\Components\Group; +use Filament\Forms\Components\Hidden; +use Filament\Forms\Components\RichEditor; +use Filament\Forms\Components\Section; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\SpatieMediaLibraryFileUpload; +use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\Toggle; +use Filament\Forms\Form; use Filament\Resources\Resource; class CommunityProfileResource extends Resource @@ -36,4 +47,95 @@ public static function getPages(): array 'index' => Pages\EditCommunityProfile::route('/'), ]; } + + public static function form(Form $form): Form + { + $services = Service::pluck('name', 'id'); + + return $form + ->schema([ + Section::make() + ->columns(4) + ->schema([ + Group::make() + ->columnSpan(3) + ->schema([ + TextInput::make('name') + ->label(__('community.field.name')) + ->placeholder(__('community.placeholder.name')) + ->maxLength(200) + ->required(), + + TableRepeater::make('services') + ->relationship() + ->reorderable(false) + ->hideLabels() + ->addActionLabel(__('service.action.create')) + ->minItems(1) + ->schema([ + Hidden::make('model_type') + ->default(app(CommunityProfile::class)->getMorphClass()), + + Select::make('service_id') + ->label(__('community.field.service')) + ->options($services) + ->required(), + + Toggle::make('is_visible') + ->label(__('community.field.service_visible')), + + Toggle::make('is_available') + ->label(__('community.field.service_available')), + + ]), + + Select::make('counties') + ->relationship('counties', 'name') + ->label(__('community.field.location')) + ->placeholder(__('community.placeholder.location')) + ->multiple() + ->preload(), + ]), + + RichEditor::make('description') + ->label(__('community.field.description')) + ->placeholder(__('community.placeholder.description')) + ->toolbarButtons([ + 'bold', + 'bulletList', + 'italic', + 'link', + 'orderedList', + 'redo', + 'strike', + 'underline', + 'undo', + ]) + ->columnSpanFull(), + + SpatieMediaLibraryFileUpload::make('logo') + ->label(__('community.field.logo')) + ->helperText(__('community.help.logo')) + ->image() + ->collection('logo') + ->conversion('large') + ->columnSpanFull(), + + TextInput::make('email') + ->label(__('community.field.email')) + ->placeholder(__('placeholder.email')) + ->email(), + + TextInput::make('phone') + ->label(__('community.field.phone')) + ->placeholder(__('placeholder.phone')) + ->tel(), + + TextInput::make('website') + ->label(__('community.field.website')) + ->placeholder(__('placeholder.url')) + ->url(), + ]), + ]); + } } diff --git a/app/Filament/Organizations/Resources/CommunityProfileResource/Pages/EditCommunityProfile.php b/app/Filament/Organizations/Resources/CommunityProfileResource/Pages/EditCommunityProfile.php index 246463cf..3b3445b3 100644 --- a/app/Filament/Organizations/Resources/CommunityProfileResource/Pages/EditCommunityProfile.php +++ b/app/Filament/Organizations/Resources/CommunityProfileResource/Pages/EditCommunityProfile.php @@ -5,11 +5,6 @@ namespace App\Filament\Organizations\Resources\CommunityProfileResource\Pages; use App\Filament\Organizations\Resources\CommunityProfileResource; -use Filament\Forms\Components\RichEditor; -use Filament\Forms\Components\Section; -use Filament\Forms\Components\SpatieMediaLibraryFileUpload; -use Filament\Forms\Components\TextInput; -use Filament\Forms\Form; use Filament\Resources\Pages\EditRecord; class EditCommunityProfile extends EditRecord @@ -26,54 +21,4 @@ public function mount($record = null): void $this->previousUrl = url()->previous(); } - - public function form(Form $form): Form - { - return $form - ->schema([ - Section::make() - ->columns(4) - ->schema([ - TextInput::make('name') - ->label(__('organization.field.name')) - ->maxLength(200) - ->columnSpan(3) - ->required(), - - RichEditor::make('description') - ->label(__('organization.field.description')) - ->toolbarButtons([ - 'bold', - 'bulletList', - 'italic', - 'link', - 'orderedList', - 'redo', - 'strike', - 'underline', - 'undo', - ]) - ->columnSpanFull(), - - SpatieMediaLibraryFileUpload::make('logo') - ->label(__('organization.field.logo')) - ->image() - ->collection('logo') - ->conversion('large') - ->columnSpanFull(), - - TextInput::make('email') - ->label(__('organization.field.email')) - ->email(), - - TextInput::make('phone') - ->label(__('organization.field.phone')) - ->tel(), - - TextInput::make('website') - ->label(__('organization.field.website')) - ->url(), - ]), - ]); - } } diff --git a/app/Filament/Organizations/Resources/CommunityResource.php b/app/Filament/Organizations/Resources/CommunityResource.php index 58294894..a6d3e49f 100644 --- a/app/Filament/Organizations/Resources/CommunityResource.php +++ b/app/Filament/Organizations/Resources/CommunityResource.php @@ -6,6 +6,7 @@ use App\Filament\Organizations\Resources\CommunityResource\Pages; use App\Models\CommunityProfile; +use App\Tables\Columns\ServiceChipsColumn; use Filament\Infolists\Components\Grid; use Filament\Infolists\Components\Section; use Filament\Infolists\Components\SpatieMediaLibraryImageEntry; @@ -21,6 +22,7 @@ use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Str; class CommunityResource extends Resource @@ -29,6 +31,8 @@ class CommunityResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-globe-alt'; + protected static ?string $recordRouteKeyName = 'slug'; + protected static bool $isScopedToTenant = false; protected static ?string $slug = 'community'; @@ -45,16 +49,6 @@ public static function getNavigationLabel(): string return __('navigation.community.network'); } - public static function getModelLabel(): string - { - return __('beneficiary.label.singular'); - } - - public static function getPluralModelLabel(): string - { - return __('beneficiary.label.plural'); - } - public static function infolist(Infolist $infolist): Infolist { return $infolist @@ -113,6 +107,7 @@ public static function infolist(Infolist $infolist): Infolist public static function table(Table $table): Table { return $table + ->modifyQueryUsing(fn (Builder $query) => $query->with('services', 'counties')) ->columns([ Split::make([ Stack::make([ @@ -125,7 +120,7 @@ public static function table(Table $table): Table ->size('text-3xl') ->weight('normal') ->extraAttributes([ - 'class' => 'mt-2.5 mb-6', + 'class' => '-mt-3.5', ]), TextColumn::make('description') @@ -135,7 +130,12 @@ public static function table(Table $table): Table ->stripTags() ->limit(300, '...') ), + + ServiceChipsColumn::make('services'), ]) + ->extraAttributes([ + 'class' => 'flex flex-col gap-6', + ]) ->columnSpan(2), SpatieMediaLibraryImageColumn::make('logo') @@ -150,6 +150,10 @@ public static function table(Table $table): Table ]) ->from('md'), ]) + + ->contentGrid([ + 'default' => 1, + ]) ->filters([ SelectFilter::make('county') ->relationship('counties', 'name') @@ -174,7 +178,7 @@ public static function getPages(): array { return [ 'index' => Pages\ListCommunityProfiles::route('/'), - 'view' => Pages\ViewCommunityProfile::route('/{record}'), + 'view' => Pages\ViewCommunityProfile::route('/{record:slug}'), ]; } } diff --git a/app/Models/CommunityProfile.php b/app/Models/CommunityProfile.php index deda5a23..f62d6640 100644 --- a/app/Models/CommunityProfile.php +++ b/app/Models/CommunityProfile.php @@ -5,9 +5,11 @@ namespace App\Models; use App\Concerns\HasCounties; +use App\Concerns\HasSlug; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; use Spatie\Image\Manipulations; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; @@ -16,10 +18,12 @@ class CommunityProfile extends Model implements HasMedia { use HasCounties; use HasFactory; + use HasSlug; use InteractsWithMedia; protected $fillable = [ 'name', + 'slug', 'description', 'email', 'phone', @@ -31,6 +35,12 @@ public function organization(): BelongsTo return $this->belongsTo(Organization::class); } + public function services(): HasMany + { + return $this->hasMany(ServicePivot::class, 'model_id') + ->where('model_type', $this->getMorphClass()); + } + public function registerMediaCollections(): void { $this->addMediaCollection('logo') @@ -41,4 +51,9 @@ public function registerMediaCollections(): void ->optimize(); }); } + + protected function getSlugSource(): string + { + return $this->name; + } } diff --git a/app/Models/ServicePivot.php b/app/Models/ServicePivot.php new file mode 100644 index 00000000..65074790 --- /dev/null +++ b/app/Models/ServicePivot.php @@ -0,0 +1,36 @@ + 'boolean', + 'is_available' => 'boolean', + ]; + + protected $with = [ + 'service', + ]; + + public function service(): BelongsTo + { + return $this->belongsTo(Service::class); + } +} diff --git a/app/Tables/Columns/ServiceChipsColumn.php b/app/Tables/Columns/ServiceChipsColumn.php new file mode 100644 index 00000000..67024ce0 --- /dev/null +++ b/app/Tables/Columns/ServiceChipsColumn.php @@ -0,0 +1,32 @@ +size = $size; + + return $this; + } + + public function getSize(mixed $state): string | null + { + return $this->evaluate($this->size, [ + 'state' => $state, + ]); + } +} diff --git a/database/factories/CommunityProfileFactory.php b/database/factories/CommunityProfileFactory.php index 2ab53820..fafe6fa6 100644 --- a/database/factories/CommunityProfileFactory.php +++ b/database/factories/CommunityProfileFactory.php @@ -6,6 +6,7 @@ use App\Models\CommunityProfile; use App\Models\County; +use App\Models\Service; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -41,6 +42,19 @@ public function configure(): static ->take(fake()->numberBetween(1, 3)) ->get() ); + + $communityProfile->services()->createMany( + Service::query() + ->inRandomOrder() + ->take(fake()->numberBetween(1, 3)) + ->get() + ->map(fn (Service $service) => [ + 'model_type' => $communityProfile->getMorphClass(), + 'service_id' => $service->id, + 'is_visible' => fake()->boolean(), + 'is_available' => fake()->boolean(), + ]) + ); }); } } diff --git a/database/migrations/2023_11_28_124405_create_services_table.php b/database/migrations/2023_11_28_124405_create_services_table.php index 65bcf249..5a0f8b24 100644 --- a/database/migrations/2023_11_28_124405_create_services_table.php +++ b/database/migrations/2023_11_28_124405_create_services_table.php @@ -18,10 +18,12 @@ public function up(): void $table->text('description')->nullable(); }); - Schema::create('model_has_service', function (Blueprint $table) { + Schema::create('model_has_services', function (Blueprint $table) { $table->id(); $table->morphs('model'); $table->foreignIdFor(Service::class)->constrained()->cascadeOnDelete(); + $table->boolean('is_visible')->default(false); + $table->boolean('is_available')->default(false); }); } }; diff --git a/database/migrations/2023_11_29_144514_create_community_profiles_table.php b/database/migrations/2023_11_29_144514_create_community_profiles_table.php index fc8b99e1..d5b4b353 100644 --- a/database/migrations/2023_11_29_144514_create_community_profiles_table.php +++ b/database/migrations/2023_11_29_144514_create_community_profiles_table.php @@ -15,6 +15,7 @@ public function up(): void $table->id(); $table->timestamps(); $table->string('name'); + $table->string('slug')->unique(); $table->text('description')->nullable(); $table->string('email')->nullable(); $table->string('phone')->nullable(); diff --git a/lang/ro/community.php b/lang/ro/community.php new file mode 100644 index 00000000..fe337da1 --- /dev/null +++ b/lang/ro/community.php @@ -0,0 +1,32 @@ + [ + 'name' => 'Numele organizației', + 'services' => 'Serviciile oferite', + 'location' => 'Locație', + 'description' => 'Descrierea organizației', + 'logo' => 'Logo sau imagine', + 'email' => 'Adresă de email', + 'phone' => 'Număr de telefon', + 'website' => 'Website', + 'service' => 'Serviciul', + 'service_visible' => 'Vizibil în profilul meu în rețea', + 'service_available' => 'Disponibil', + ], + + 'placeholder' => [ + 'name' => 'Introdu numele care va fi afișat pe profil', + 'services' => 'Alege toate tipurile de servicii oferite', + 'location' => 'Județul sau județele unde activează organizația', + 'description' => 'Descrie profilul organizației și adaugă orice detalii relevante despre serviciile oferite', + ], + + 'help' => [ + 'logo' => 'Încarcă logo-ul organizației sau o imagine ilustrativă, care să poată fi afișată lângă descrierea organizației.', + ], + +]; diff --git a/lang/ro/placeholder.php b/lang/ro/placeholder.php index 36e8b384..2d9a6d95 100644 --- a/lang/ro/placeholder.php +++ b/lang/ro/placeholder.php @@ -29,6 +29,8 @@ 'phone_or_email' => 'Introdu un număr de telefon sau email', 'studies' => 'Alege cel mai înalt nivel absolvit', 'workplace' => 'Introdu detalii privind locația și angajatorul (sau unitatea de învățământ)', + 'email' => 'Introdu adresa de email', + 'url' => 'URL', // 'accreditation_number' => 'Introdu seria și numărul', // 'activity' => 'Introdu activitatea', diff --git a/resources/css/filament/common/tailwind.config.js b/resources/css/filament/common/tailwind.config.js index 60c4d87b..19d2a4cf 100644 --- a/resources/css/filament/common/tailwind.config.js +++ b/resources/css/filament/common/tailwind.config.js @@ -5,6 +5,7 @@ export default { content: [ './app/Filament/**/*.php', './resources/views/filament/**/*.blade.php', + './resources/views/**/*.blade.php', './vendor/filament/**/*.blade.php', './vendor/awcodes/filament-table-repeater/resources/**/*.blade.php' ], diff --git a/resources/views/components/chip.blade.php b/resources/views/components/chip.blade.php new file mode 100644 index 00000000..1304d764 --- /dev/null +++ b/resources/views/components/chip.blade.php @@ -0,0 +1,29 @@ +@props([ + 'color' => 'primary', + 'disabled' => false, +]) + +
class([ + 'px-3 py-1 ring-1', + 'flex items-center justify-start rounded-full', + 'text-xs font-medium text-center', + 'opacity-50' => $disabled, + 'bg-gray-50 text-gray-600 ring-gray-600 dark:bg-gray-400/10 dark:text-gray-400 dark:ring-gray-400' => $disabled, + 'bg-custom-50 text-custom-600 ring-custom-600 dark:bg-custom-400/10 dark:text-custom-400 dark:ring-custom-400' => !$disabled, + ]) + ->style([ + \Filament\Support\get_color_css_variables( + $color, + shades: [ + 50, + 400, + 600, + ], + alias: 'badge', + ) => $color !== 'gray', + ]) + }}> + {{ $slot }} +
diff --git a/resources/views/tables/columns/service-chips-column.blade.php b/resources/views/tables/columns/service-chips-column.blade.php new file mode 100644 index 00000000..e4336908 --- /dev/null +++ b/resources/views/tables/columns/service-chips-column.blade.php @@ -0,0 +1,14 @@ +@php + $services = $getState()->filter(fn($service) => $service->is_visible); +@endphp + +
merge($getExtraAttributes(), escape: false)->class('flex flex-wrap gap-2') }}> + @foreach ($services as $service) + + {{ $service->service->name }} + + @endforeach +