diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index e78c3b927..15e5cc382 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -142,9 +142,12 @@ class ProfileController extends BasePageController 'None', ); - // Update dark mode preference - if ($request->has('dark_mode')) { - User::where('id', $userid)->update(['dark_mode' => (bool) $request->input('dark_mode')]); + // Update theme preference + if ($request->has('theme_preference')) { + $themeValue = $request->input('theme_preference'); + if (in_array($themeValue, ['light', 'dark', 'system'])) { + User::where('id', $userid)->update(['theme_preference' => $themeValue]); + } } // Handle Console permission @@ -317,16 +320,16 @@ class ProfileController extends BasePageController } $validator = Validator::make($request->all(), [ - 'dark_mode' => ['required', 'boolean'], + 'theme_preference' => ['required', 'in:light,dark,system'], ]); if ($validator->fails()) { return response()->json(['success' => false, 'message' => 'Invalid input'], 400); } - $user->dark_mode = $request->input('dark_mode'); + $user->theme_preference = $request->input('theme_preference'); $user->save(); - return response()->json(['success' => true, 'dark_mode' => $user->dark_mode]); + return response()->json(['success' => true, 'theme_preference' => $user->theme_preference]); } } diff --git a/database/migrations/2025_10_16_120000_update_dark_mode_to_theme_preference.php b/database/migrations/2025_10_16_120000_update_dark_mode_to_theme_preference.php new file mode 100644 index 000000000..5a391232b --- /dev/null +++ b/database/migrations/2025_10_16_120000_update_dark_mode_to_theme_preference.php @@ -0,0 +1,50 @@ +string('theme_preference', 10)->default('light')->after('dark_mode'); + }); + + // Migrate existing dark_mode values to theme_preference + DB::table('users')->where('dark_mode', true)->update(['theme_preference' => 'dark']); + DB::table('users')->where('dark_mode', false)->update(['theme_preference' => 'light']); + + // Drop the old dark_mode column + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('dark_mode'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // Add back the dark_mode column + Schema::table('users', function (Blueprint $table) { + $table->boolean('dark_mode')->default(false)->after('notes'); + }); + + // Migrate theme_preference back to dark_mode + DB::table('users')->where('theme_preference', 'dark')->update(['dark_mode' => true]); + DB::table('users')->whereIn('theme_preference', ['light', 'system'])->update(['dark_mode' => false]); + + // Drop theme_preference column + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('theme_preference'); + }); + } +}; + diff --git a/resources/views/layouts/admin.blade.php b/resources/views/layouts/admin.blade.php index e68da5441..8baea800e 100644 --- a/resources/views/layouts/admin.blade.php +++ b/resources/views/layouts/admin.blade.php @@ -19,14 +19,24 @@ (function() { @auth // Use user's database preference when authenticated - const userDarkMode = {{ auth()->user()->dark_mode ? 'true' : 'false' }}; - if (userDarkMode) { + const userThemePreference = '{{ auth()->user()->theme_preference ?? 'light' }}'; + + if (userThemePreference === 'system') { + // Use OS preference + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.classList.add('dark'); + } + } else if (userThemePreference === 'dark') { document.documentElement.classList.add('dark'); } @else // Fallback to localStorage for non-authenticated users const theme = localStorage.getItem('theme') || 'light'; - if (theme === 'dark') { + if (theme === 'system') { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.classList.add('dark'); + } + } else if (theme === 'dark') { document.documentElement.classList.add('dark'); } @endauth @@ -91,54 +101,101 @@ - @stack('scripts') diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index c88e7676d..efc2228e6 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -20,14 +20,24 @@ (function() { @auth // Use user's database preference when authenticated - const userDarkMode = {{ auth()->user()->dark_mode ? 'true' : 'false' }}; - if (userDarkMode) { + const userThemePreference = '{{ auth()->user()->theme_preference ?? 'light' }}'; + + if (userThemePreference === 'system') { + // Use OS preference + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.classList.add('dark'); + } + } else if (userThemePreference === 'dark') { document.documentElement.classList.add('dark'); } @else // Fallback to localStorage for non-authenticated users const theme = localStorage.getItem('theme') || 'light'; - if (theme === 'dark') { + if (theme === 'system') { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.classList.add('dark'); + } + } else if (theme === 'dark') { document.documentElement.classList.add('dark'); } @endauth @@ -102,9 +112,9 @@ - @@ -119,50 +129,97 @@ @stack('scripts') diff --git a/resources/views/profile/edit.blade.php b/resources/views/profile/edit.blade.php index dca420b00..49e6c669f 100644 --- a/resources/views/profile/edit.blade.php +++ b/resources/views/profile/edit.blade.php @@ -67,8 +67,8 @@ Theme Preference
-

Your theme preference will be applied across all devices and browsers when you're logged in. @@ -318,27 +331,36 @@ @endpush diff --git a/resources/views/profile/index.blade.php b/resources/views/profile/index.blade.php index 3e055c562..56dadc030 100644 --- a/resources/views/profile/index.blade.php +++ b/resources/views/profile/index.blade.php @@ -147,11 +147,19 @@ Theme Mode

- @if($user->dark_mode) + @php + $themePreference = $user->theme_preference ?? 'light'; + @endphp + @if($themePreference === 'dark')
Dark Mode
+ @elseif($themePreference === 'system') +
+ + System (Auto) +
@else