Initial commit: Pireon Admin — headless admin panel and public API
Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
121
app/Filament/Resources/Members/Schemas/MemberForm.php
Normal file
121
app/Filament/Resources/Members/Schemas/MemberForm.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Resources\Members\Schemas;
|
||||
|
||||
use App\Filament\Support\TranslatableTabs;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class MemberForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Section::make()
|
||||
->columns(2)
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label(__('panel.members.fields.name'))
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->live(onBlur: true)
|
||||
->afterStateUpdated(function (?string $state, callable $get, callable $set) {
|
||||
if (blank($get('slug'))) {
|
||||
$set('slug', Str::slug((string) $state));
|
||||
}
|
||||
}),
|
||||
|
||||
TextInput::make('slug')
|
||||
->label(__('panel.members.fields.slug'))
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->rules(fn ($record) => [Rule::unique('members', 'slug')->ignore($record?->id)]),
|
||||
|
||||
FileUpload::make('avatar')
|
||||
->label(__('panel.members.fields.avatar'))
|
||||
->image()
|
||||
->avatar()
|
||||
// Explicit: the default disk is private, and the
|
||||
// frontend runs on another host.
|
||||
->disk(config('media.disk'))
|
||||
->directory('members')
|
||||
->imageEditor()
|
||||
// A portrait is described by the person's name, so
|
||||
// there is no alt field here to fill in wrong.
|
||||
->helperText(__('panel.members.fields.avatar_hint')),
|
||||
|
||||
// The link that makes commit attribution and the git
|
||||
// integration line up with a real person.
|
||||
TextInput::make('github_username')
|
||||
->label(__('panel.members.fields.github_username'))
|
||||
->prefix('github.com/')
|
||||
->maxLength(120),
|
||||
|
||||
Select::make('user_id')
|
||||
->label(__('panel.members.fields.user'))
|
||||
->relationship('user', 'name')
|
||||
->searchable()
|
||||
->preload()
|
||||
->helperText(__('panel.members.fields.user_hint')),
|
||||
|
||||
Select::make('technologies')
|
||||
->label(__('panel.members.fields.technologies'))
|
||||
->relationship('technologies', 'name')
|
||||
->multiple()
|
||||
->preload()
|
||||
->searchable(),
|
||||
]),
|
||||
|
||||
Section::make(__('panel.members.sections.profile'))
|
||||
->description(__('panel.members.sections.profile_hint'))
|
||||
->schema([
|
||||
TranslatableTabs::make(fn (string $locale, bool $isDefault) => [
|
||||
TextInput::make("headline.{$locale}")
|
||||
->label(__('panel.members.fields.headline'))
|
||||
->maxLength(255)
|
||||
->columnSpanFull(),
|
||||
|
||||
Textarea::make("bio.{$locale}")
|
||||
->label(__('panel.members.fields.bio'))
|
||||
->rows(5)
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
]),
|
||||
|
||||
Section::make(__('panel.members.sections.membership'))
|
||||
->columns(3)
|
||||
->schema([
|
||||
Toggle::make('is_public')
|
||||
->label(__('panel.members.fields.is_public'))
|
||||
->default(true),
|
||||
|
||||
Toggle::make('is_founder')
|
||||
->label(__('panel.members.fields.is_founder')),
|
||||
|
||||
TextInput::make('position')
|
||||
->label(__('panel.members.fields.position'))
|
||||
->numeric()
|
||||
->default(0),
|
||||
|
||||
DatePicker::make('joined_at')
|
||||
->label(__('panel.members.fields.joined_at')),
|
||||
|
||||
// Leaving hides them from the current roster without
|
||||
// erasing the work they did.
|
||||
DatePicker::make('left_at')
|
||||
->label(__('panel.members.fields.left_at'))
|
||||
->helperText(__('panel.members.fields.left_at_hint')),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user