Manage calls and the inbox through the API

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 19:42:59 +02:00
parent b02464a7ed
commit 4c65604f04
11 changed files with 890 additions and 1 deletions

View File

@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\V1\CallRequest;
use App\Http\Resources\CallResource;
use App\Models\Call;
use App\Support\TranslatablePayload;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Facades\DB;
/**
* Open calls for contributors. Deleted for good, like the panel does.
*/
class CallController extends Controller
{
protected const WITH = ['technologies'];
/**
* Filters: status, project_id, search (title in the active language).
*/
public function index(Request $request): AnonymousResourceCollection
{
$this->authorize('viewAny', Call::class);
$locale = app()->getLocale();
$calls = Call::query()
->with(self::WITH)
->withCount('applications')
->when($request->filled('status'), fn ($q) => $q->where('status', $request->string('status')))
->when($request->filled('project_id'), fn ($q) => $q->where('project_id', $request->integer('project_id')))
->when($request->filled('search'), fn ($q) => $q->where("title->{$locale}", 'like', '%'.$request->string('search').'%'))
->latest('id')
->paginate(perPage: min($request->integer('per_page', 25), 100))
->withQueryString();
return CallResource::collection($calls);
}
public function store(CallRequest $request): JsonResponse
{
$this->authorize('create', Call::class);
return CallResource::make($this->save(new Call, $request))->response()->setStatusCode(201);
}
public function show(Call $call): CallResource
{
$this->authorize('view', $call);
return CallResource::make($call->load(self::WITH)->loadCount('applications'));
}
public function update(CallRequest $request, Call $call): CallResource
{
$this->authorize('update', $call);
return CallResource::make($this->save($call, $request));
}
public function destroy(Call $call): JsonResponse
{
$this->authorize('delete', $call);
$call->delete();
return response()->json(status: 204);
}
protected function save(Call $call, CallRequest $request): Call
{
$data = $request->validated();
DB::transaction(function () use ($call, $data): void {
$call->fill(TranslatablePayload::merge(
$call,
collect($data)->except(['technology_ids'])->all(),
$call->translatable,
));
$call->save();
if (array_key_exists('technology_ids', $data)) {
$call->technologies()->sync($data['technology_ids']);
}
});
return $call->load(self::WITH)->loadCount('applications');
}
}