Files
Portfolio-Game/api/app/Http/Controllers/Api/ProjectController.php
skycel 2269ecdb62 Add project detail page with prev/next navigation (Story 2.3)
- Enhance ProjectController show() with prev/next navigation data
- Create useFetchProject composable with ProjectNavigation type
- Implement [slug].vue with full project details:
  - Hero image, title with featured badge, formatted date
  - Description, external links (site/GitHub)
  - Skills grid with level progression (before → after)
  - Prev/next navigation with project titles
  - 404 state with spider narrator
- Add dynamic SEO meta tags with og:image from project
- Responsive design: stacked mobile, grid desktop

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 02:20:27 +01:00

58 lines
1.8 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\ProjectResource;
use App\Models\Project;
use App\Models\Translation;
class ProjectController extends Controller
{
public function index()
{
$projects = Project::with('skills')->ordered()->get();
return ProjectResource::collection($projects)
->additional(['meta' => ['lang' => app()->getLocale()]]);
}
public function show(string $slug)
{
$project = Project::with('skills')->where('slug', $slug)->first();
if (!$project) {
return response()->json([
'error' => [
'code' => 'PROJECT_NOT_FOUND',
'message' => 'Project not found',
],
], 404);
}
$lang = app()->getLocale();
// Get all projects in order for navigation
$allProjects = Project::ordered()->get(['id', 'slug', 'title_key']);
$currentIndex = $allProjects->search(fn ($p) => $p->slug === $slug);
$prev = $currentIndex > 0 ? $allProjects[$currentIndex - 1] : null;
$next = $currentIndex < $allProjects->count() - 1 ? $allProjects[$currentIndex + 1] : null;
return (new ProjectResource($project))
->additional([
'meta' => ['lang' => $lang],
'navigation' => [
'prev' => $prev ? [
'slug' => $prev->slug,
'title' => Translation::getTranslation($prev->title_key, $lang),
] : null,
'next' => $next ? [
'slug' => $next->slug,
'title' => Translation::getTranslation($next->title_key, $lang),
] : null,
],
]);
}
}