Files
landing-api/app/Filament/Resources/Applications/Schemas/ApplicationInfolist.php

141 lines
6.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Resources\Applications\Schemas;
use App\Models\Application;
use App\Models\ApplicationReply;
use Filament\Infolists\Components\KeyValueEntry;
use Filament\Infolists\Components\RepeatableEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
/**
* A submission is read, not edited: everything above the divider was written
* by somebody else and must stay exactly as they sent it. Only the notes and
* the status below belong to the collective.
*/
class ApplicationInfolist
{
public static function configure(Schema $schema): Schema
{
return $schema->components([
Section::make(__('panel.applications.sections.message'))
->columns(3)
->schema([
TextEntry::make('name')
->label(__('panel.applications.fields.name'))
->weight('bold'),
TextEntry::make('email')
->label(__('panel.applications.fields.email'))
->copyable()
// The reply is the whole point of the record, so it is
// one click away rather than a copy-paste.
->url(fn (Application $record) => 'mailto:'.$record->email),
TextEntry::make('organisation')
->label(__('panel.applications.fields.organisation'))
->placeholder('—'),
TextEntry::make('kind')
->label(__('panel.applications.fields.kind'))
->badge(),
TextEntry::make('call_title')
->label(__('panel.applications.fields.subject'))
->state(fn (Application $record) => $record->subject()),
TextEntry::make('hours_per_week')
->label(__('panel.applications.fields.hours_per_week'))
->formatStateUsing(fn (?int $state) => $state ? "{$state} h" : '—')
// The number to compare against the call's own ask.
->helperText(fn (Application $record) => $record->call?->hours_per_week
? __('panel.applications.fields.hours_asked', [
'hours' => $record->call->hours_per_week,
])
: null),
TextEntry::make('message')
->label(__('panel.applications.fields.message'))
->prose()
->columnSpanFull(),
KeyValueEntry::make('links')
->label(__('panel.applications.fields.links'))
->keyLabel(__('panel.applications.fields.link_name'))
->valueLabel(__('panel.applications.fields.link_url'))
->columnSpanFull()
->visible(fn (Application $record) => filled($record->links)),
]),
// What was already said, so the next person to open this does not
// say it again.
Section::make(__('panel.replies.history'))
->visible(fn (Application $record) => $record->replies()->exists())
->schema([
RepeatableEntry::make('replies')
->hiddenLabel()
->schema([
TextEntry::make('subject')
->hiddenLabel()
->weight('bold'),
TextEntry::make('created_at')
->hiddenLabel()
->state(fn (ApplicationReply $record) => __('panel.replies.by', [
'name' => $record->user_name ?? '—',
'when' => $record->created_at?->isoFormat('LLL'),
]).' · '.__("panel.replies.channels.{$record->channel}"))
->color('gray'),
TextEntry::make('body')
->hiddenLabel()
->prose()
->formatStateUsing(fn (string $state) => nl2br(e($state)))
->html()
->columnSpanFull(),
])
->columns(2),
]),
Section::make(__('panel.applications.sections.internal'))
->description(__('panel.applications.sections.internal_hint'))
->columns(4)
->schema([
TextEntry::make('status')
->label(__('panel.applications.fields.status'))
->badge(),
TextEntry::make('created_at')
->label(__('panel.applications.fields.received_at'))
->dateTime(),
TextEntry::make('handler.name')
->label(__('panel.applications.fields.handled_by'))
->placeholder('—'),
TextEntry::make('handled_at')
->label(__('panel.applications.fields.handled_at'))
->dateTime()
->placeholder('—'),
TextEntry::make('locale')
->label(__('panel.applications.fields.locale'))
->badge()
->color('gray')
// Reply in the language they wrote in.
->formatStateUsing(fn (string $state) => config("locales.supported.{$state}.native", $state)),
TextEntry::make('notes')
->label(__('panel.applications.fields.notes'))
->prose()
->placeholder(__('panel.applications.fields.notes_empty'))
->columnSpanFull(),
]),
]);
}
}