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

1 month ago
<?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,
];
}
}