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

Target

Select target project
  • c3lingo/rescheduled
1 result
Show changes
Commits on Source (3)
......@@ -38,6 +38,7 @@ Run `bin/dev` in the integrated terminal to start the dev webserver and the tail
The application requires some secrets, as of writing these include:
- `invitation_token`
- `filedrop_user`
- `filedrop_password`
- `heartbeat_deen`
......
......@@ -114,7 +114,7 @@ class User < ApplicationRecord
private
def valid_invitation_token
valid_tokens = [ "gargamel" ]
valid_tokens = [ fetch_credential("invitation_token") ]
errors.add(:invitation_token, "is invalid") unless valid_tokens.include?(invitation_token)
end
......
......@@ -43,7 +43,7 @@
<% if user.new_record? %>
<div>
<%= form.label :invitation_token, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<%= form.text_field :invitation_token, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white", value: "gargamel" %>
<%= form.text_field :invitation_token, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white", value: fetch_credential("invitation_token") %>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Default invitation token</p>
</div>
<% end %>
......
......@@ -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>
......@@ -110,8 +109,8 @@
<% else %>
<!-- Not logged in state -->
<div class="flex items-center space-x-4">
<%= link_to "Assignments", assignments_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" %>
</div>
<!-- Dark mode toggle button -->
......@@ -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>
......
cedAIG6rZwVaMfjDf/fzqjqjJLtPKR4RnfixBSIi1PLaEBAg8bvSfJPUVq7BFQbTanlz4rrOQ9nXQWljcpjmTY8DxXqYVd0G7Ifqp0z3lyjnxuI7xTFPOlLOQHpJ+DiQuX4S9Ldczg7InxWTkJK+JNqRO5aMA/usMR/hiWeLNBFYVHyjNm7JGQ9GuV3qhUJAT/7beb6cT4fcyzw+bcvBMsXvmQyqCUGHjrq+8pXdJp2a4WNsQNoUIwpVpcUnO7c6Ia2zU4DieJtbgK3uyO//yQU2WaQrilrglll8BnxkPoXuAtnTaJ4sxeJvNri4CNrcH7xDac907JYXSG/fItC1AuseMeZIlPFZTf8XXHHprlURabqkhRjhH3WuloHBXxXzsK8SGGn4neCuxodPaztIEOnd+FJ48aqTly67g5HbLhZt1eNWcJzsaXrbxAk2kyy4tqtJL7h8A8QehR1SZOFZoRQtSiSMDJ8nIgHIwZ1fd3ONUaKqePkXMNAp2XQctOQWk9NNWFNqL82wlEh08DuxQTvqdL007HZmH6kO3llOfLHJ44WmXHpUzoQbFR27sd7irVKpm5TfgnB1UHzLTGcJDA4GJv29FkUQkiHxG//wm5NRDllE3hRsaM2B3P+dZRu4xcSsZ1sYYfHmdCdXmmIRUIx1vv+YyUFSSYDP6fqZostRFNtYF7KxUxZBW2SZyz453U2FETKkmVBIGAfd7K1qGrLPpz2EVPzZU1nwIM/1Qy1FHiA9uHQEm/ufxGV90FQXL9N5r76C3pE5A5t7BhPp3+i0Je++dMAH/c388dKZYle9xlPWjMWeH93T4xarVGKefYA8pia9BoM+8DA7yh3DDRE8WCZCfA86IraxKlw/TsQQtqy2RjmTK7wMIDEBCYIS7zlS7yPdG6slx2mtoI0lenVEaAPCNzEPREyGUSMeq/v8EW9QSrmnTQixViLD9KJVyXDlUN+2syR94MfiV4/ocAWFuQ==--i2jfYUHs7mOaeKp5--LwBBPAnWTJGcZg7BMU+aXg==
\ No newline at end of file
9gqI59pLB/EQaWXF5ywgyRNyCrVdNceWTXcedZMZn5Q03XK/6Q/qzmfQd53JVmMK/BkPpX85cgxRHvGYCzInvAOeJaZoTgBRfCcm2owz+GdcyXKVbM8IX2K8ic9OkeQQ+aaYTtN/cRfoDqU3CoIuxq8o8B7AuutAn2K5S7JC/WNSqw/kRkD23yo9TZ3oMitIJuTK3peM24fPb5mhZ9qvqqsblWNsCAkIZbHq0oGZqNvrqLtp1gG3N+2aZUhnXfOazHpcYppFHauovKEmRA3OrEuI5PzP/0VYCvSIteEtP8Xt2qloSNqQRhBLS/UOG+sDVoHeYmxnnYdDhmzCb6wlnSWWOTQbUq8dRETzRyWakp4I4D4VWEiwr8zhw2yJcZBTtH39HS2hKkqMRd30YufuH8NjqLCVQguSnZntVVBKpYZuOSO25ppZ+jtAbxh3ch2zSAu3D+U2T80331BksQI+ZdjCn0Arcy6z0jZfDfAWA1Dse/aZiak4bQLLFy0pKYjCo3JkJcWrPj4/5NmZA0nOSr1+ta0f8cILCmK/UA6+d1MRXDaqwEaE+nDPkR3fJiQjsRnO5GqSSGk+nxDjw82nXsfBD29j2eT36tlb6ji4AycOeIHijmdbAU/H4ymnpPDfioxWOQB2EVLNrYtc3xEh7TYstIC4fOl7YpsVVw2PcXqbvQrOFLMhqUUvmFMWTX6mus6dBORBEeU5O2NNAnsMIbAD41yUVB5ync6zBb9xLQrzgUbCNENLOLKyBZqo6UWQnILZp8xNRXAIIY4i3VaJDH8sS/r+43+MzA+8BbuGYqrualS/+3lSwPathqLWW9imzv4zQsdfphAGDFoh4QIObyiJpqxO1kUVySLiovlohi5bBDBhSX9SCtYYQ0Oz3IyYj3Zyv6RUUdV+pQ3cv8a/Jt/6F+FkGrcQ0yLNEH0xwLMGay8w3SPC+F/UH35mrwko1r1SSxhsINyEqrNUd7VOHCieMk0bWD6zxn1NAELLpsTbGgT+iVkqnrySA+q2UA==--QwhsveBIYJFf7bdw--0onIOoaCnmbbTRtoFgLCCg==
\ No newline at end of file
......@@ -402,7 +402,7 @@
# %w[coverage fog comedy adjust forge fail vigorous promise chemistry conception meat storage certain warm develop civilian cousin injection hammer health appetite conventional good snake grant suspect atmosphere linen wrong deal calf sea management silence watch nuance loan quit convert failure bracket slice sweat treaty plot still chimpanzee assume functional marsh dream mail state dorm kid formation secular agile beach guide salesperson merit goalkeeper incongruous cart pig joystick regulation apparatus myth patent glue behead flu departure spectrum parking indication delay hesitate viable lay treat cooperative sensation auction sphere stain tap pass].each do |username|
# User.find_or_create_by(name: username) do |u|
# u.email = "c3lingo+#{username}@x.moeffju.net"
# u.invitation_token = "gargamel"
# u.invitation_token = fetch_credential("invitation_token")
# u.save!
# end
# end
......