Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • eh22
  • main
  • renovate/bootsnap-1.x-lockfile
  • renovate/gcr.io-kaniko-project-executor-1.x
  • renovate/ruby
  • renovate/selenium-webdriver-4.x-lockfile
  • update-readme
  • update-rubocop
8 results

Target

Select target project
  • c3lingo/rescheduled
1 result
Select Git revision
  • eh22
  • main
  • renovate/bootsnap-1.x-lockfile
  • renovate/gcr.io-kaniko-project-executor-1.x
  • renovate/ruby
  • renovate/selenium-webdriver-4.x-lockfile
  • update-readme
  • update-rubocop
8 results
Show changes
Commits on Source (3)
Showing with 281 additions and 82 deletions
...@@ -52,11 +52,77 @@ ...@@ -52,11 +52,77 @@
.stages { .stages {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
min-width: 100%;
} }
.stages .stage { .stages .stage {
width: 400px; width: 400px;
min-width: 300px;
padding: 0 8px; padding: 0 8px;
border-right: 1px dashed gray; border-right: 1px dashed gray;
flex-shrink: 0;
}
/* Improve mobile scrolling for tables */
.table-responsive,
table.w-full,
.overflow-x-auto,
.admin-table-container,
div:has(> table) {
width: 100%;
overflow-x: auto !important;
-webkit-overflow-scrolling: touch;
max-width: 100vw;
display: block;
}
/* Mobile responsive headers with buttons */
@media (max-width: 640px) {
.header-with-actions {
flex-direction: column;
align-items: flex-start;
}
.header-with-actions h1,
.header-with-actions h2,
.header-with-actions h3 {
margin-bottom: 0.75rem;
}
.header-with-actions .actions {
margin-top: 0.5rem;
margin-bottom: 1rem;
}
}
/* Make day headers sticky on mobile devices */
.conference-day h3.sticky {
position: sticky;
top: 0;
z-index: 40;
backdrop-filter: blur(4px);
}
/* Responsive admin dashboard tiles */
@media (max-width: 768px) {
.admin-dashboard-tiles {
grid-template-columns: repeat(2, 1fr);
}
.admin-dashboard-tiles .tile {
padding: 0.75rem;
min-height: auto;
}
.admin-dashboard-tiles .tile h3 {
font-size: 1rem;
}
.admin-dashboard-tiles .tile p {
font-size: 0.875rem;
}
.admin-dashboard-tiles .tile .stat {
font-size: 1.25rem;
}
} }
/* Role-based visibility classes */ /* Role-based visibility classes */
......
...@@ -52,31 +52,11 @@ ...@@ -52,31 +52,11 @@
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@apply font-bold; @apply font-bold text-black dark:text-gray-200;
} }
{{/* input[type=submit] { html.dark {
@apply border bg-gray-400 rounded-md px-2 py-1; @apply text-gray-200;
&.primary {
@apply bg-teal-800 text-teal-50 border-teal-600;
} }
}
select, [type=text], [type=password] {
@apply pl-2 pr-6 py-1;
}
.dark {
input[type=submit] {
@apply bg-gray-600 text-slate-200;
}
select, [type=text], [type=password] {
@apply bg-zinc-900;
}
.session-holder {
select, [type=text], [type=password] {
@apply bg-white/60;
}
}
} */}}
.session-holder { .session-holder {
@apply w-full; @apply w-full;
......
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8">
<div class="flex justify-between items-center mb-6"> <div class="flex justify-between items-center mb-6 header-with-actions">
<h1 class="text-2xl font-bold dark:text-gray-200">Import History for <%= @conference.name %></h1> <h1 class="text-2xl font-bold dark:text-gray-200">Import History for <%= @conference.name %></h1>
<div class="flex space-x-2"> <div class="flex space-x-2 actions">
<%= button_to "Run Import Now", retry_import_admin_conference_path(@conference), method: :post, class: "btn btn-primary" %> <%= button_to "Run Import Now", retry_import_admin_conference_path(@conference), method: :post, class: "btn btn-primary" %>
<%= link_to "Back to Conference", admin_conference_path(@conference), class: "btn btn-tertiary" %> <%= link_to "Back to Conference", admin_conference_path(@conference), class: "btn btn-tertiary" %>
</div> </div>
</div> </div>
<div class="bg-white shadow overflow-hidden sm:rounded-lg dark:bg-gray-800"> <div class="bg-white shadow overflow-hidden sm:rounded-lg dark:bg-gray-800 table-responsive">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700"> <thead class="bg-gray-50 dark:bg-gray-700">
<tr> <tr>
......
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8">
<div class="flex justify-between items-center mb-6"> <div class="flex justify-between items-center mb-6 header-with-actions">
<h1 class="text-2xl font-bold dark:text-gray-200">Admin: Conferences</h1> <h1 class="text-2xl font-bold dark:text-gray-200">Conferences</h1>
<div class="actions">
<%= link_to "New Conference", new_admin_conference_path, class: "btn btn-primary" %> <%= link_to "New Conference", new_admin_conference_path, class: "btn btn-primary" %>
</div> </div>
</div>
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg"> <div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg table-responsive">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700"> <thead class="bg-gray-50 dark:bg-gray-700">
<tr> <tr>
......
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8">
<div class="flex justify-between items-center mb-6"> <div class="flex justify-between items-center mb-6 header-with-actions">
<h1 class="text-2xl font-bold dark:text-gray-200">Conference: <%= @conference.name %></h1> <h1 class="text-2xl font-bold dark:text-gray-200"><%= @conference.name %></h1>
<div class="flex space-x-2"> <div class="flex space-x-2 actions">
<%= link_to "Edit", edit_admin_conference_path(@conference), class: "btn btn-primary" %> <%= link_to "Edit", edit_admin_conference_path(@conference), class: "btn btn-primary" %>
<%= link_to "Back to List", admin_conferences_path, class: "btn btn-tertiary" %> <%= link_to "Back to List", admin_conferences_path, class: "btn btn-tertiary" %>
</div> </div>
......
...@@ -2,45 +2,45 @@ ...@@ -2,45 +2,45 @@
<h1 class="text-2xl font-bold dark:text-gray-200 mb-6">Admin Dashboard</h1> <h1 class="text-2xl font-bold dark:text-gray-200 mb-6">Admin Dashboard</h1>
<!-- Stats Overview --> <!-- Stats Overview -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8"> <div class="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6 mb-8 admin-dashboard-tiles">
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg"> <div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg tile">
<div class="px-4 py-5 sm:p-6"> <div class="px-3 py-3 sm:p-6">
<dl> <dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Conferences</dt> <dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Conferences</dt>
<dd class="mt-1 text-3xl font-semibold text-blue-600 dark:text-blue-400"> <dd class="mt-1 text-2xl md:text-3xl font-semibold text-blue-600 dark:text-blue-400 stat">
<%= link_to @conferences_count, admin_conferences_path, class: "hover:underline" %> <%= link_to @conferences_count, admin_conferences_path, class: "hover:underline" %>
</dd> </dd>
</dl> </dl>
</div> </div>
</div> </div>
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg"> <div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg tile">
<div class="px-4 py-5 sm:p-6"> <div class="px-3 py-3 sm:p-6">
<dl> <dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Sessions</dt> <dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Sessions</dt>
<dd class="mt-1 text-3xl font-semibold text-blue-600 dark:text-blue-400"> <dd class="mt-1 text-2xl md:text-3xl font-semibold text-blue-600 dark:text-blue-400 stat">
<%= @sessions_count %> <%= @sessions_count %>
</dd> </dd>
</dl> </dl>
</div> </div>
</div> </div>
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg"> <div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg tile">
<div class="px-4 py-5 sm:p-6"> <div class="px-3 py-3 sm:p-6">
<dl> <dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Users</dt> <dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Users</dt>
<dd class="mt-1 text-3xl font-semibold text-blue-600 dark:text-blue-400"> <dd class="mt-1 text-2xl md:text-3xl font-semibold text-blue-600 dark:text-blue-400 stat">
<%= link_to @users_count, admin_users_path, class: "hover:underline" %> <%= link_to @users_count, admin_users_path, class: "hover:underline" %>
</dd> </dd>
</dl> </dl>
</div> </div>
</div> </div>
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg"> <div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg tile">
<div class="px-4 py-5 sm:p-6"> <div class="px-3 py-3 sm:p-6">
<dl> <dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Assignments</dt> <dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Assignments</dt>
<dd class="mt-1 text-3xl font-semibold text-blue-600 dark:text-blue-400"> <dd class="mt-1 text-2xl md:text-3xl font-semibold text-blue-600 dark:text-blue-400 stat">
<%= @assignments_count %> <%= @assignments_count %>
</dd> </dd>
</dl> </dl>
......
...@@ -37,11 +37,13 @@ ...@@ -37,11 +37,13 @@
<div class="px-4 py-5 sm:p-6"> <div class="px-4 py-5 sm:p-6">
<div class="space-y-2"> <div class="space-y-2">
<% permissions.each do |permission| %> <% permissions.each do |permission| %>
<div class="flex flex-col sm:flex-row sm:items-center mb-2">
<div class="flex items-center"> <div class="flex items-center">
<%= check_box_tag "role[permission_ids][]", permission.id, role.permissions.include?(permission), id: "permission_#{permission.id}", class: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded dark:bg-gray-700 dark:border-gray-600" %> <%= check_box_tag "role[permission_ids][]", permission.id, role.permissions.include?(permission), id: "permission_#{permission.id}", class: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded dark:bg-gray-700 dark:border-gray-600" %>
<%= label_tag "permission_#{permission.id}", permission.name, class: "ml-2 block text-sm text-gray-900 dark:text-gray-300" %> <%= label_tag "permission_#{permission.id}", permission.name, class: "ml-2 text-sm text-gray-900 dark:text-gray-300" %>
</div>
<% if permission.description.present? %> <% if permission.description.present? %>
<span class="ml-2 text-xs text-gray-500 dark:text-gray-400"><%= permission.description %></span> <span class="mt-1 sm:mt-0 sm:ml-2 block text-xs text-gray-500 dark:text-gray-400"><%= permission.description %></span>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
......
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8">
<h1 class="text-2xl font-bold mb-6 dark:text-gray-200">Admin: Edit Role: <%= @role.name %></h1> <h1 class="text-2xl font-bold mb-6 dark:text-gray-200">Edit Role: <%= @role.name %></h1>
<%= render "form", role: @role, permissions: @permissions, submit_text: "Update Role" %> <%= render "form", role: @role, permissions: @permissions, submit_text: "Update Role" %>
</div> </div>
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8">
<h1 class="text-2xl font-bold mb-6 dark:text-gray-200">Admin: Roles and Permissions</h1> <h1 class="text-2xl font-bold mb-6 dark:text-gray-200">Roles and Permissions</h1>
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg"> <div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg table-responsive">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700"> <thead class="bg-gray-50 dark:bg-gray-700">
<tr> <tr>
......
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8">
<div class="flex justify-between items-center mb-6"> <div class="flex justify-between items-center mb-6 header-with-actions">
<h1 class="text-2xl font-bold dark:text-gray-200">Admin: Users</h1> <h1 class="text-2xl font-bold dark:text-gray-200">Users</h1>
<div class="actions">
<%= link_to "New User", new_admin_user_path, class: "px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 dark:bg-blue-700 dark:hover:bg-blue-800" %> <%= link_to "New User", new_admin_user_path, class: "px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 dark:bg-blue-700 dark:hover:bg-blue-800" %>
</div> </div>
</div>
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg"> <div class="bg-white dark:bg-gray-800 shadow overflow-hidden rounded-lg table-responsive">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700"> <thead class="bg-gray-50 dark:bg-gray-700">
<tr> <tr>
......
...@@ -58,7 +58,7 @@ current_time = Time.zone.now.in_time_zone(@conference.time_zone) ...@@ -58,7 +58,7 @@ current_time = Time.zone.now.in_time_zone(@conference.time_zone)
timeline_ends_at = day_ends_at.advance(minutes: (day_ends_at.min / timeline_granularity.to_f).ceil * timeline_granularity) timeline_ends_at = day_ends_at.advance(minutes: (day_ends_at.min / timeline_granularity.to_f).ceil * timeline_granularity)
%> %>
<div class="conference-day my-8" id="<%= date.strftime('day-%Y-%m-%d') %>"> <div class="conference-day my-8" id="<%= date.strftime('day-%Y-%m-%d') %>">
<h3 class="text-xl my-4 border-b sticky top-0 md:top-[3.7rem] bg-white dark:bg-gray-900 bg-opacity-70 dark:bg-opacity-70 z-30"><%= date.strftime('%B %d, %Y') %></h3> <h3 class="text-xl my-4 border-b sticky top-0 md:top-[3.7rem] bg-white dark:bg-gray-900 bg-opacity-70 dark:bg-opacity-70 z-40"><%= date.strftime('%B %d, %Y') %></h3>
<% <%
=begin%> =begin%>
<ul class="list-disc"> <ul class="list-disc">
...@@ -69,7 +69,7 @@ current_time = Time.zone.now.in_time_zone(@conference.time_zone) ...@@ -69,7 +69,7 @@ current_time = Time.zone.now.in_time_zone(@conference.time_zone)
</ul> </ul>
<% <%
=end %> =end %>
<div class="day-wrapper flex relative"> <div class="day-wrapper flex relative table-responsive overflow-x-auto -webkit-overflow-scrolling-touch">
<div class="times sticky left-0 bg-white dark:bg-gray-900 bg-opacity-70 dark:bg-opacity-70 z-20"> <div class="times sticky left-0 bg-white dark:bg-gray-900 bg-opacity-70 dark:bg-opacity-70 z-20">
<h4>Time</h4> <h4>Time</h4>
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
<script> <script>
(function() { (function() {
if (!document.documentElement.classList.contains('dark') && if (document.documentElement.classList.contains('auto')) {
!document.documentElement.classList.contains('light')) {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) { if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark'); document.documentElement.classList.add('dark');
} else { } else {
...@@ -22,7 +21,7 @@ ...@@ -22,7 +21,7 @@
} }
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
if (!localStorage.getItem('theme')) { if (!document.documentElement.classList.contains('auto')) {
document.documentElement.classList.remove('dark', 'light'); document.documentElement.classList.remove('dark', 'light');
document.documentElement.classList.add(e.matches ? 'dark' : 'light'); document.documentElement.classList.add(e.matches ? 'dark' : 'light');
} }
...@@ -34,24 +33,27 @@ ...@@ -34,24 +33,27 @@
<body <%= tag.attributes(body_data_attributes) %> class="bg-gray-100 dark:bg-gray-900 min-h-screen"> <body <%= tag.attributes(body_data_attributes) %> class="bg-gray-100 dark:bg-gray-900 min-h-screen">
<header class="bg-white dark:bg-gray-800 shadow"> <header class="bg-white dark:bg-gray-800 shadow">
<div class="container mx-auto px-4 py-4 flex justify-between items-center"> <div class="container mx-auto px-4 py-4 flex justify-between items-center">
<div class="flex items-center space-x-4"> <div class="flex items-center">
<h1 class="text-xl font-bold text-gray-900 dark:text-white"> <h1 class="text-xl font-bold text-gray-900 dark:text-white">
<%= link_to "re:scheduled", root_path %> <%= link_to "re:scheduled", root_path, class: "whitespace-nowrap" %>
</h1> </h1>
<!-- Desktop navigation items -->
<div class="hidden md:flex md:items-center md:space-x-4 md:ml-4">
<%= link_to 'Conferences', conferences_path, class: 'text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white' %> <%= link_to 'Conferences', conferences_path, class: 'text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white' %>
<%= link_to 'Assignments', assignments_path, class: 'text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white' %> <%= link_to 'Assignments', assignments_path, class: 'text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white' %>
</div> </div>
</div>
<nav class="flex items-center space-x-4"> <nav class="flex items-center">
<% if user_signed_in? %> <% if user_signed_in? %>
<div class="flex items-center space-x-4 ml-4"> <!-- Desktop user navigation -->
<%= render partial: "application/user_avatar", locals: { user: current_user } %> <div class="hidden md:flex md:items-center md:space-x-4">
<%= link_to edit_user_registration_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white", aria_label: "My Profile" do %> <%= link_to edit_user_registration_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white", aria_label: "My Profile" do %>
<span class="hidden lg:inline">My </span>Profile <span>My Profile</span>
<% end %> <% end %>
<%= link_to user_assignments_path(current_user), class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" do %> <%= 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 class="hidden lg:inline">My </span>Assignments <span>My Assignments</span>
<% end %> <% 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" %> <%= 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" %>
...@@ -59,9 +61,47 @@ ...@@ -59,9 +61,47 @@
<%= link_to "Admin", admin_root_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <%= link_to "Admin", admin_root_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %>
<% end %> <% end %>
</div> </div>
<!-- User avatar always visible -->
<div class="flex items-center ml-4">
<%= render partial: "application/user_avatar", locals: { user: current_user } %>
</div>
<!-- Mobile hamburger menu -->
<div class="md:hidden relative ml-4">
<button id="main-menu-toggle" class="text-gray-900 dark:text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<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 z-50">
<div class="py-2">
<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">Navigation</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 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
<% end %>
<%= 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>
</div>
<% else %> <% else %>
<!-- Not logged in state -->
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
<span class="px-2 text-gray-600 dark:text-gray-300">not logged in</span> <span class="px-2 text-gray-600 dark:text-gray-300 hidden md:inline">not logged in</span>
<%= link_to "Log in", new_user_session_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <%= link_to "Log in", new_user_session_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %>
<%= link_to "Sign Up", new_user_registration_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <%= link_to "Sign Up", new_user_registration_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %>
</div> </div>
...@@ -70,6 +110,38 @@ ...@@ -70,6 +110,38 @@
</div> </div>
</header> </header>
<script>
function initializeMainNavMenu() {
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');
});
// Close the menu when clicking outside
document.addEventListener('click', function(e) {
if (mobileMenu && !mobileMenu.contains(e.target) && e.target !== newMenuToggle) {
mobileMenu.classList.add('hidden');
}
});
}
}
// Initialize on DOMContentLoaded
document.addEventListener('DOMContentLoaded', initializeMainNavMenu);
// Re-initialize on Turbo navigation
document.addEventListener('turbo:load', initializeMainNavMenu);
document.addEventListener('turbo:render', initializeMainNavMenu);
</script>
<main> <main>
<% if notice %> <% 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
......
<header class="bg-gray-800 dark:bg-stone-200 text-white dark:text-black shadow"> <header class="bg-gray-800 dark:bg-stone-200 text-white dark:text-black shadow">
<div class="container mx-auto px-4 py-4 flex justify-between items-center"> <div class="container mx-auto px-4 py-4 flex justify-between items-center">
<div class="flex items-center space-x-4"> <div class="flex items-center">
<h1 class="text-xl font-bold"> <h1 class="text-xl font-bold text-white dark:text-black">
<%= link_to "re:scheduled admin", admin_root_path %> <%= link_to "re:scheduled admin", admin_root_path, class: "whitespace-nowrap hidden md:inline" %>
<%= link_to "re:admin", admin_root_path, class: "whitespace-nowrap md:hidden" %>
</h1> </h1>
<div class="hidden md:flex md:items-center md:space-x-4 md:ml-4">
<%= link_to "Dashboard", admin_dashboard_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %> <%= link_to "Dashboard", admin_dashboard_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %>
<%= link_to "Users", admin_users_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %> <%= link_to "Users", admin_users_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %>
<%= link_to "Roles", admin_roles_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %> <%= link_to "Roles", admin_roles_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %>
<%= link_to "Conferences", admin_conferences_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %> <%= link_to "Conferences", admin_conferences_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %>
</div> </div>
<nav class="flex items-center space-x-4"> <!-- Mobile visible key nav links -->
<div class="ml-4 md:hidden flex overflow-hidden whitespace-nowrap">
<%= link_to "Users", admin_users_path, class: "text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black mr-3" %>
</div>
</div>
<nav class="flex items-center space-x-3">
<!-- User avatar -->
<div class="flex items-center">
<%= render partial: "application/user_avatar", locals: { user: current_user } %> <%= render partial: "application/user_avatar", locals: { user: current_user } %>
<%= link_to "Back to Site", root_path, class: "ml-4 text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" %> </div>
<!-- Back to site link with curved arrow icon -->
<%= link_to root_path, class: "flex items-center justify-center text-gray-300 dark:text-gray-600 hover:text-white dark:hover:text-black" do %>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
<path d="M9 10.5l-5 3.5 5 3.5v-2.5h8a4 4 0 0 0 0-8h-3v2h3a2 2 0 1 1 0 4H9v-2.5z"/>
</svg>
<% end %>
<!-- Hamburger menu button - mobile only -->
<div class="relative md:hidden">
<button id="admin-menu-toggle" class="text-white dark:text-black">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
<!-- Dropdown menu instead of overlay -->
<div id="admin-mobile-menu" class="hidden absolute right-0 mt-2 w-48 bg-gray-800 dark:bg-stone-100 rounded shadow-lg z-50">
<div class="py-2">
<%= link_to "Dashboard", admin_dashboard_path, class: "block px-4 py-2 text-gray-300 dark:text-gray-600 hover:bg-gray-700 dark:hover:bg-stone-200" %>
<%= link_to "Users", admin_users_path, class: "block px-4 py-2 text-gray-300 dark:text-gray-600 hover:bg-gray-700 dark:hover:bg-stone-200" %>
<%= link_to "Roles", admin_roles_path, class: "block px-4 py-2 text-gray-300 dark:text-gray-600 hover:bg-gray-700 dark:hover:bg-stone-200" %>
<%= link_to "Conferences", admin_conferences_path, class: "block px-4 py-2 text-gray-300 dark:text-gray-600 hover:bg-gray-700 dark:hover:bg-stone-200" %>
<div class="border-t border-gray-700 dark:border-gray-300 my-1"></div>
<%= link_to root_path, class: "block px-4 py-2 text-gray-300 dark:text-gray-600 hover:bg-gray-700 dark:hover:bg-stone-200 flex items-center" do %>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4 mr-2">
<path d="M9 10.5l-5 3.5 5 3.5v-2.5h8a4 4 0 0 0 0-8h-3v2h3a2 2 0 1 1 0 4H9v-2.5z"/>
</svg>
Back to Site
<% end %>
</div>
</div>
</div>
</nav> </nav>
</div> </div>
<script>
function initializeAdminNavMenu() {
const menuToggle = document.getElementById('admin-menu-toggle');
const mobileMenu = document.getElementById('admin-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');
});
// Close the menu when clicking outside
document.addEventListener('click', function(e) {
if (mobileMenu && !mobileMenu.contains(e.target) && e.target !== newMenuToggle) {
mobileMenu.classList.add('hidden');
}
});
}
}
// Initialize on DOMContentLoaded
document.addEventListener('DOMContentLoaded', initializeAdminNavMenu);
// Re-initialize on Turbo navigation
document.addEventListener('turbo:load', initializeAdminNavMenu);
document.addEventListener('turbo:render', initializeAdminNavMenu);
</script>
</header> </header>