Initial commit: Pireon Admin — headless admin panel and public API
Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
74
app/Http/Controllers/Api/V1/CategoryController.php
Normal file
74
app/Http/Controllers/Api/V1/CategoryController.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\V1\CategoryRequest;
|
||||
use App\Http\Resources\CategoryResource;
|
||||
use App\Models\Category;
|
||||
use App\Support\TranslatablePayload;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$this->authorize('viewAny', Category::class);
|
||||
|
||||
$locale = app()->getLocale();
|
||||
|
||||
$categories = Category::query()
|
||||
->withCount('pages')
|
||||
->when($request->has('is_visible'), fn ($q) => $q->where('is_visible', $request->boolean('is_visible')))
|
||||
->when($request->filled('search'), fn ($q) => $q->where("name->{$locale}", 'like', '%'.$request->string('search').'%'))
|
||||
->orderBy('position')
|
||||
->orderBy("name->{$locale}")
|
||||
->paginate(perPage: min($request->integer('per_page', 25), 100))
|
||||
->withQueryString();
|
||||
|
||||
return CategoryResource::collection($categories);
|
||||
}
|
||||
|
||||
public function store(CategoryRequest $request): JsonResponse
|
||||
{
|
||||
$this->authorize('create', Category::class);
|
||||
|
||||
$category = new Category;
|
||||
$category->fill(TranslatablePayload::merge($category, $request->validated(), $category->translatable));
|
||||
$category->save();
|
||||
|
||||
return CategoryResource::make($category)->response()->setStatusCode(201);
|
||||
}
|
||||
|
||||
public function show(Category $category): CategoryResource
|
||||
{
|
||||
$this->authorize('view', $category);
|
||||
|
||||
return CategoryResource::make($category->loadCount('pages'));
|
||||
}
|
||||
|
||||
public function update(CategoryRequest $request, Category $category): CategoryResource
|
||||
{
|
||||
$this->authorize('update', $category);
|
||||
|
||||
$category->fill(TranslatablePayload::merge($category, $request->validated(), $category->translatable));
|
||||
$category->save();
|
||||
|
||||
return CategoryResource::make($category->loadCount('pages'));
|
||||
}
|
||||
|
||||
public function destroy(Category $category): JsonResponse
|
||||
{
|
||||
// CategoryPolicy refuses while the category still holds pages, so this
|
||||
// answers 403 rather than orphaning content.
|
||||
$this->authorize('delete', $category);
|
||||
|
||||
$category->delete();
|
||||
|
||||
return response()->json(status: 204);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user