Add Validation for contribution form

This commit is contained in:
philipp lang 2025-03-28 15:53:17 +01:00
parent d6a1de8fb9
commit 6806e54209
2 changed files with 126 additions and 0 deletions
modules/Contribution/Components

View File

@ -2,14 +2,126 @@
namespace Modules\Contribution\Components;
use App\Contribution\ContributionFactory;
use App\Country;
use Illuminate\Support\Collection;
use App\Member\Member;
use Livewire\Attributes\Validate;
use Livewire\Component;
class FillList extends Component
{
#[Validate(rule: 'required|string|max:255', as: 'Veranstaltungs-Name')]
public string $eventName = '';
#[Validate(rule: 'required|date', as: 'Datum von')]
public Carbon $dateFrom;
#[Validate(rule: 'required|date', as: 'Datum bis')]
public Carbon $dateUntil;
#[Validate(rule: 'required|integer|gt:0', as: 'Land')]
public int $country;
#[Validate(rule: 'array|min:1', as: 'Mitglieder')]
public $members = [];
#[Validate(rule: 'required', as: 'Formular')]
public string $compiler;
#[Validate(rule: 'required', as: 'PLZ / Ort')]
public string $zipLocation;
public Collection $countries;
public string $search = '';
public Collection $compilers;
public Collection $memberResults;
public function rules(): array
{
return [
'eventName' => 'required|string|max:255',
];
}
public function mount(): void
{
$this->compilers = app(ContributionFactory::class)->compilerSelect();
$this->countries = Country::select('name', 'id')->get()->toBase();
$this->clearSearch();
}
/** @todo implement compilation of document */
public function submit(): void
{
$this->validate();
}
public function updatedSearch(): void
{
$this->memberResults = Member::search($this->search, fn ($engine, $query, $options) => $engine->search($query, [
...$options,
'filter' => ['birthday IS NOT NULL', 'address IS NOT EMPTY']
]))->get()->toBase();
}
public function onSubmitFirstMemberResult(): void
{
if (count($this->memberResults) === 0) {
$this->clearSearch();
return;
}
$this->onSubmitMemberResult($this->memberResults[0]->id);
}
public function onSubmitMemberResult(int $memberId): void
{
if (in_array($memberId, $this->members)) {
$this->members = array_values(array_filter($this->members, fn ($m) => $m !== $memberId));
} else {
$this->members[] = $memberId;
}
$this->js('document.querySelector("#search_input").focus()');
$this->clearSearch();
}
public function clearSearch(): void
{
$this->search = '';
$this->memberResults = collect([]);
}
public function render()
{
return <<<'HTML'
<x-page::layout title="Zuschüsse" menu="contribution">
<form wire:submit.prevent="submit" class="max-w-4xl w-full mx-auto gap-6 grid-cols-2 grid p-6">
<x-form::text name="eventName" wire:model="eventName" class="col-span-2" label="Veranstaltungs-Name" required></x-form::text>
<x-form::text name="dateFrom" wire:model="dateFrom" type="date" label="Datum von" required></x-form::text>
<x-form::text name="dateUntil" wire:model="dateUntil" type="date" label="Datum bis" required></x-form::text>
<x-form::text name="zipLocation" v-model="zipLocation" label="PLZ / Ort" required></x-form::text>
<x-form::select name="country" wire:model="country" :options="$countries" label="Land" required></x-form::select>
<x-form::select name="compiler" wire:model="compiler" :options="$compilers" label="Formular" required></x-form::select>
<x-ui::box class="relative col-span-2" title="Mitglieder finden">
<x-ui::errors for="members" />
<x-form::text name="search_text" id="search_input" wire:model.live="search" class="col-span-2" label="Suchen …" size="sm" wire:keydown.enter="onSubmitFirstMemberResult"></x-form::text>
<div class="mt-2 grid grid-cols-[repeat(auto-fill,minmax(180px,1fr))] gap-2 col-span-2">
@foreach($memberResults as $member)
<x-form::lever
id="members-{{$member->id}}"
:wire:key="$member->id"
wire:model="members"
:label="$member->fullname"
name="members"
:value="$member->id"
size="sm"
wire:keydown.enter="onSubmitMemberResult({{$member->id}})"
></x-form::lever>
@endforeach
</div>
</x-ui::box>
<x-ui::button class="col-span-2" type="submit">Formular erstellen</x-ui::button>
</form>
</x-page::layout>
HTML;
}

View File

@ -22,3 +22,17 @@ it('loads component', function () {
Livewire::test(FillList::class)
->assertSee('Zuschüsse');
});
it('validates payload', function (array $attributes, array $error) {
Livewire::test(FillList::class)
->setArray($attributes)
->call('submit')
->assertHasErrors($error);
})->with([
[['eventName' => ''], ['eventName' => 'Veranstaltungs-Name ist erforderlich.']],
[['dateFrom' => ''], ['dateFrom' => 'Datum von ist erforderlich.']],
[['dateUntil' => ''], ['dateUntil' => 'Datum bis ist erforderlich.']],
[['country' => ''], ['country' => 'Land ist erforderlich.']],
[['zipLocation' => ''], ['zipLocation' => 'PLZ / Ort ist erforderlich.']],
[['compiler' => null], ['compiler' => 'Formular ist erforderlich.']],
]);