You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.9 KiB
131 lines
3.9 KiB
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Admin\StoreCompetitionRequest;
|
|
use App\Http\Requests\Admin\UpdateCompetitionRequest;
|
|
use App\Models\Competition;
|
|
use App\Models\FormSchemaDefinition;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class CompetitionController extends Controller
|
|
{
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$perPage = min((int) $request->query('per_page', 15), 100);
|
|
|
|
$paginator = Competition::query()
|
|
->orderByDesc('id')
|
|
->paginate($perPage);
|
|
|
|
$paginator->getCollection()->transform(fn (Competition $c) => $this->toSummary($c));
|
|
|
|
return response()->json($paginator);
|
|
}
|
|
|
|
public function store(StoreCompetitionRequest $request): JsonResponse
|
|
{
|
|
$competition = Competition::query()->create($request->validated());
|
|
|
|
return response()->json($this->toDetail($competition), 201);
|
|
}
|
|
|
|
public function show(Competition $competition): JsonResponse
|
|
{
|
|
return response()->json($this->toDetail($competition->loadMissing([
|
|
'tracks',
|
|
'formSchema',
|
|
'reviewFormSchema',
|
|
])));
|
|
}
|
|
|
|
public function update(UpdateCompetitionRequest $request, Competition $competition): JsonResponse
|
|
{
|
|
$competition->fill($request->validated());
|
|
$competition->save();
|
|
|
|
return response()->json($this->toDetail($competition->loadMissing([
|
|
'tracks',
|
|
'formSchema',
|
|
'reviewFormSchema',
|
|
])));
|
|
}
|
|
|
|
public function destroy(Competition $competition): JsonResponse
|
|
{
|
|
$competition->delete();
|
|
|
|
return response()->noContent();
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function toSummary(Competition $c): array
|
|
{
|
|
return [
|
|
'id' => $c->id,
|
|
'slug' => $c->slug,
|
|
'name' => $c->name,
|
|
'status' => $c->status,
|
|
'published' => $c->published,
|
|
'signup_open_at' => $c->signup_open_at?->toIso8601String(),
|
|
'signup_close_at' => $c->signup_close_at?->toIso8601String(),
|
|
'form_schema_id' => $c->form_schema_id,
|
|
'review_form_schema_id' => $c->review_form_schema_id,
|
|
'created_at' => $c->created_at?->toIso8601String(),
|
|
'updated_at' => $c->updated_at?->toIso8601String(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function toDetail(Competition $c): array
|
|
{
|
|
$base = $this->toSummary($c);
|
|
|
|
$base['description'] = $c->description;
|
|
$base['pledge_content_html'] = $c->pledge_content_html;
|
|
$base['branding_json'] = $c->branding_json;
|
|
$base['settings'] = $c->settings;
|
|
$base['scoring_rules_json'] = $c->scoring_rules_json;
|
|
|
|
if ($c->relationLoaded('tracks')) {
|
|
$base['tracks'] = $c->tracks->map(fn ($t) => [
|
|
'id' => $t->id,
|
|
'track_code' => $t->track_code,
|
|
'title' => $t->title,
|
|
'description' => $t->description,
|
|
'sort' => $t->sort,
|
|
'is_enabled' => $t->is_enabled,
|
|
])->values();
|
|
}
|
|
|
|
if ($c->relationLoaded('formSchema') && $c->formSchema) {
|
|
$base['form_schema'] = $this->formSchemaBrief($c->formSchema);
|
|
}
|
|
if ($c->relationLoaded('reviewFormSchema') && $c->reviewFormSchema) {
|
|
$base['review_form_schema'] = $this->formSchemaBrief($c->reviewFormSchema);
|
|
}
|
|
|
|
return $base;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function formSchemaBrief(FormSchemaDefinition $schema): array
|
|
{
|
|
return [
|
|
'id' => $schema->id,
|
|
'name' => $schema->name,
|
|
'purpose' => $schema->purpose,
|
|
'version' => $schema->version,
|
|
'is_published' => $schema->is_published,
|
|
];
|
|
}
|
|
}
|