Manage calls and the inbox through the API
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
104
app/Http/Controllers/Api/V1/ApplicationController.php
Normal file
104
app/Http/Controllers/Api/V1/ApplicationController.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Enums\ApplicationStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\V1\ApplicationRequest;
|
||||
use App\Http\Resources\ApplicationResource;
|
||||
use App\Models\Application;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
/**
|
||||
* The inbox: what people sent from the public site.
|
||||
*
|
||||
* Nothing is created here — submissions arrive through the public API — and
|
||||
* what can be changed is what the panel changes: the status and the private
|
||||
* notes.
|
||||
*/
|
||||
class ApplicationController extends Controller
|
||||
{
|
||||
protected const WITH = ['call', 'handler'];
|
||||
|
||||
/**
|
||||
* Filters: status, kind, call_id, search (name, e-mail or organisation), trashed.
|
||||
*
|
||||
* Spam stays out unless asked for by `status=spam`, as in the panel.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$this->authorize('viewAny', Application::class);
|
||||
|
||||
$applications = Application::query()
|
||||
->with(self::WITH)
|
||||
->when(
|
||||
$request->filled('status'),
|
||||
fn ($q) => $q->where('status', $request->string('status')),
|
||||
fn ($q) => $q->notSpam(),
|
||||
)
|
||||
->when($request->filled('kind'), fn ($q) => $q->where('kind', $request->string('kind')))
|
||||
->when($request->filled('call_id'), fn ($q) => $q->where('call_id', $request->integer('call_id')))
|
||||
->when($request->filled('search'), function ($q) use ($request): void {
|
||||
$term = '%'.$request->string('search').'%';
|
||||
|
||||
$q->where(fn ($q) => $q
|
||||
->where('name', 'like', $term)
|
||||
->orWhere('email', 'like', $term)
|
||||
->orWhere('organisation', 'like', $term));
|
||||
})
|
||||
->when($request->boolean('trashed'), fn ($q) => $q->onlyTrashed())
|
||||
->latest()
|
||||
->paginate(perPage: min($request->integer('per_page', 25), 100))
|
||||
->withQueryString();
|
||||
|
||||
return ApplicationResource::collection($applications);
|
||||
}
|
||||
|
||||
public function show(Application $application): ApplicationResource
|
||||
{
|
||||
$this->authorize('view', $application);
|
||||
|
||||
return ApplicationResource::make($application->load(self::WITH));
|
||||
}
|
||||
|
||||
public function update(ApplicationRequest $request, Application $application): ApplicationResource
|
||||
{
|
||||
$this->authorize('update', $application);
|
||||
|
||||
$data = $request->validated();
|
||||
|
||||
// Notes are outside the model's fillable list so the public form can
|
||||
// never reach them; this is the one other place that writes them.
|
||||
if (array_key_exists('notes', $data)) {
|
||||
$application->forceFill(['notes' => $data['notes']])->save();
|
||||
}
|
||||
|
||||
if (isset($data['status'])) {
|
||||
$application->markAs(ApplicationStatus::from($data['status']), $request->user());
|
||||
}
|
||||
|
||||
return ApplicationResource::make($application->load(self::WITH));
|
||||
}
|
||||
|
||||
public function destroy(Application $application): JsonResponse
|
||||
{
|
||||
$this->authorize('delete', $application);
|
||||
|
||||
$application->delete();
|
||||
|
||||
return response()->json(status: 204);
|
||||
}
|
||||
|
||||
public function restore(Application $application): ApplicationResource
|
||||
{
|
||||
$this->authorize('restore', $application);
|
||||
|
||||
$application->restore();
|
||||
|
||||
return ApplicationResource::make($application->load(self::WITH));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user