diff --git a/CHANGELOG.md b/CHANGELOG.md index b8fc8f0..658baf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 2026-02-28 +- Updated ACP General to use section navigation with `Overview` as the default landing view and a dedicated `Settings` view. +- Reorganized ACP General placeholders by moving `Client communication` and `Server configuration` into the Settings area as dedicated sub-tabs. +- Added nested Settings tab grouping and bordered tab-content containers to match the ACP tabbed layout pattern. +- Refined ACP tab visual states so inactive tabs render muted and active tabs use the configured accent color. +- Standardized key ACP refresh actions with explicit icon + spacing so repeated controls render consistently. +- Added icon support to additional primary UI actions (update modal/footer actions, auth screens, and forum/thread actions). +- Synced board version/build display in stats from `composer.json` and added safe DB setting synchronization fallback logic. +- Applied global accent-based Bootstrap button variable overrides so primary button styling remains consistent across ACP and user-facing screens. + ## 2026-02-27 - Reworked ACP System navigation into `Health` and `Updates`. - Moved update/version actions into the new `Updates` area and grouped update checks under `Live Update`, `CLI`, and `CI/CD`. diff --git a/app/Http/Controllers/StatsController.php b/app/Http/Controllers/StatsController.php index 6c14047..819d221 100644 --- a/app/Http/Controllers/StatsController.php +++ b/app/Http/Controllers/StatsController.php @@ -32,8 +32,10 @@ class StatsController extends Controller $avatarSizeBytes = $this->resolveAvatarDirectorySize(); $orphanAttachments = $this->resolveOrphanAttachments(); - $version = Setting::query()->where('key', 'version')->value('value'); - $build = Setting::query()->where('key', 'build')->value('value'); + $composer = $this->readComposerMetadata(); + $this->syncVersionBuildSettings($composer); + $version = $composer['version'] ?? Setting::query()->where('key', 'version')->value('value'); + $build = $composer['build'] ?? Setting::query()->where('key', 'build')->value('value'); $boardVersion = $version ? ($build ? "{$version} (build {$build})" : $version) : null; @@ -158,4 +160,59 @@ class StatsController extends Controller $value = ini_get('zlib.output_compression'); return in_array(strtolower((string) $value), ['1', 'on', 'true'], true); } + + private function readComposerMetadata(): array + { + $path = base_path('composer.json'); + if (!is_file($path) || !is_readable($path)) { + return []; + } + + $raw = file_get_contents($path); + if ($raw === false) { + return []; + } + + $data = json_decode($raw, true); + if (!is_array($data)) { + return []; + } + + $version = trim((string) ($data['version'] ?? '')); + $build = trim((string) ($data['build'] ?? '')); + + return [ + 'version' => $version !== '' ? $version : null, + 'build' => ctype_digit($build) ? (int) $build : null, + ]; + } + + private function syncVersionBuildSettings(array $composer): void + { + $version = $composer['version'] ?? null; + $build = $composer['build'] ?? null; + + if ($version === null && $build === null) { + return; + } + + try { + if ($version !== null) { + $currentVersion = Setting::query()->where('key', 'version')->value('value'); + if ((string) $currentVersion !== (string) $version) { + Setting::updateOrCreate(['key' => 'version'], ['value' => (string) $version]); + } + } + + if ($build !== null) { + $buildString = (string) $build; + $currentBuild = Setting::query()->where('key', 'build')->value('value'); + if ((string) $currentBuild !== $buildString) { + Setting::updateOrCreate(['key' => 'build'], ['value' => $buildString]); + } + } + } catch (\Throwable) { + // Stats endpoint should remain readable even if settings sync fails. + } + } } diff --git a/composer.json b/composer.json index 1ffee20..74ae9b9 100644 --- a/composer.json +++ b/composer.json @@ -98,5 +98,5 @@ "minimum-stability": "stable", "prefer-stable": true, "version": "26.0.3", - "build": "110" + "build": "111" } diff --git a/resources/js/App.jsx b/resources/js/App.jsx index 423ad0b..26de9ad 100644 --- a/resources/js/App.jsx +++ b/resources/js/App.jsx @@ -576,6 +576,7 @@ function AppShell() { className="bb-accent-button" onClick={() => window.location.reload()} > +