Skip to content

Commit 0858cef

Browse files
committed
wip
1 parent 745c07d commit 0858cef

33 files changed

+1344
-270
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ RUN apk update && \
1212
#
1313
# production dependencies
1414
apk add --no-cache \
15+
ffmpeg \
1516
nginx && \
1617
#
1718
# install extensions

app/Concerns/Publishable.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Concerns;
6+
7+
use Carbon\Carbon;
8+
use Illuminate\Database\Eloquent\Builder;
9+
10+
trait Publishable
11+
{
12+
public function initializePublishable(): void
13+
{
14+
$this->fillable[] = 'published_at';
15+
16+
$this->casts['published_at'] = 'datetime';
17+
}
18+
19+
public function scopeWithDrafted(Builder $query): Builder
20+
{
21+
return $query->withoutGlobalScope('published');
22+
}
23+
24+
public function scopeOnlyDrafted(Builder $query): Builder
25+
{
26+
return $query
27+
->withDrafted()
28+
->whereNull('published_at');
29+
}
30+
31+
public function scopeOnlyScheduled(Builder $query): Builder
32+
{
33+
return $query
34+
->withDrafted()
35+
->whereNotNull('published_at')
36+
->where('published_at', '>', Carbon::now());
37+
}
38+
39+
public function scopeOnlyPublished(Builder $query): Builder
40+
{
41+
return $query
42+
->whereNotNull('published_at')
43+
->where('published_at', '<=', Carbon::now());
44+
}
45+
46+
public function isDraft(): bool
47+
{
48+
return \is_null($this->published_at);
49+
}
50+
51+
public function isPublished(): bool
52+
{
53+
return ! $this->isDraft() && $this->published_at->isPast();
54+
}
55+
56+
public function isScheduled(): bool
57+
{
58+
return ! $this->isDraft() && $this->published_at->isFuture();
59+
}
60+
61+
/**
62+
* Determine the publish status of the model instance.
63+
*
64+
* @return string
65+
*/
66+
public function status(): string
67+
{
68+
if ($this->isDraft()) {
69+
return 'draft';
70+
}
71+
72+
if ($this->isPublished()) {
73+
return 'published';
74+
}
75+
76+
if ($this->isScheduled()) {
77+
return 'scheduled';
78+
}
79+
}
80+
}

app/Enums/Country.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Enums;
6+
7+
use App\Concerns\Enums\Arrayable;
8+
use App\Concerns\Enums\Comparable;
9+
use App\Concerns\Enums\HasLabel;
10+
11+
enum Country: string
12+
{
13+
use Arrayable;
14+
use Comparable;
15+
use HasLabel;
16+
17+
case EU = 'eu';
18+
case AT = 'at';
19+
case BE = 'be';
20+
case BG = 'bg';
21+
case HR = 'hr';
22+
case CY = 'cy';
23+
case CZ = 'cz';
24+
case DK = 'dk';
25+
case EE = 'ee';
26+
case FI = 'fi';
27+
case FR = 'fr';
28+
case DE = 'de';
29+
case GR = 'gr';
30+
case HU = 'hu';
31+
case IE = 'ie';
32+
case IT = 'it';
33+
case LV = 'lv';
34+
case LT = 'lt';
35+
case LU = 'lu';
36+
case MT = 'mt';
37+
case NL = 'nl';
38+
case PL = 'pl';
39+
case PT = 'pt';
40+
case RO = 'ro';
41+
case SK = 'sk';
42+
case SI = 'si';
43+
case ES = 'es';
44+
case SE = 'se';
45+
46+
protected function labelKeyPrefix(): ?string
47+
{
48+
return 'countries';
49+
}
50+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources;
6+
7+
use App\Filament\Resources\ElectionDayResource\Pages;
8+
use App\Models\ElectionDay;
9+
use Carbon\Carbon;
10+
use Filament\Forms\Components\DatePicker;
11+
use Filament\Forms\Form;
12+
use Filament\Resources\Resource;
13+
use Filament\Tables;
14+
use Filament\Tables\Columns\TextColumn;
15+
use Filament\Tables\Table;
16+
17+
class ElectionDayResource extends Resource
18+
{
19+
protected static ?string $model = ElectionDay::class;
20+
21+
protected static ?string $navigationIcon = 'heroicon-o-calendar-days';
22+
23+
public static function getNavigationGroup(): ?string
24+
{
25+
return __('navigation.group.manage');
26+
}
27+
28+
public static function form(Form $form): Form
29+
{
30+
return $form
31+
->schema([
32+
DatePicker::make('date')
33+
->time(false)
34+
->unique(ignoreRecord:true)
35+
->columnSpanFull(),
36+
]);
37+
}
38+
39+
public static function table(Table $table): Table
40+
{
41+
return $table
42+
->columns([
43+
TextColumn::make('id')
44+
->prefix('#')
45+
->sortable()
46+
->shrink(),
47+
48+
TextColumn::make('date')
49+
->sortable()
50+
->formatStateUsing(fn (Carbon $state) => $state->toDateString()),
51+
])
52+
->filters([
53+
//
54+
])
55+
->actions([
56+
Tables\Actions\EditAction::make(),
57+
])
58+
->bulkActions([
59+
Tables\Actions\BulkActionGroup::make([
60+
Tables\Actions\DeleteBulkAction::make(),
61+
]),
62+
])
63+
->defaultSort('date', 'desc');
64+
}
65+
66+
public static function getRelations(): array
67+
{
68+
return [
69+
//
70+
];
71+
}
72+
73+
public static function getPages(): array
74+
{
75+
return [
76+
'index' => Pages\ManageElectionDays::route('/'),
77+
];
78+
}
79+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\ElectionDayResource\Pages;
6+
7+
use App\Filament\Resources\ElectionDayResource;
8+
use Filament\Actions;
9+
use Filament\Resources\Pages\ListRecords;
10+
11+
class ManageElectionDays extends ListRecords
12+
{
13+
protected static string $resource = ElectionDayResource::class;
14+
15+
protected function getHeaderActions(): array
16+
{
17+
return [
18+
Actions\CreateAction::make(),
19+
];
20+
}
21+
}

app/Filament/Resources/PostResource.php

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,31 @@
44

55
namespace App\Filament\Resources;
66

7+
use App\Enums\Country;
78
use App\Filament\Resources\PostResource\Pages;
9+
use App\Models\ElectionDay;
810
use App\Models\Post;
11+
use Carbon\Carbon;
12+
use Filament\Forms\Components\DateTimePicker;
13+
use Filament\Forms\Components\Repeater;
14+
use Filament\Forms\Components\RichEditor;
15+
use Filament\Forms\Components\Section;
16+
use Filament\Forms\Components\Select;
17+
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
18+
use Filament\Forms\Components\Textarea;
19+
use Filament\Forms\Components\TextInput;
920
use Filament\Forms\Form;
1021
use Filament\Resources\Resource;
1122
use Filament\Tables;
1223
use Filament\Tables\Columns\TextColumn;
24+
use Filament\Tables\Filters\SelectFilter;
1325
use Filament\Tables\Table;
1426

1527
class PostResource extends Resource
1628
{
1729
protected static ?string $model = Post::class;
1830

19-
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
31+
protected static ?string $navigationIcon = 'heroicon-o-document-text';
2032

2133
public static function getNavigationGroup(): ?string
2234
{
@@ -27,20 +39,95 @@ public static function form(Form $form): Form
2739
{
2840
return $form
2941
->schema([
30-
//
42+
Section::make()
43+
->columns(2)
44+
->schema([
45+
TextInput::make('title')
46+
->required()
47+
->maxLength(255),
48+
49+
Select::make('country')
50+
->options(Country::options())
51+
->enum(Country::class),
52+
53+
Select::make('author_id')
54+
->relationship('author', 'name')
55+
->required()
56+
->preload(),
57+
58+
DateTimePicker::make('published_at')
59+
->nullable(),
60+
61+
RichEditor::make('content')
62+
->required()
63+
->columnSpanFull(),
64+
]),
65+
66+
Section::make()
67+
->schema([
68+
SpatieMediaLibraryFileUpload::make('media')
69+
->multiple()
70+
->reorderable()
71+
->previewable(false),
72+
]),
73+
74+
Section::make()
75+
->schema([
76+
Repeater::make('embeds')
77+
->schema([
78+
Textarea::make('html'),
79+
]),
80+
]),
81+
3182
]);
3283
}
3384

3485
public static function table(Table $table): Table
3586
{
3687
return $table
3788
->columns([
89+
TextColumn::make('id')
90+
->prefix('#')
91+
->sortable()
92+
->shrink(),
93+
94+
TextColumn::make('electionDay.date')
95+
->formatStateUsing(fn (?Carbon $state) => $state?->toDateString())
96+
->sortable()
97+
->toggleable(),
98+
3899
TextColumn::make('title')
39100
->searchable()
40101
->sortable(),
102+
103+
TextColumn::make('country')
104+
->badge()
105+
->formatStateUsing(fn (?Country $state) => $state?->label()),
106+
107+
TextColumn::make('author.name')
108+
->sortable()
109+
->toggleable(),
110+
111+
TextColumn::make('published_at')
112+
->formatStateUsing(fn (?Carbon $state) => $state?->toDateTimeString())
113+
->sortable()
114+
->toggleable(),
41115
])
42116
->filters([
43-
//
117+
SelectFilter::make('country')
118+
->options(Country::options())
119+
->multiple(),
120+
121+
SelectFilter::make('author')
122+
->relationship('author', 'name')
123+
->multiple()
124+
->preload(),
125+
126+
SelectFilter::make('electionDay')
127+
->relationship('electionDay', 'date')
128+
->getOptionLabelFromRecordUsing(fn (ElectionDay $record) => $record->date->toDateString())
129+
->multiple()
130+
->preload(),
44131
])
45132
->actions([
46133
Tables\Actions\EditAction::make(),
@@ -49,7 +136,8 @@ public static function table(Table $table): Table
49136
Tables\Actions\BulkActionGroup::make([
50137
Tables\Actions\DeleteBulkAction::make(),
51138
]),
52-
]);
139+
])
140+
->defaultSort('id', 'desc');
53141
}
54142

55143
public static function getRelations(): array

0 commit comments

Comments
 (0)