Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiio committed Aug 19, 2024
1 parent 1d268a7 commit b928aea
Show file tree
Hide file tree
Showing 11 changed files with 386 additions and 62 deletions.
40 changes: 40 additions & 0 deletions app/Concerns/BelongsToElection.php
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);
}
}
196 changes: 196 additions & 0 deletions app/Filament/Resources/ElectionResource.php
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 app/Filament/Resources/ElectionResource/Pages/CreateElection.php
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 app/Filament/Resources/ElectionResource/Pages/EditElection.php
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 app/Filament/Resources/ElectionResource/Pages/ListElections.php
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 app/Filament/Resources/ElectionResource/Pages/ViewElection.php
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;
}
}
32 changes: 32 additions & 0 deletions app/Models/Election.php
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',
];
}
}
29 changes: 29 additions & 0 deletions app/Models/Scopes/BelongsToElectionScope.php
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());
}
}
Loading

0 comments on commit b928aea

Please sign in to comment.