Skip to content

Commit

Permalink
Merge pull request #202 from code4romania/155-super-admin-implement-a…
Browse files Browse the repository at this point in the history
…dd-organization-flow

Add institutions
  • Loading branch information
gheorghelupu17 authored Nov 1, 2024
2 parents ca814d0 + 79858a9 commit e80492c
Show file tree
Hide file tree
Showing 41 changed files with 1,701 additions and 41 deletions.
10 changes: 10 additions & 0 deletions app/Concerns/HasUserStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public function isPending(): bool
return UserStatus::isValue($this->status, UserStatus::PENDING);
}

public function isInactive(): bool
{
return UserStatus::isValue($this->status, UserStatus::INACTIVE);
}

public function setPendingStatus(): void
{
$this->update(['status' => UserStatus::PENDING]);
Expand All @@ -27,4 +32,9 @@ public function deactivate(): void
{
$this->update(['status' => UserStatus::INACTIVE]);
}

public function activate(): void
{
$this->update(['status' => UserStatus::ACTIVE]);
}
}
37 changes: 37 additions & 0 deletions app/Enums/InstitutionStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace App\Enums;

use App\Concerns\Enums\Arrayable;
use App\Concerns\Enums\Comparable;
use App\Concerns\Enums\HasLabel as HasLabelTrait;
use Filament\Support\Colors\Color;
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasLabel;

enum InstitutionStatus: string implements HasLabel, HasColor
{
use Arrayable;
use Comparable;
use HasLabelTrait;

case ACTIVE = 'active';
case INACTIVE = 'inactive';
case PENDING = 'pending';

protected function labelKeyPrefix(): ?string
{
return 'enum.institution_status';
}

public function getColor(): string|array|null
{
return match ($this) {
self::ACTIVE => Color::Green,
self::INACTIVE => Color::Red,
self::PENDING => Color::Yellow,
};
}
}
83 changes: 83 additions & 0 deletions app/Filament/Admin/Resources/InstitutionResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace App\Filament\Admin\Resources;

use App\Filament\Admin\Resources\InstitutionResource\Pages;
use App\Filament\Admin\Resources\UserInstitutionResource\Pages\EditUserInstitution;
use App\Filament\Admin\Resources\UserInstitutionResource\Pages\ViewUserInstitution;
use App\Models\Institution;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

class InstitutionResource extends Resource
{
protected static ?string $model = Institution::class;

protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

public static function form(Form $form): Form
{
return $form
->schema([
//
]);
}

public static function table(Table $table): Table
{
return $table
->modifyQueryUsing(
fn (Builder $query) => $query
->withCount(['organizations', 'beneficiaries', 'users'])
->with(['county', 'city'])
)
->columns([
TextColumn::make('name')
->label(__('institution.headings.institution_name')),

TextColumn::make('county_and_city')
->label(__('institution.headings.registered_office')),

TextColumn::make('organizations_count')
->label(__('institution.headings.centers')),

TextColumn::make('beneficiaries_count')
->label(__('institution.headings.cases')),

TextColumn::make('users_count')
->label(__('institution.headings.specialists')),

TextColumn::make('status')
->label(__('institution.headings.status')),
])
->filters([
//
])
->actions([
ViewAction::make()
->label(__('general.action.view_details')),
])
->emptyStateIcon('heroicon-o-clipboard-document-list')
->emptyStateHeading(__('institution.headings.empty_state'))
->emptyStateDescription(null);
}

public static function getPages(): array
{
return [
'index' => Pages\ListInstitutions::route('/'),
'create' => Pages\CreateInstitution::route('/create'),
'view' => Pages\ViewInstitution::route('/{record}'),
'edit_institution_details' => Pages\EditInstitutionDetails::route('/{record}/editInstitutionDetails'),
'edit_institution_centers' => Pages\EditInstitutionCenters::route('/{record}/editCenters'),
'user.view' => ViewUserInstitution::route('{parent}/user/{record}'),
'user.edit' => EditUserInstitution::route('{parent}/user/{record}/edit'),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace App\Filament\Admin\Resources\InstitutionResource\Actions;

use App\Models\Institution;
use Filament\Actions\Action;

class ActivateInstitution extends Action
{
protected function setUp(): void
{
parent::setUp();

$this->name('activate_institution');
$this->label(__('institution.actions.activate'));
$this->icon('heroicon-s-arrow-path');
$this->color('success');
$this->outlined();
$this->visible(fn (Institution $record) => $record->isInactivated());
$this->action(fn (Institution $record) => $record->activate());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace App\Filament\Admin\Resources\InstitutionResource\Actions;

use App\Models\Institution;
use Filament\Actions\Action;

class InactivateInstitution extends Action
{
protected function setUp(): void
{
parent::setUp();

$this->name('inactivate_institution');
$this->label(__('institution.actions.inactivate'));
$this->icon('heroicon-o-user-minus');
$this->color('danger');
$this->outlined();
$this->visible(fn (Institution $record) => $record->isActivated());
$this->modalHeading(__('institution.headings.inactivate'));
$this->modalDescription(__('institution.labels.inactivate'));
$this->modalSubmitActionLabel(__('institution.actions.inactivate'));
$this->action(fn (Institution $record) => $record->inactivate());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace App\Filament\Admin\Resources\InstitutionResource\Pages;

use App\Filament\Admin\Resources\InstitutionResource;
use App\Filament\Admin\Resources\UserInstitutionResource\Pages\EditUserInstitution;
use App\Forms\Components\Repeater;
use App\Models\Organization;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Wizard\Step;
use Filament\Resources\Pages\Concerns\HasWizard;
use Filament\Resources\Pages\CreateRecord;

class CreateInstitution extends CreateRecord
{
use HasWizard;

protected static string $resource = InstitutionResource::class;

public function getSteps(): array
{
return [
Step::make(__('institution.headings.institution_details'))
->schema(EditInstitutionDetails::getSchema()),

Step::make(__('institution.headings.center_details'))
->schema([
Placeholder::make('center_details')
->hiddenLabel()
->maxWidth('3xl')
->content(__('institution.placeholders.center_details')),

...EditInstitutionCenters::getSchema(),
]),

Step::make(__('institution.headings.ngo_admin'))
->schema([
Placeholder::make('ngo_admins')
->hiddenLabel()
->maxWidth('3xl')
->content(__('institution.placeholders.ngo_admins')),

Repeater::make('admins')
->maxWidth('3xl')
->hiddenLabel()
->columns()
->minItems(1)
->relationship('admins')
->addActionLabel(__('institution.actions.add_admin'))
->schema([
...EditUserInstitution::getSchema(),

Hidden::make('ngo_admin')
->default(1),
]),
]),
];
}

public function afterCreate()
{
$record = $this->getRecord();
$admins = $record->admins;
$organizations = $record->organizations;

$organizations->each(fn (Organization $organization) => $organization->users()->attach($admins->pluck('id')));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

namespace App\Filament\Admin\Resources\InstitutionResource\Pages;

use App\Filament\Admin\Resources\InstitutionResource;
use App\Forms\Components\Repeater;
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Contracts\Support\Htmlable;

class EditInstitutionCenters extends EditRecord
{
protected static string $resource = InstitutionResource::class;

protected function getRedirectUrl(): ?string
{
return self::$resource::getUrl('view', [
'record' => $this->getRecord(),
'activeRelationManager' => 'organizations',
]);
}

public function getBreadcrumbs(): array
{
return [
InstitutionResource::getUrl() => __('institution.headings.list_title'),
InstitutionResource::getUrl('view', ['record' => $this->getRecord()]) => $this->getRecord()->name,
];
}

public function getTitle(): string|Htmlable
{
return $this->getRecord()->name;
}

public function form(Form $form): Form
{
return $form->schema(self::getSchema());
}

public static function getSchema(): array
{
return [
Repeater::make('organizations')
->maxWidth('3xl')
->hiddenLabel()
->columns()
->minItems(1)
->relationship('organizations')
->addActionLabel(__('institution.actions.add_organization'))
->schema([
TextInput::make('name')
->label(__('institution.labels.center_name')),

TextInput::make('short_name')
->label(__('organization.field.short_name')),

TextInput::make('main_activity')
->label(__('organization.field.main_activity'))
->columnSpanFull(),

SpatieMediaLibraryFileUpload::make('social_service_licensing_certificate')
->label(__('institution.labels.social_service_licensing_certificate'))
->helperText(__('institution.helper_texts.social_service_licensing_certificate'))
->collection('social_service_licensing_certificate')
->columnSpanFull(),

SpatieMediaLibraryFileUpload::make('logo')
->label(__('institution.labels.logo_center'))
->helperText(__('institution.helper_texts.logo'))
->collection('logo')
->columnSpanFull(),

SpatieMediaLibraryFileUpload::make('organization_header')
->label(__('institution.labels.organization_header'))
->helperText(__('institution.helper_texts.organization_header'))
->collection('organization_header')
->columnSpanFull(),
]),
];
}
}
Loading

0 comments on commit e80492c

Please sign in to comment.