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
+
+@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
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',
+ ]);
+ }
+}
--
2.55.0