diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 561b9856dc18d66ff7dd742d1eda810a01550569..5baad62469ababb1d80a018a8a88b4b25e922f4e 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -9,7 +9,7 @@ <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> - + <script> (function() { if (document.documentElement.classList.contains('auto')) { @@ -19,7 +19,7 @@ document.documentElement.classList.add('light'); } } - + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { if (!document.documentElement.classList.contains('auto')) { document.documentElement.classList.remove('dark', 'light'); @@ -55,13 +55,12 @@ <%= link_to user_assignments_path(current_user), class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" do %> <span>My Assignments</span> <% end %> - <%= link_to "Logout", destroy_user_session_path, data: { turbo_method: :delete }, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> - <% if current_user.has_role?("admin") || current_user.has_role?("events_admin") %> <%= link_to "Admin", admin_root_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <% end %> + <%= link_to "Logout", destroy_user_session_path, data: { turbo_method: :delete }, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> </div> - + <!-- User avatar always visible --> <div class="flex items-center ml-4"> <%= render partial: "application/user_avatar", locals: { user: current_user } %> @@ -76,7 +75,7 @@ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" /> </svg> </button> - + <!-- Mobile hamburger menu --> <div class="md:hidden relative ml-4"> <button id="main-menu-toggle" class="text-gray-900 dark:text-white"> @@ -84,13 +83,13 @@ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> </svg> </button> - + <!-- Mobile dropdown menu --> <div id="main-mobile-menu" class="hidden absolute right-0 mt-2 w-48 bg-white dark:bg-gray-800 rounded shadow-lg border border-gray-200 dark:border-gray-700 z-50"> <div class="py-2"> <%= link_to 'Conferences', conferences_path, class: 'block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' %> <%= link_to 'Assignments', assignments_path, class: 'block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' %> - + <div class="px-4 py-2 font-semibold text-sm text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-700 mt-2">Account</div> <%= link_to edit_user_registration_path, class: "block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700" do %> My Profile @@ -98,11 +97,11 @@ <%= link_to user_assignments_path(current_user), class: "block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700" do %> My Assignments <% end %> - + <% if current_user.has_role?("admin") || current_user.has_role?("events_admin") %> <%= link_to "Admin", admin_root_path, class: "block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700" %> <% end %> - + <%= link_to "Logout", destroy_user_session_path, data: { turbo_method: :delete }, class: "block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700" %> </div> </div> @@ -123,7 +122,7 @@ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" /> </svg> </button> - + <!-- Mobile hamburger menu for non-logged in users --> <div class="md:hidden relative ml-4"> <button id="guest-menu-toggle" class="text-gray-900 dark:text-white"> @@ -131,13 +130,13 @@ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> </svg> </button> - + <!-- Mobile dropdown menu for guests --> <div id="guest-mobile-menu" class="hidden absolute right-0 mt-2 w-48 bg-white dark:bg-gray-800 rounded shadow-lg border border-gray-200 dark:border-gray-700 z-50"> <div> <%= link_to 'Conferences', conferences_path, class: 'block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' %> <%= link_to 'Assignments', assignments_path, class: 'block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' %> - + <div class="px-4 py-2 font-semibold text-sm text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-700 mt-2">Account</div> <%= link_to "Log in", new_user_session_path, class: 'block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' %> <%= link_to "Sign Up", new_user_registration_path, class: 'block px-4 py-2 text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' %> @@ -153,22 +152,22 @@ function initializeThemeToggle() { const themeToggle = document.getElementById('theme-toggle'); if (!themeToggle) return; - + // Remove any existing event listeners to prevent duplicates const newThemeToggle = themeToggle.cloneNode(true); themeToggle.parentNode.replaceChild(newThemeToggle, themeToggle); - + newThemeToggle.addEventListener('click', function() { const htmlElement = document.documentElement; const isDark = htmlElement.classList.contains('dark'); const newMode = isDark ? 'light' : 'dark'; - + // Remove all theme classes htmlElement.classList.remove('dark', 'light', 'auto'); - + // Add the new theme class htmlElement.classList.add(newMode); - + // For logged-in users, save preference via AJAX if (window.userSignedIn) { fetch('/users/update_theme', { @@ -179,13 +178,13 @@ }, body: JSON.stringify({ darkmode: newMode }) }).catch(error => console.error('Error updating theme preference:', error)); - } + } // For logged-out users, save preference in localStorage else { localStorage.setItem('theme', newMode); } }); - + // If logged out and we have a theme in localStorage, apply it if (!window.userSignedIn && localStorage.getItem('theme')) { const savedTheme = localStorage.getItem('theme'); @@ -199,59 +198,59 @@ } } } - + function initializeNavMenus() { // Initialize main menu for logged in users const menuToggle = document.getElementById('main-menu-toggle'); const mobileMenu = document.getElementById('main-mobile-menu'); - + if (menuToggle && mobileMenu) { // Remove any existing event listeners to prevent duplicates const newMenuToggle = menuToggle.cloneNode(true); menuToggle.parentNode.replaceChild(newMenuToggle, menuToggle); - + newMenuToggle.addEventListener('click', function(e) { e.stopPropagation(); mobileMenu.classList.toggle('hidden'); }); } - + // Initialize guest menu for non-logged in users const guestMenuToggle = document.getElementById('guest-menu-toggle'); const guestMobileMenu = document.getElementById('guest-mobile-menu'); - + if (guestMenuToggle && guestMobileMenu) { // Remove any existing event listeners to prevent duplicates const newGuestMenuToggle = guestMenuToggle.cloneNode(true); guestMenuToggle.parentNode.replaceChild(newGuestMenuToggle, guestMenuToggle); - + newGuestMenuToggle.addEventListener('click', function(e) { e.stopPropagation(); guestMobileMenu.classList.toggle('hidden'); }); } - + // Close all menus when clicking outside document.addEventListener('click', function(e) { if (mobileMenu && !mobileMenu.contains(e.target) && e.target !== menuToggle) { mobileMenu.classList.add('hidden'); } - + if (guestMobileMenu && !guestMobileMenu.contains(e.target) && e.target !== guestMenuToggle) { guestMobileMenu.classList.add('hidden'); } }); } - + // Set user signed in state for JS window.userSignedIn = <%= user_signed_in? %>; - + // Initialize on DOMContentLoaded document.addEventListener('DOMContentLoaded', () => { initializeThemeToggle(); initializeNavMenus(); }); - + // Re-initialize on Turbo navigation document.addEventListener('turbo:load', () => { initializeThemeToggle(); @@ -265,14 +264,14 @@ <main> <% if notice %> - <div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative mb-4 mx-4 mt-4 + <div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative mb-4 mx-4 mt-4 dark:bg-green-900 dark:border-green-600 dark:text-green-300" role="alert"> <span class="block sm:inline"><%= notice %></span> </div> <% end %> <% if alert %> - <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4 mx-4 mt-4 + <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4 mx-4 mt-4 dark:bg-red-900 dark:border-red-600 dark:text-red-300" role="alert"> <span class="block sm:inline"><%= alert %></span> </div>