-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
386 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Concerns; | ||
|
||
use App\Models\Election; | ||
use App\Models\Scopes\BelongsToElectionScope; | ||
use Filament\Facades\Filament; | ||
use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||
|
||
trait BelongsToElection | ||
{ | ||
public function initializeBelongsToElection(): void | ||
{ | ||
// | ||
} | ||
|
||
protected static function bootBelongsToElection(): void | ||
{ | ||
static::creating(function (self $model) { | ||
if (! Filament::auth()->check()) { | ||
return; | ||
} | ||
|
||
if (! Filament::hasTenancy()) { | ||
return; | ||
} | ||
|
||
$model->election()->associate(Filament::getTenant()); | ||
}); | ||
|
||
static::addGlobalScope(new BelongsToElectionScope); | ||
} | ||
|
||
public function election(): BelongsTo | ||
{ | ||
return $this->belongsTo(Election::class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Resources; | ||
|
||
use App\Filament\Resources\ElectionResource\Pages; | ||
use App\Models\Election; | ||
use Filament\Forms; | ||
use Filament\Forms\Components\Select; | ||
use Filament\Forms\Components\TextInput; | ||
use Filament\Forms\Components\Toggle; | ||
use Filament\Forms\Form; | ||
use Filament\Infolists; | ||
use Filament\Infolists\Components\IconEntry; | ||
use Filament\Infolists\Components\TextEntry; | ||
use Filament\Infolists\Infolist; | ||
use Filament\Pages\SubNavigationPosition; | ||
use Filament\Resources\Pages\EditRecord; | ||
use Filament\Resources\Pages\Page; | ||
use Filament\Resources\Resource; | ||
use Filament\Tables; | ||
use Filament\Tables\Columns\IconColumn; | ||
use Filament\Tables\Columns\TextColumn; | ||
use Filament\Tables\Enums\FiltersLayout; | ||
use Filament\Tables\Filters\SelectFilter; | ||
use Filament\Tables\Table; | ||
|
||
class ElectionResource extends Resource | ||
{ | ||
protected static ?string $model = Election::class; | ||
|
||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; | ||
|
||
protected static ?int $navigationSort = 21; | ||
|
||
protected static SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top; | ||
|
||
public static function getNavigationGroup(): ?string | ||
{ | ||
return __('admin.navigation.elections'); | ||
} | ||
|
||
public static function getModelLabel(): string | ||
{ | ||
return __('app.election.label.singular'); | ||
} | ||
|
||
public static function getPluralModelLabel(): string | ||
{ | ||
return __('app.election.label.plural'); | ||
} | ||
|
||
public static function form(Form $form): Form | ||
{ | ||
return $form | ||
->schema([ | ||
Forms\Components\Section::make() | ||
->schema([ | ||
Select::make('type') | ||
->label(__('admin.field.type')) | ||
->relationship('type', 'name') | ||
->required(), | ||
|
||
TextInput::make('title') | ||
->label(__('admin.field.title')) | ||
->required(), | ||
|
||
TextInput::make('subtitle') | ||
->label(__('admin.field.subtitle')) | ||
->nullable(), | ||
|
||
/* | ||
* @see https://dev.mysql.com/doc/refman/8.4/en/year.html Documentation for the YEAR data type | ||
*/ | ||
TextInput::make('year') | ||
->label(__('admin.field.year')) | ||
->minValue(1901) | ||
->maxValue(2155) | ||
->numeric() | ||
->default(today()->year) | ||
->required(), | ||
|
||
Toggle::make('is_live') | ||
->label(__('admin.field.is_live')) | ||
->default(false), | ||
|
||
]), | ||
]); | ||
} | ||
|
||
public static function infolist(Infolist $infolist): Infolist | ||
{ | ||
return $infolist | ||
->columns(3) | ||
->schema([ | ||
Infolists\Components\Section::make() | ||
->columnSpan(2) | ||
->columns(2) | ||
->schema([ | ||
TextEntry::make('title') | ||
->label(__('admin.field.title')), | ||
|
||
TextEntry::make('subtitle') | ||
->label(__('admin.field.subtitle')), | ||
|
||
TextEntry::make('year') | ||
->label(__('admin.field.year')), | ||
|
||
IconEntry::make('is_live') | ||
->label(__('admin.field.is_live')) | ||
->boolean(), | ||
]), | ||
|
||
Infolists\Components\Section::make() | ||
->columnSpan(1) | ||
->schema([ | ||
TextEntry::make('created_at') | ||
->label(__('admin.field.created_at')) | ||
->dateTime(), | ||
|
||
TextEntry::make('updated_at') | ||
->label(__('admin.field.updated_at')) | ||
->dateTime(), | ||
]), | ||
|
||
]); | ||
} | ||
|
||
public static function table(Table $table): Table | ||
{ | ||
return $table | ||
->columns([ | ||
TextColumn::make('id') | ||
->label(__('admin.field.id')) | ||
->sortable() | ||
->shrink(), | ||
|
||
TextColumn::make('type.name') | ||
->label(__('admin.field.type')) | ||
->sortable(), | ||
|
||
TextColumn::make('title') | ||
->label(__('admin.field.title')) | ||
->searchable() | ||
->sortable() | ||
->description(fn (Election $record) => $record->subtitle), | ||
|
||
TextColumn::make('year') | ||
->label(__('admin.field.year')) | ||
->sortable(), | ||
|
||
IconColumn::make('is_live') | ||
->label(__('admin.field.is_live')) | ||
->boolean(), | ||
]) | ||
->filters([ | ||
SelectFilter::make('type') | ||
->label(__('admin.field.type')) | ||
->relationship('type', 'name'), | ||
]) | ||
->filtersLayout(FiltersLayout::AboveContent) | ||
->actions([ | ||
Tables\Actions\ViewAction::make() | ||
->iconButton(), | ||
|
||
Tables\Actions\EditAction::make() | ||
->iconButton(), | ||
]) | ||
->defaultSort('id', 'desc'); | ||
} | ||
|
||
public static function getRecordSubNavigation(Page $page): array | ||
{ | ||
return []; | ||
if ($page instanceof EditRecord) { | ||
return []; | ||
} | ||
|
||
return $page->generateNavigationItems([ | ||
Pages\ViewElection::class, | ||
Pages\EditElection::class, | ||
// Pages\ElectionRounds\ManageElectionRounds::class, | ||
]); | ||
} | ||
|
||
public static function getPages(): array | ||
{ | ||
return [ | ||
'index' => Pages\ListElections::route('/'), | ||
'create' => Pages\CreateElection::route('/create'), | ||
'view' => Pages\ViewElection::route('/{record}'), | ||
'edit' => Pages\EditElection::route('/{record}/edit'), | ||
]; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
app/Filament/Resources/ElectionResource/Pages/CreateElection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Resources\ElectionResource\Pages; | ||
|
||
use App\Filament\Resources\ElectionResource; | ||
use Filament\Resources\Pages\CreateRecord; | ||
|
||
class CreateElection extends CreateRecord | ||
{ | ||
protected static string $resource = ElectionResource::class; | ||
} |
21 changes: 21 additions & 0 deletions
21
app/Filament/Resources/ElectionResource/Pages/EditElection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Resources\ElectionResource\Pages; | ||
|
||
use App\Filament\Resources\ElectionResource; | ||
use Filament\Actions; | ||
use Filament\Resources\Pages\EditRecord; | ||
|
||
class EditElection extends EditRecord | ||
{ | ||
protected static string $resource = ElectionResource::class; | ||
|
||
protected function getHeaderActions(): array | ||
{ | ||
return [ | ||
Actions\DeleteAction::make(), | ||
]; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
app/Filament/Resources/ElectionResource/Pages/ListElections.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Resources\ElectionResource\Pages; | ||
|
||
use App\Filament\Resources\ElectionResource; | ||
use Filament\Actions; | ||
use Filament\Resources\Pages\ListRecords; | ||
|
||
class ListElections extends ListRecords | ||
{ | ||
protected static string $resource = ElectionResource::class; | ||
|
||
protected function getHeaderActions(): array | ||
{ | ||
return [ | ||
Actions\CreateAction::make(), | ||
]; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
app/Filament/Resources/ElectionResource/Pages/ViewElection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Resources\ElectionResource\Pages; | ||
|
||
use App\Filament\Resources\ElectionResource; | ||
use Filament\Actions; | ||
use Filament\Resources\Pages\ViewRecord; | ||
|
||
class ViewElection extends ViewRecord | ||
{ | ||
protected static string $resource = ElectionResource::class; | ||
|
||
protected function getHeaderActions(): array | ||
{ | ||
return [ | ||
Actions\EditAction::make(), | ||
]; | ||
} | ||
|
||
public function getTitle(): string | ||
{ | ||
return $this->getRecord()->title; | ||
} | ||
|
||
public function getSubheading(): ?string | ||
{ | ||
return $this->getRecord()->subtitle; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Models; | ||
|
||
use Database\Factories\ElectionFactory; | ||
use Illuminate\Database\Eloquent\Factories\HasFactory; | ||
use Illuminate\Database\Eloquent\Model; | ||
|
||
class Election extends Model | ||
{ | ||
/** @use HasFactory<ElectionFactory> */ | ||
use HasFactory; | ||
|
||
protected static string $factory = ElectionFactory::class; | ||
|
||
protected $fillable = [ | ||
'title', | ||
'subtitle', | ||
'year', | ||
'is_live', | ||
]; | ||
|
||
protected function casts(): array | ||
{ | ||
return [ | ||
'year' => 'int', | ||
'is_live' => 'boolean', | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Models\Scopes; | ||
|
||
use Filament\Facades\Filament; | ||
use Illuminate\Database\Eloquent\Builder; | ||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Database\Eloquent\Scope; | ||
|
||
class BelongsToElectionScope implements Scope | ||
{ | ||
/** | ||
* Apply the scope to a given Eloquent query builder. | ||
*/ | ||
public function apply(Builder $builder, Model $model): void | ||
{ | ||
if (! Filament::auth()->check()) { | ||
return; | ||
} | ||
|
||
if (! Filament::hasTenancy()) { | ||
return; | ||
} | ||
|
||
$builder->whereBelongsTo(Filament::getTenant()); | ||
} | ||
} |
Oops, something went wrong.