From 8bf0667683148a8e4df60325d53acb695292550a Mon Sep 17 00:00:00 2001 From: jheaps Date: Thu, 9 Oct 2025 13:23:44 -0600 Subject: [PATCH] Enhance user experience --- Media.JoshHeaps.Net/Pages/Index.cshtml | 1 + Media.JoshHeaps.Net/Pages/Profile.cshtml | 180 +++++++++++++++++ Media.JoshHeaps.Net/Pages/Profile.cshtml.cs | 22 +++ .../Pages/Shared/_Layout.cshtml | 2 + Media.JoshHeaps.Net/wwwroot/css/Home/page.css | 86 ++++---- Media.JoshHeaps.Net/wwwroot/css/auth.css | 112 +++++------ Media.JoshHeaps.Net/wwwroot/css/gallery.css | 184 +++++++++++------- Media.JoshHeaps.Net/wwwroot/css/site.css | 81 ++++++++ Media.JoshHeaps.Net/wwwroot/js/gallery.js | 10 +- Media.JoshHeaps.Net/wwwroot/js/theme.js | 38 ++++ 10 files changed, 557 insertions(+), 159 deletions(-) create mode 100644 Media.JoshHeaps.Net/Pages/Profile.cshtml create mode 100644 Media.JoshHeaps.Net/Pages/Profile.cshtml.cs create mode 100644 Media.JoshHeaps.Net/wwwroot/js/theme.js diff --git a/Media.JoshHeaps.Net/Pages/Index.cshtml b/Media.JoshHeaps.Net/Pages/Index.cshtml index f8c3c59..670cd30 100644 --- a/Media.JoshHeaps.Net/Pages/Index.cshtml +++ b/Media.JoshHeaps.Net/Pages/Index.cshtml @@ -20,6 +20,7 @@ Verify Email } + Edit Profile Logout diff --git a/Media.JoshHeaps.Net/Pages/Profile.cshtml b/Media.JoshHeaps.Net/Pages/Profile.cshtml new file mode 100644 index 0000000..18af864 --- /dev/null +++ b/Media.JoshHeaps.Net/Pages/Profile.cshtml @@ -0,0 +1,180 @@ +@page +@model Media.JoshHeaps.Net.Pages.ProfileModel +@{ + ViewData["Title"] = "Profile Settings"; + Layout = "_Layout"; +} + +@section Styles { + + +} + +
+ ← Back to Dashboard + +
+

Profile Information

+
+ +
@Model.Dashboard?.Username
+
+
+ +
@Model.Dashboard?.Email
+
+
+ +
+ @if (Model.Dashboard?.EmailVerified == true) + { + Verified + } + else + { + Unverified + } +
+
+
+ +
+

Appearance

+
+
+ Dark Mode + Enable dark theme across the application +
+ +
+
+
diff --git a/Media.JoshHeaps.Net/Pages/Profile.cshtml.cs b/Media.JoshHeaps.Net/Pages/Profile.cshtml.cs new file mode 100644 index 0000000..c46ec25 --- /dev/null +++ b/Media.JoshHeaps.Net/Pages/Profile.cshtml.cs @@ -0,0 +1,22 @@ +using Media.JoshHeaps.Net.Models; +using Media.JoshHeaps.Net.Services; +using Microsoft.AspNetCore.Mvc; + +namespace Media.JoshHeaps.Net.Pages +{ + public class ProfileModel(UserService userService) : AuthenticatedPageModel + { + public UserDashboard? Dashboard { get; set; } + + public async Task OnGetAsync() + { + RequireAuthentication(); + LoadUserSession(); + + // Load user dashboard data + Dashboard = await userService.GetUserDashboardAsync(UserId); + + return Page(); + } + } +} diff --git a/Media.JoshHeaps.Net/Pages/Shared/_Layout.cshtml b/Media.JoshHeaps.Net/Pages/Shared/_Layout.cshtml index dff923b..b8b8a2a 100644 --- a/Media.JoshHeaps.Net/Pages/Shared/_Layout.cshtml +++ b/Media.JoshHeaps.Net/Pages/Shared/_Layout.cshtml @@ -9,6 +9,8 @@ @ViewData["Title"] + + @await RenderSectionAsync("Styles", required: false) @await RenderSectionAsync("Scripts", required: false) diff --git a/Media.JoshHeaps.Net/wwwroot/css/Home/page.css b/Media.JoshHeaps.Net/wwwroot/css/Home/page.css index 19892ce..7ce6d83 100644 --- a/Media.JoshHeaps.Net/wwwroot/css/Home/page.css +++ b/Media.JoshHeaps.Net/wwwroot/css/Home/page.css @@ -5,12 +5,12 @@ } .welcome-section { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - padding: 40px; - border-radius: 12px; - margin-bottom: 30px; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + background: var(--bg-tertiary); + border: 1px solid var(--border-primary); + color: var(--text-primary); + padding: 32px 40px; + border-radius: 8px; + margin-bottom: 32px; display: flex; justify-content: space-between; align-items: center; @@ -18,13 +18,14 @@ .welcome-section h1 { margin: 0; - font-size: 32px; + font-size: 28px; font-weight: 600; + letter-spacing: -0.5px; } .welcome-section p { margin: 0; - opacity: 0.9; + opacity: 0.8; font-size: 16px; } @@ -36,26 +37,31 @@ } .card { - background: white; - border-radius: 12px; - padding: 30px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + background: var(--bg-secondary); + border: 1px solid var(--border-primary); + border-radius: 8px; + padding: 24px; + transition: border-color 0.2s ease; +} + +.card:hover { + border-color: var(--border-secondary); } .card h2 { margin: 0 0 20px 0; - font-size: 20px; + font-size: 18px; font-weight: 600; - color: #333; - border-bottom: 2px solid #667eea; - padding-bottom: 10px; + color: var(--text-primary); + border-bottom: 1px solid var(--border-primary); + padding-bottom: 12px; } .info-row { display: flex; justify-content: space-between; padding: 12px 0; - border-bottom: 1px solid #f0f0f0; + border-bottom: 1px solid var(--border-secondary); } .info-row:last-child { @@ -64,30 +70,30 @@ .info-label { font-weight: 500; - color: #666; + color: var(--text-secondary); } .info-value { - color: #333; + color: var(--text-primary); font-weight: 500; } .status-badge { display: inline-block; padding: 4px 12px; - border-radius: 12px; + border-radius: 6px; font-size: 12px; font-weight: 600; } .status-verified { - background: #d4edda; - color: #155724; + background: rgba(63, 185, 80, 0.15); + color: var(--success); } .status-unverified { - background: #fff3cd; - color: #856404; + background: rgba(187, 128, 9, 0.15); + color: #d29922; } .quick-actions { @@ -98,44 +104,52 @@ } .btn { - padding: 10px 20px; + padding: 8px 16px; border-radius: 6px; text-decoration: none; font-weight: 500; + font-size: 14px; display: inline-block; - transition: all 0.2s; + transition: all 0.2s ease; + border: 1px solid transparent; } .btn-primary { - background: #667eea; - color: white; + background: var(--accent-primary); + color: var(--bg-primary); + border-color: var(--accent-primary); } .btn-primary:hover { - background: #5568d3; + background: var(--accent-hover); + border-color: var(--accent-hover); } .btn-secondary { - background: #6c757d; - color: white; + background: var(--bg-tertiary); + color: var(--text-primary); + border-color: var(--border-primary); } .btn-secondary:hover { - background: #5a6268; + background: var(--bg-hover); + border-color: var(--border-secondary); } .btn-danger { - background: #dc3545; - color: white; + background: transparent; + color: var(--danger); + border-color: var(--danger); } .btn-danger:hover { - background: #c82333; + background: var(--danger); + color: var(--text-primary); } .empty-state { text-align: center; - color: #999; + color: var(--text-secondary); padding: 20px; font-style: italic; } diff --git a/Media.JoshHeaps.Net/wwwroot/css/auth.css b/Media.JoshHeaps.Net/wwwroot/css/auth.css index 10e5a9c..e7c7115 100644 --- a/Media.JoshHeaps.Net/wwwroot/css/auth.css +++ b/Media.JoshHeaps.Net/wwwroot/css/auth.css @@ -1,29 +1,19 @@ /* Authentication Pages Styling */ -:root { - --primary-color: #007bff; - --primary-hover: #0056b3; - --danger-color: #dc3545; - --success-color: #28a745; - --warning-color: #ffc107; - --border-color: #dee2e6; - --input-focus: #80bdff; - --text-muted: #6c757d; -} - .auth-container { min-height: 100vh; display: flex; align-items: center; justify-content: center; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: var(--bg-primary); padding: 20px; } .auth-card { - background: white; - border-radius: 12px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1); + background: var(--bg-secondary); + border: 1px solid var(--border-primary); + border-radius: 8px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); padding: 40px; width: 100%; max-width: 450px; @@ -31,18 +21,19 @@ .auth-header { text-align: center; - margin-bottom: 30px; + margin-bottom: 32px; } .auth-header h1 { font-size: 28px; font-weight: 600; - color: #333; - margin-bottom: 10px; + color: var(--text-primary); + margin-bottom: 8px; + letter-spacing: -0.5px; } .auth-header p { - color: var(--text-muted); + color: var(--text-secondary); font-size: 14px; } @@ -52,7 +43,7 @@ .form-label { font-weight: 500; - color: #333; + color: var(--text-primary); margin-bottom: 8px; display: block; font-size: 14px; @@ -61,28 +52,30 @@ .form-control { width: 100%; padding: 12px 16px; - border: 1px solid var(--border-color); + border: 1px solid var(--border-primary); border-radius: 6px; font-size: 14px; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + background: var(--bg-tertiary); + color: var(--text-primary); + transition: border-color 0.2s ease, box-shadow 0.2s ease; } .form-control:focus { outline: none; - border-color: var(--input-focus); - box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1); + border-color: var(--accent-primary); + box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.15); } .form-control.is-invalid { - border-color: var(--danger-color); + border-color: var(--danger); } .form-control.is-invalid:focus { - box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.1); + box-shadow: 0 0 0 3px rgba(248, 81, 73, 0.15); } .invalid-feedback { - color: var(--danger-color); + color: var(--danger); font-size: 13px; margin-top: 5px; display: none; @@ -103,20 +96,21 @@ transform: translateY(-50%); background: none; border: none; - color: var(--text-muted); + color: var(--text-secondary); cursor: pointer; padding: 4px 8px; font-size: 14px; + transition: color 0.2s ease; } .password-toggle:hover { - color: #333; + color: var(--text-primary); } .password-strength { margin-top: 8px; height: 4px; - background: var(--border-color); + background: var(--bg-tertiary); border-radius: 2px; overflow: hidden; display: none; @@ -133,17 +127,17 @@ } .password-strength-bar.weak { - background-color: var(--danger-color); + background-color: var(--danger); width: 33%; } .password-strength-bar.medium { - background-color: var(--warning-color); + background-color: #d29922; width: 66%; } .password-strength-bar.strong { - background-color: var(--success-color); + background-color: var(--success); width: 100%; } @@ -151,6 +145,7 @@ font-size: 12px; margin-top: 4px; display: none; + color: var(--text-secondary); } .password-strength-text.active { @@ -167,11 +162,13 @@ margin-right: 8px; width: 16px; height: 16px; + accent-color: var(--accent-primary); + cursor: pointer; } .checkbox-wrapper label { font-size: 14px; - color: #333; + color: var(--text-primary); margin: 0; cursor: pointer; } @@ -179,22 +176,25 @@ .btn-primary { width: 100%; padding: 12px; - background: var(--primary-color); - color: white; - border: none; + background: var(--accent-primary); + color: var(--bg-primary); + border: 1px solid var(--accent-primary); border-radius: 6px; - font-size: 16px; + font-size: 15px; font-weight: 500; cursor: pointer; - transition: background-color 0.15s ease-in-out; + transition: all 0.2s ease; } .btn-primary:hover { - background: var(--primary-hover); + background: var(--accent-hover); + border-color: var(--accent-hover); } .btn-primary:disabled { - background: var(--text-muted); + background: var(--bg-tertiary); + border-color: var(--border-primary); + color: var(--text-secondary); cursor: not-allowed; } @@ -202,22 +202,24 @@ text-align: center; margin-top: 24px; padding-top: 24px; - border-top: 1px solid var(--border-color); + border-top: 1px solid var(--border-primary); } .auth-footer p { - color: var(--text-muted); + color: var(--text-secondary); font-size: 14px; margin: 0; } .auth-footer a { - color: var(--primary-color); + color: var(--accent-primary); text-decoration: none; font-weight: 500; + transition: color 0.2s ease; } .auth-footer a:hover { + color: var(--accent-hover); text-decoration: underline; } @@ -229,29 +231,29 @@ } .alert-danger { - background-color: #f8d7da; - color: #721c24; - border: 1px solid #f5c6cb; + background-color: rgba(248, 81, 73, 0.15); + color: var(--danger); + border: 1px solid rgba(248, 81, 73, 0.3); } .alert-success { - background-color: #d4edda; - color: #155724; - border: 1px solid #c3e6cb; + background-color: rgba(63, 185, 80, 0.15); + color: var(--success); + border: 1px solid rgba(63, 185, 80, 0.3); } .alert-warning { - background-color: #fff3cd; - color: #856404; - border: 1px solid #ffeaa7; + background-color: rgba(187, 128, 9, 0.15); + color: #d29922; + border: 1px solid rgba(187, 128, 9, 0.3); } .spinner { display: inline-block; width: 16px; height: 16px; - border: 2px solid rgba(255, 255, 255, 0.3); - border-top-color: white; + border: 2px solid rgba(88, 166, 255, 0.3); + border-top-color: var(--accent-primary); border-radius: 50%; animation: spin 0.6s linear infinite; margin-right: 8px; diff --git a/Media.JoshHeaps.Net/wwwroot/css/gallery.css b/Media.JoshHeaps.Net/wwwroot/css/gallery.css index 6565c11..7d93f75 100644 --- a/Media.JoshHeaps.Net/wwwroot/css/gallery.css +++ b/Media.JoshHeaps.Net/wwwroot/css/gallery.css @@ -3,34 +3,37 @@ position: fixed; bottom: 30px; right: 30px; - width: 60px; - height: 60px; + width: 56px; + height: 56px; border-radius: 50%; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border: none; - box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); + background: var(--accent-primary); + color: var(--bg-primary); + border: 1px solid var(--accent-primary); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); cursor: pointer; z-index: 1000; - transition: transform 0.2s, box-shadow 0.2s; + transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; - font-size: 32px; + font-size: 28px; line-height: 1; + font-weight: 300; } .floating-add-btn:hover { - transform: scale(1.1); - box-shadow: 0 6px 16px rgba(102, 126, 234, 0.6); + transform: scale(1.05); + background: var(--accent-hover); + border-color: var(--accent-hover); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); } .floating-add-btn:active { - transform: scale(0.95); + transform: scale(0.98); } .floating-add-btn .btn-icon { - transition: transform 0.3s; + transition: transform 0.3s ease; } .floating-add-btn.active .btn-icon { @@ -46,7 +49,7 @@ z-index: 1001; max-width: 500px; width: 90%; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6); } /* Upload Progress Bar */ @@ -56,24 +59,24 @@ .progress-bar { width: 100%; - height: 30px; - background: #f0f0f0; - border-radius: 15px; + height: 8px; + background: var(--bg-tertiary); + border-radius: 4px; overflow: hidden; margin-bottom: 10px; } .progress-fill { height: 100%; - background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); + background: var(--accent-primary); transition: width 0.3s ease; width: 0%; } .progress-text { text-align: center; - font-size: 14px; - color: #555; + font-size: 13px; + color: var(--text-secondary); font-weight: 500; } @@ -87,40 +90,40 @@ .close-upload-form { background: transparent; border: none; - font-size: 32px; - color: #999; + font-size: 28px; + color: var(--text-secondary); cursor: pointer; padding: 0; width: 32px; height: 32px; line-height: 1; - transition: color 0.2s; + transition: color 0.2s ease; } .close-upload-form:hover { - color: #333; + color: var(--text-primary); } /* Gallery Grid Layout */ .gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); - gap: 20px; + gap: 16px; padding: 20px 0; } .gallery-item { position: relative; - background: #fff; + background: var(--bg-secondary); + border: 1px solid var(--border-primary); border-radius: 8px; overflow: hidden; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - transition: transform 0.2s, box-shadow 0.2s; + transition: all 0.2s ease; } .gallery-item:hover { - transform: translateY(-4px); - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + transform: translateY(-2px); + border-color: var(--border-secondary); } .gallery-item img { @@ -129,91 +132,137 @@ object-fit: cover; display: block; cursor: pointer; + transition: opacity 0.2s ease; +} + +.gallery-item img:hover { + opacity: 0.9; } .gallery-item-description { - padding: 10px; - font-size: 14px; - color: #555; - background: #f9f9f9; - border-top: 1px solid #eee; + padding: 12px; + font-size: 13px; + color: var(--text-secondary); + background: var(--bg-secondary); + border-top: 1px solid var(--border-primary); + line-height: 1.5; } .gallery-item-info { display: flex; justify-content: space-between; align-items: center; - padding: 10px; - background: #fff; - border-top: 1px solid #eee; + padding: 10px 12px; + background: var(--bg-tertiary); + border-top: 1px solid var(--border-primary); } .gallery-item-date { font-size: 12px; - color: #888; + color: var(--text-secondary); } .btn-delete { - background: #dc3545; - color: white; - border: none; - padding: 5px 12px; + background: transparent; + color: var(--danger); + border: 1px solid var(--danger); + padding: 4px 10px; border-radius: 4px; font-size: 12px; cursor: pointer; - transition: background 0.2s; + transition: all 0.2s ease; + font-weight: 500; } .btn-delete:hover { - background: #c82333; + background: var(--danger); + color: var(--text-primary); } /* Upload Form Styles */ .form-group { - margin-bottom: 15px; + margin-bottom: 16px; } .form-group label { display: block; - margin-bottom: 5px; + margin-bottom: 8px; font-weight: 500; - color: #333; + color: var(--text-primary); + font-size: 14px; } .form-group input[type="file"] { width: 100%; - padding: 8px; - border: 2px dashed #ddd; - border-radius: 4px; + padding: 12px; + border: 1px dashed var(--border-primary); + border-radius: 6px; cursor: pointer; + background: var(--bg-tertiary); + color: var(--text-primary); + font-size: 14px; + transition: border-color 0.2s ease; +} + +.form-group input[type="file"]:hover { + border-color: var(--accent-primary); +} + +.form-group input[type="file"]::file-selector-button { + padding: 8px 16px; + margin-right: 12px; + background: var(--accent-primary); + color: var(--bg-primary); + border: 1px solid var(--accent-primary); + border-radius: 4px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; +} + +.form-group input[type="file"]::file-selector-button:hover { + background: var(--accent-hover); + border-color: var(--accent-hover); } .form-group textarea { width: 100%; padding: 10px; - border: 1px solid #ddd; - border-radius: 4px; + border: 1px solid var(--border-primary); + border-radius: 6px; font-family: inherit; resize: vertical; + background: var(--bg-tertiary); + color: var(--text-primary); + font-size: 14px; + line-height: 1.5; + transition: border-color 0.2s ease; +} + +.form-group textarea:focus { + outline: none; + border-color: var(--accent-primary); } /* Alert Messages */ .alert { padding: 12px 16px; - border-radius: 4px; - margin-bottom: 15px; + border-radius: 6px; + margin-bottom: 16px; + font-size: 14px; } .alert-success { - background: #d4edda; - color: #155724; - border: 1px solid #c3e6cb; + background: rgba(63, 185, 80, 0.15); + color: var(--success); + border: 1px solid rgba(63, 185, 80, 0.3); } .alert-error { - background: #f8d7da; - color: #721c24; - border: 1px solid #f5c6cb; + background: rgba(248, 81, 73, 0.15); + color: var(--danger); + border: 1px solid rgba(248, 81, 73, 0.3); } /* Image Modal */ @@ -235,7 +284,8 @@ left: 0; right: 0; bottom: 0; - background: rgba(0, 0, 0, 0.8); + background: rgba(0, 0, 0, 0.85); + backdrop-filter: blur(4px); } .modal-content { @@ -250,25 +300,27 @@ max-height: 90vh; display: block; border-radius: 8px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6); } .modal-close { position: absolute; - top: -40px; + top: -50px; right: 0; background: transparent; border: none; - color: white; - font-size: 36px; + color: var(--text-primary); + font-size: 32px; cursor: pointer; padding: 0; width: 40px; height: 40px; - line-height: 36px; + line-height: 32px; + transition: color 0.2s ease; } .modal-close:hover { - color: #ccc; + color: var(--text-secondary); } /* Responsive Design */ diff --git a/Media.JoshHeaps.Net/wwwroot/css/site.css b/Media.JoshHeaps.Net/wwwroot/css/site.css index e69de29..e60d954 100644 --- a/Media.JoshHeaps.Net/wwwroot/css/site.css +++ b/Media.JoshHeaps.Net/wwwroot/css/site.css @@ -0,0 +1,81 @@ +/* Theme Variables */ +:root { + /* Dark Mode (Default) */ + --bg-primary: #0d1117; + --bg-secondary: #161b22; + --bg-tertiary: #1f2937; + --bg-hover: #252d3a; + --text-primary: #e6edf3; + --text-secondary: #8b949e; + --border-primary: #30363d; + --border-secondary: #21262d; + --accent-primary: #58a6ff; + --accent-hover: #4a93e3; + --danger: #f85149; + --danger-hover: #da3633; + --success: #3fb950; +} + +/* Light Mode */ +[data-theme="light"] { + --bg-primary: #ffffff; + --bg-secondary: #f6f8fa; + --bg-tertiary: #E2EFFF; + --bg-hover: #f3f4f6; + --text-primary: #24292f; + --text-secondary: #57606a; + --border-primary: #d0d7de; + --border-secondary: #e5e7eb; + --accent-primary: #0969da; + --accent-hover: #0550ae; + --danger: #cf222e; + --danger-hover: #a40e26; + --success: #1a7f37; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, body { + background: var(--bg-primary); + color: var(--text-primary); + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif; + line-height: 1.6; + min-height: 100vh; +} + +body { + margin: 0; + padding: 0; +} + +a { + color: var(--accent-primary); + text-decoration: none; + transition: color 0.2s ease; +} + +a:hover { + color: var(--accent-hover); +} + +/* Scrollbar Styling */ +::-webkit-scrollbar { + width: 12px; +} + +::-webkit-scrollbar-track { + background: var(--bg-primary); +} + +::-webkit-scrollbar-thumb { + background: var(--border-primary); + border-radius: 6px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--bg-hover); +} diff --git a/Media.JoshHeaps.Net/wwwroot/js/gallery.js b/Media.JoshHeaps.Net/wwwroot/js/gallery.js index b878842..284d215 100644 --- a/Media.JoshHeaps.Net/wwwroot/js/gallery.js +++ b/Media.JoshHeaps.Net/wwwroot/js/gallery.js @@ -7,8 +7,14 @@ document.addEventListener('DOMContentLoaded', function() { if (addFilesBtn && uploadFormCard) { addFilesBtn.addEventListener('click', () => { - uploadFormCard.style.display = 'block'; - addFilesBtn.classList.add('active'); + if (addFilesBtn.classList.contains('active')) { + uploadFormCard.style.display = 'none'; + addFilesBtn.classList.remove('active'); + } + else { + uploadFormCard.style.display = 'block'; + addFilesBtn.classList.add('active'); + } }); if (closeUploadBtn) { diff --git a/Media.JoshHeaps.Net/wwwroot/js/theme.js b/Media.JoshHeaps.Net/wwwroot/js/theme.js new file mode 100644 index 0000000..b59e698 --- /dev/null +++ b/Media.JoshHeaps.Net/wwwroot/js/theme.js @@ -0,0 +1,38 @@ +// Theme Toggle Functionality +(function() { + const THEME_KEY = 'theme-preference'; + + // Initialize theme on page load + function initTheme() { + const savedTheme = localStorage.getItem(THEME_KEY); + const theme = savedTheme || 'light'; // Default to light + + document.documentElement.setAttribute('data-theme', theme); + + // Update toggle if it exists + const toggle = document.getElementById('theme-toggle'); + if (toggle) { + toggle.checked = theme === 'dark'; + } + } + + // Toggle theme + function toggleTheme() { + const currentTheme = document.documentElement.getAttribute('data-theme') || 'light'; + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + + document.documentElement.setAttribute('data-theme', newTheme); + localStorage.setItem(THEME_KEY, newTheme); + } + + // Initialize immediately (before DOMContentLoaded to prevent flash) + initTheme(); + + // Set up toggle listener when DOM is ready + document.addEventListener('DOMContentLoaded', function() { + const toggle = document.getElementById('theme-toggle'); + if (toggle) { + toggle.addEventListener('change', toggleTheme); + } + }); +})();