From 9e9fbdc127e983a4a33a9aae313c3930956db6c8 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Fri, 28 Aug 2026 14:49:53 +0100 Subject: [PATCH] Add admin-editable About page Mirrors the existing Bio singleton pattern: a new `about` table/model, admin CRUD at /admin/about, and a public page at /about linked from both the header nav and the admin homepage. Content is wrapped in .e-content so it lays out correctly within the site's CSS grid. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_013bzYwaDD8p3XNDMYKvXKrs --- app/Http/Controllers/AboutPageController.php | 16 +++++ .../Controllers/Admin/AboutController.php | 32 +++++++++ app/Models/About.php | 13 ++++ database/factories/AboutFactory.php | 24 +++++++ .../2026_08_28_142830_create_about_table.php | 28 ++++++++ resources/views/about.blade.php | 9 +++ resources/views/admin/about/show.blade.php | 19 ++++++ resources/views/admin/welcome.blade.php | 5 ++ resources/views/master.blade.php | 1 + routes/web.php | 11 +++ tests/Feature/AboutPageTest.php | 26 +++++++ tests/Feature/Admin/AboutTest.php | 68 +++++++++++++++++++ 12 files changed, 252 insertions(+) create mode 100644 app/Http/Controllers/AboutPageController.php create mode 100644 app/Http/Controllers/Admin/AboutController.php create mode 100644 app/Models/About.php create mode 100644 database/factories/AboutFactory.php create mode 100644 database/migrations/2026_08_28_142830_create_about_table.php create mode 100644 resources/views/about.blade.php create mode 100644 resources/views/admin/about/show.blade.php create mode 100644 tests/Feature/AboutPageTest.php create mode 100644 tests/Feature/Admin/AboutTest.php diff --git a/app/Http/Controllers/AboutPageController.php b/app/Http/Controllers/AboutPageController.php new file mode 100644 index 00000000..d174e550 --- /dev/null +++ b/app/Http/Controllers/AboutPageController.php @@ -0,0 +1,16 @@ + About::first()?->content, + ]); + } +} diff --git a/app/Http/Controllers/Admin/AboutController.php b/app/Http/Controllers/Admin/AboutController.php new file mode 100644 index 00000000..cc5be0ad --- /dev/null +++ b/app/Http/Controllers/Admin/AboutController.php @@ -0,0 +1,32 @@ + $about, + ]); + } + + public function update(Request $request): RedirectResponse + { + $about = About::firstOrNew(); + $about->content = $request->input('content'); + $about->save(); + + return redirect()->route('admin.about.show'); + } +} diff --git a/app/Models/About.php b/app/Models/About.php new file mode 100644 index 00000000..26b6a719 --- /dev/null +++ b/app/Models/About.php @@ -0,0 +1,13 @@ + + */ +class AboutFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'content' => $this->faker->paragraph, + ]; + } +} diff --git a/database/migrations/2026_08_28_142830_create_about_table.php b/database/migrations/2026_08_28_142830_create_about_table.php new file mode 100644 index 00000000..15ab6f84 --- /dev/null +++ b/database/migrations/2026_08_28_142830_create_about_table.php @@ -0,0 +1,28 @@ +id(); + $table->text('content'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('about'); + } +}; diff --git a/resources/views/about.blade.php b/resources/views/about.blade.php new file mode 100644 index 00000000..e73c933a --- /dev/null +++ b/resources/views/about.blade.php @@ -0,0 +1,9 @@ +@extends('master') +@section('title')About « @stop + +@section('content') +

About

+
+ {!! $about !!} +
+@stop diff --git a/resources/views/admin/about/show.blade.php b/resources/views/admin/about/show.blade.php new file mode 100644 index 00000000..59c6a433 --- /dev/null +++ b/resources/views/admin/about/show.blade.php @@ -0,0 +1,19 @@ +@extends('master') + +@section('title')Edit About « Admin CP « @stop + +@section('content') +

Edit About

+
+ {{ csrf_field() }} + {{ method_field('PUT') }} +
+ +
+ +
+
+ +
+
+@stop diff --git a/resources/views/admin/welcome.blade.php b/resources/views/admin/welcome.blade.php index 03112665..132da7cc 100644 --- a/resources/views/admin/welcome.blade.php +++ b/resources/views/admin/welcome.blade.php @@ -57,6 +57,11 @@ Edit your bio.

+

About

+

+ Edit your about page. +

+

Passkeys

Manager your passkeys. diff --git a/resources/views/master.blade.php b/resources/views/master.blade.php index 543f4255..b33d1fa9 100644 --- a/resources/views/master.blade.php +++ b/resources/views/master.blade.php @@ -36,6 +36,7 @@ Likes Contacts Projects + About @include('icons.json-feed', ['title' => 'JSON Feed'])

diff --git a/routes/web.php b/routes/web.php index 3b6fa7d2..03d865b1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,7 @@ name('login'); Route::post('login', [AuthController::class, 'login']); @@ -167,6 +172,12 @@ Route::middleware(MyAuthMiddleware::class)->prefix('admin')->group(function () { Route::put('/', [SettingsController::class, 'update']); }); + // About + Route::prefix('about')->group(function () { + Route::get('/', [AboutController::class, 'show'])->name('admin.about.show'); + Route::put('/', [AboutController::class, 'update']); + }); + // Passkeys Route::prefix('passkeys')->group(function () { Route::get('/', [PasskeysController::class, 'index']); diff --git a/tests/Feature/AboutPageTest.php b/tests/Feature/AboutPageTest.php new file mode 100644 index 00000000..61455069 --- /dev/null +++ b/tests/Feature/AboutPageTest.php @@ -0,0 +1,26 @@ +create([ + 'content' => 'This is the about page content.', + ]); + + $this->get('/about') + ->assertSee('This is the about page content.'); + } +} diff --git a/tests/Feature/Admin/AboutTest.php b/tests/Feature/Admin/AboutTest.php new file mode 100644 index 00000000..141a548b --- /dev/null +++ b/tests/Feature/Admin/AboutTest.php @@ -0,0 +1,68 @@ +make(); + + $response = $this->actingAs($user) + ->get('/admin/about'); + $response->assertSeeText('Edit About'); + } + + #[Test] + public function admin_can_create_about(): void + { + $user = User::factory()->make(); + + $this->actingAs($user) + ->post('/admin/about', [ + '_method' => 'PUT', + 'content' => 'About content', + ]); + $this->assertDatabaseHas('about', ['content' => 'About content']); + } + + #[Test] + public function admin_can_load_existing_about(): void + { + $user = User::factory()->make(); + $about = About::factory()->create([ + 'content' => 'This is my about page. It uses HTML.', + ]); + + $response = $this->actingAs($user) + ->get('/admin/about'); + $response->assertSeeText('This is my about page. It uses HTML.'); + } + + #[Test] + public function admin_can_edit_about(): void + { + $user = User::factory()->make(); + $about = About::factory()->create(); + + $this->actingAs($user) + ->post('/admin/about', [ + '_method' => 'PUT', + 'content' => 'This about page has been edited', + ]); + $this->assertDatabaseHas('about', [ + 'content' => 'This about page has been edited', + ]); + } +}