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;
|
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\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Form extends Model
|
class Form extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use Sluggable;
|
||||||
|
|
||||||
public $guarded = [];
|
public $guarded = [];
|
||||||
|
|
||||||
|
@ -15,6 +19,23 @@ class Form extends Model
|
||||||
'config' => 'json',
|
'config' => 'json',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function sluggable(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'slug' => ['source' => ['name']],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
public $dates = ['from', 'to', 'registration_from', 'registration_until'];
|
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' => []],
|
'config' => ['sections' => []],
|
||||||
'from' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
|
'from' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
|
||||||
'to' => $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_from' => $this->faker->dateTimeBetween('-2 weeks', 'now')->format('Y-m-d H:i:s'),
|
||||||
'registration_until' => $this->faker->dateTime()->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_top' => $this->faker->text(),
|
||||||
'mail_bottom' => $this->faker->text(),
|
'mail_bottom' => $this->faker->text(),
|
||||||
];
|
];
|
||||||
|
|
|
@ -23,6 +23,7 @@ return new class extends Migration
|
||||||
Schema::create('forms', function (Blueprint $table) {
|
Schema::create('forms', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->string('name');
|
$table->string('name');
|
||||||
|
$table->string('slug');
|
||||||
$table->text('description');
|
$table->text('description');
|
||||||
$table->text('excerpt');
|
$table->text('excerpt');
|
||||||
$table->json('config');
|
$table->json('config');
|
||||||
|
@ -44,5 +45,6 @@ return new class extends Migration
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('formtemplates');
|
Schema::dropIfExists('formtemplates');
|
||||||
|
Schema::dropIfExists('forms');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@ use App\Invoice\Actions\InvoiceStoreAction;
|
||||||
use App\Course\Actions\CourseUpdateAction;
|
use App\Course\Actions\CourseUpdateAction;
|
||||||
use App\Dashboard\Actions\IndexAction as DashboardIndexAction;
|
use App\Dashboard\Actions\IndexAction as DashboardIndexAction;
|
||||||
use App\Efz\ShowEfzDocumentAction;
|
use App\Efz\ShowEfzDocumentAction;
|
||||||
|
use App\Form\Actions\FormApiListAction;
|
||||||
use App\Form\Actions\FormDestroyAction;
|
use App\Form\Actions\FormDestroyAction;
|
||||||
use App\Form\Actions\FormIndexAction;
|
use App\Form\Actions\FormIndexAction;
|
||||||
use App\Group\Actions\GroupApiIndexAction;
|
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/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