A reply starts from a template filled in the language the person wrote in, is sent by the application when it has a mailer that delivers or handed to the replier's mail program otherwise, and is recorded on the submission. The same is available through the API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
141 lines
6.1 KiB
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(),
|
|
]),
|
|
]);
|
|
}
|
|
}
|