Add form api to display event overview on website
This commit is contained in:
parent
e005ed0d0d
commit
e011b52534
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form\Actions;
|
||||
|
||||
use App\Form\FilterScope;
|
||||
use App\Form\Models\Form;
|
||||
use App\Form\Resources\FormApiResource;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Lorisleiva\Actions\ActionRequest;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class FormApiListAction
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
/**
|
||||
* @return Collection<int, Form>
|
||||
*/
|
||||
public function handle(FilterScope $filter): Collection
|
||||
{
|
||||
return Form::withFilter($filter)->get();
|
||||
}
|
||||
|
||||
public function asController(ActionRequest $request): AnonymousResourceCollection
|
||||
{
|
||||
return FormApiResource::collection($this->handle(FilterScope::fromRequest($request->input('filter', ''))));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Form\Models\Form;
|
||||
use App\Lib\Filter;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
|
||||
|
||||
/**
|
||||
* @extends Filter<Form>
|
||||
*/
|
||||
#[MapInputName(SnakeCaseMapper::class)]
|
||||
#[MapOutputName(SnakeCaseMapper::class)]
|
||||
class FilterScope extends Filter
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function locks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<Form> $query
|
||||
*
|
||||
* @return Builder<Form>
|
||||
*/
|
||||
public function apply(Builder $query): Builder
|
||||
{
|
||||
return $query;
|
||||
}
|
||||
}
|
|
@ -2,12 +2,16 @@
|
|||
|
||||
namespace App\Form\Models;
|
||||
|
||||
use App\Form\FilterScope;
|
||||
use Cviebrock\EloquentSluggable\Sluggable;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Form extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use Sluggable;
|
||||
|
||||
public $guarded = [];
|
||||
|
||||
|
@ -15,6 +19,23 @@ class Form extends Model
|
|||
'config' => 'json',
|
||||
];
|
||||
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => ['source' => ['name']],
|
||||
];
|
||||
}
|
||||
|
||||
/** @var array<int, string> */
|
||||
public $dates = ['from', 'to', 'registration_from', 'registration_until'];
|
||||
|
||||
/**
|
||||
* @param Builder<self> $query
|
||||
*
|
||||
* @return Builder<self>
|
||||
*/
|
||||
public function scopeWithFilter(Builder $query, FilterScope $filter): Builder
|
||||
{
|
||||
return $filter->apply($query);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form\Resources;
|
||||
|
||||
use App\Form\Models\Form;
|
||||
use App\Lib\HasMeta;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/**
|
||||
* @mixin Form
|
||||
*/
|
||||
class FormApiResource extends JsonResource
|
||||
{
|
||||
use HasMeta;
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'from_human' => $this->from->format('d.m.Y'),
|
||||
'to_human' => $this->to->format('d.m.Y'),
|
||||
'excerpt' => $this->excerpt,
|
||||
'description' => $this->description,
|
||||
'config' => $this->config,
|
||||
'slug' => $this->slug,
|
||||
'dates' => $this->from->equalTo($this->to) ? $this->from->format('d.m.Y') : $this->from->format('d.m.Y') . ' - ' . $this->to->format('d.m.Y'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function meta(): array
|
||||
{
|
||||
return [
|
||||
'base_url' => url(''),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -41,8 +41,8 @@ class FormFactory extends Factory
|
|||
'config' => ['sections' => []],
|
||||
'from' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
|
||||
'to' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
|
||||
'registration_from' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
|
||||
'registration_until' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
|
||||
'registration_from' => $this->faker->dateTimeBetween('-2 weeks', 'now')->format('Y-m-d H:i:s'),
|
||||
'registration_until' => $this->faker->dateTimeBetween('now', '+2 weeks')->format('Y-m-d H:i:s'),
|
||||
'mail_top' => $this->faker->text(),
|
||||
'mail_bottom' => $this->faker->text(),
|
||||
];
|
||||
|
|
|
@ -23,6 +23,7 @@ return new class extends Migration
|
|||
Schema::create('forms', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug');
|
||||
$table->text('description');
|
||||
$table->text('excerpt');
|
||||
$table->json('config');
|
||||
|
@ -44,5 +45,6 @@ return new class extends Migration
|
|||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('formtemplates');
|
||||
Schema::dropIfExists('forms');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ use App\Invoice\Actions\InvoiceStoreAction;
|
|||
use App\Course\Actions\CourseUpdateAction;
|
||||
use App\Dashboard\Actions\IndexAction as DashboardIndexAction;
|
||||
use App\Efz\ShowEfzDocumentAction;
|
||||
use App\Form\Actions\FormApiListAction;
|
||||
use App\Form\Actions\FormDestroyAction;
|
||||
use App\Form\Actions\FormIndexAction;
|
||||
use App\Group\Actions\GroupApiIndexAction;
|
||||
|
@ -158,3 +159,4 @@ Route::group(['middleware' => 'auth:web'], function (): void {
|
|||
});
|
||||
|
||||
Route::get('/api/group/{group?}', GroupApiIndexAction::class)->name('api.group');
|
||||
Route::get('/api/form', FormApiListAction::class)->name('api.form.index');
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Form;
|
||||
|
||||
use App\Form\Models\Form;
|
||||
use App\Form\Models\Formtemplate;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class FormApiListActionTest extends TestCase
|
||||
{
|
||||
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function testItDisplaysForms(): void
|
||||
{
|
||||
$this->loginNami()->withoutExceptionHandling();
|
||||
Formtemplate::factory()->name('tname')->sections([FormtemplateSectionRequest::new()->name('sname')])->create();
|
||||
$form = Form::factory()
|
||||
->name('lala 2')
|
||||
->excerpt('fff')
|
||||
->description('desc')
|
||||
->from('2023-05-05')
|
||||
->to('2023-06-07')
|
||||
->sections([FormtemplateSectionRequest::new()->name('sname')->fields([FormtemplateFieldRequest::new()])])
|
||||
->create();
|
||||
|
||||
$this->get('/api/form')
|
||||
->assertOk()
|
||||
->assertJsonPath('data.0.name', 'lala 2')
|
||||
->assertJsonPath('data.0.config.sections.0.name', 'sname')
|
||||
->assertJsonPath('data.0.id', $form->id)
|
||||
->assertJsonPath('data.0.excerpt', 'fff')
|
||||
->assertJsonPath('data.0.description', 'desc')
|
||||
->assertJsonPath('data.0.slug', 'lala-2')
|
||||
->assertJsonPath('data.0.dates', '05.05.2023 - 07.06.2023')
|
||||
->assertJsonPath('data.0.from_human', '05.05.2023')
|
||||
->assertJsonPath('data.0.to_human', '07.06.2023');
|
||||
}
|
||||
|
||||
public function testItDisplaysDailyForms(): void
|
||||
{
|
||||
$this->loginNami()->withoutExceptionHandling();
|
||||
Form::factory()
|
||||
->from('2023-05-05')
|
||||
->to('2023-05-05')
|
||||
->create();
|
||||
|
||||
$this->get('/api/form')
|
||||
->assertJsonPath('data.0.dates', '05.05.2023');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue