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.

143 lines
4.5 KiB

5 months 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;
2 months ago
use App\Support\BizDateTime;
5 months ago
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CompetitionController extends Controller
{
2 months ago
5 months ago
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',
1 month ago
'audienceFormSchema',
5 months ago
])));
}
public function update(UpdateCompetitionRequest $request, Competition $competition): JsonResponse
{
$competition->fill($request->validated());
$competition->save();
return response()->json($this->toDetail($competition->loadMissing([
'tracks',
'formSchema',
'reviewFormSchema',
1 month ago
'audienceFormSchema',
5 months ago
])));
}
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,
2 months ago
'signup_open_at' => BizDateTime::toIso8601($c->signup_open_at),
'signup_close_at' => BizDateTime::toIso8601($c->signup_close_at),
5 months ago
'form_schema_id' => $c->form_schema_id,
'review_form_schema_id' => $c->review_form_schema_id,
1 month ago
'audience_form_schema_id' => $c->audience_form_schema_id,
5 months ago
'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;
1 month ago
$base['pledge_title'] = $c->pledge_title;
$base['pledge_title_en'] = $c->pledge_title_en;
$base['pledge_subtitle'] = $c->pledge_subtitle;
$base['pledge_subtitle_en'] = $c->pledge_subtitle_en;
5 months ago
$base['pledge_content_html'] = $c->pledge_content_html;
1 month ago
$base['pledge_content_html_en'] = $c->pledge_content_html_en;
5 months ago
$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,
1 month ago
'title_en' => $t->title_en,
5 months ago
'description' => $t->description,
1 month ago
'description_en' => $t->description_en,
5 months ago
'sort' => $t->sort,
'is_enabled' => $t->is_enabled,
])->values();
}
if ($c->relationLoaded('formSchema') && $c->formSchema) {
$base['form_schema'] = $this->formSchemaBrief($c->formSchema);
}
1 month ago
if ($c->relationLoaded('audienceFormSchema') && $c->audienceFormSchema) {
$base['audience_form_schema'] = $this->formSchemaBrief($c->audienceFormSchema);
5 months ago
}
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,
];
}
}