diff --git a/README.md b/README.md index 57b0ce5fccd0f14153e4d86987a82e44e14d72f8..8ba8a8cdf6ac2708c9a5b83571c0b70b594977f6 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,21 @@ tbd. See [rescheduled-deploy](https://git.cccv.de/c3lingo/rescheduled-deploy) for a full docker-compose stack and more explanations. +# Colors (darkmode) + +- **text**: text-slate-300 +- **text (overlay)**: text-slate-200 +- **text light**: text-slate-400 + +- **logo**: text-white +- **highlight**: text-red-500 + +- **dark background**: bg-zinc-700 +- **light background**: bg-gray-900 +- **overlay**: bg-gray-600 +- **input**: bg-zinc-900 +- **shadow**: gray-400 + ## Tips and Tricks ### Helpful `rails` tasks diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index beacefe26053f5ccc759fc6d76348e2717dfa984..8e1ab0e1be5f38ed361c8ce0e602c6284956c9b4 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -21,9 +21,24 @@ input[type=submit] { @apply bg-teal-800 text-teal-50 border-teal-600; } } -select { + +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 { @apply w-full; height: var(--height); @@ -85,4 +100,4 @@ select { @apply ml-6; } } -} \ No newline at end of file +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c964fdea1e943936cb295e287256ea03b2a8ea89..4da35cb171d4ead463de7a883f1ba4fce9a0cbb5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:invitation_token]) devise_parameter_sanitizer.permit(:account_update) do |u| - u.permit(:name, :email, :password, :password_confirmation, :avatar_color, :languages_from, :languages_to, :telegram_username, :current_password) + u.permit(:name, :email, :password, :password_confirmation, :avatar_color, :darkmode, :languages_from, :languages_to, :telegram_username, :current_password) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d1a9e8a08ab63ba1097e3821ff486f6da2e11829..268d351fe30570bba8a9fc15add25e88d6717b86 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -4,6 +4,7 @@ module ApplicationHelper attributes[:loggedin_uid] = current_user.id if user_signed_in? attributes[:is_shiftcoordinator] = 1 if current_user&.shiftcoordinator? attributes[:languages_from] = current_user.languages_from unless current_user&.languages_from.blank? + attributes[:darkmode] = current_user.darkmode { data: attributes } end end diff --git a/app/javascript/application.js b/app/javascript/application.js index 0c66ece2255f65daf4262c959d1e4e3f8b650a61..9a7c38e3c09de067a5b333670776a0adfcc2d9e5 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -4,6 +4,7 @@ import "@hotwired/turbo-rails" document.addEventListener("turbo:load", function() { console.log('turbo:load'); + applyDarkmode(); const flashMessages = document.querySelectorAll(".flash"); flashMessages.forEach(flashMessage => { diff --git a/app/models/user.rb b/app/models/user.rb index 1652be201b8e4276a2f034f57975d1d063d06e39..e54cc9c986cc05eae2cdd5875051dc26f52c3993 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,6 +3,9 @@ class User < ApplicationRecord has_many :assignments has_many :candidates + enum darkmode: { auto: 0, light: 1, dark: 2 } + validates :darkmode, inclusion: { in: %w(auto light dark) } + validates :password, presence: true, length: { minimum: 6 }, allow_nil: true validates :name, uniqueness: { case_sensitive: false, message: "already in use" }, allow_nil: false validates :email, uniqueness: { case_sensitive: false, message: "already in use" }, allow_nil: true, allow_blank: true diff --git a/app/views/assignments/by_user.html.erb b/app/views/assignments/by_user.html.erb index bb5542c9325d0cad6ece919c695415d462a098cd..9f246703ec5cb4765c46e78229cd0ea8d4b8f23f 100644 --- a/app/views/assignments/by_user.html.erb +++ b/app/views/assignments/by_user.html.erb @@ -1,5 +1,5 @@ <div> - <h1 class="text-xl my-4"> + <h1 class="text-xl my-4 dark:text-red-500"> Assignments for <%= link_to @user.name, user_assignments_path(@user) %> <span class="text-base ml-2 mb-2 inline p-2 border bg-slate-50 hover:bg-slate-100 border-slate-200 hover:border-slate-200 shadow font-normal rounded-md"><%= link_to user_assignments_path(@user, format: 'ics') do %><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 24" fill="currentColor" aria-hidden="true" class="size-6 inline-block stroke-slate-400 fill-slate-400"><path fill-rule="evenodd" d="M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z" clip-rule="evenodd"></path></svg> iCal<% end %></span> diff --git a/app/views/assignments/index.html.erb b/app/views/assignments/index.html.erb index 470a8154d28361bdfc4a55cbe6cce612a114b46e..8b61ac629bc1220ff21f976db6eebaed9527e117 100644 --- a/app/views/assignments/index.html.erb +++ b/app/views/assignments/index.html.erb @@ -1,6 +1,6 @@ <% now = Time.now %> <div class="scroll-smooth"> - <h1 class="text-xl my-4">Assignments for all users</h1> + <h1 class="text-xl my-4 dark:text-red-500">Assignments for all users</h1> <p> Jump to: <ul class="flex flex-row flex-wrap"> diff --git a/app/views/assignments/show.html.erb b/app/views/assignments/show.html.erb index 6c530750c9b9ffc4b68ac98681587d7fb112c510..be9f69e60f620716fb665e933dd0b66ace8306df 100644 --- a/app/views/assignments/show.html.erb +++ b/app/views/assignments/show.html.erb @@ -1,4 +1,4 @@ <div> - <h1 class="font-bold text-4xl">Assignments#show</h1> + <h1 class="font-bold text-4xl dark:text-red-500">Assignments#show</h1> <p>Find me in app/views/assignments/show.html.erb</p> </div> diff --git a/app/views/conferences/index.html.erb b/app/views/conferences/index.html.erb index 7de75c246d0cbff21a9cf3dfdbb55f6de3dc561d..4fcb2ed25ad66e45617c899d1fca999fc7a653c6 100644 --- a/app/views/conferences/index.html.erb +++ b/app/views/conferences/index.html.erb @@ -1,8 +1,8 @@ <div> -<h1 class="text-xl my-4">Conferences</h1> +<h1 class="text-xl my-4 dark:text-red-500">Conferences</h1> <ul> <% @conferences.each do |conference| %> -<li><%= link_to conference.name, conference_path(conference.slug), class: "inline-block px-4 py-2 text-slate-500 hover:text-slate-900 hover:bg-slate-100 rounded-md" %></li> +<li><%= link_to conference.name, conference_path(conference.slug), class: "inline-block px-4 py-2 text-slate-500 hover:text-slate-900 dark:hover:text-slate-200 hover:bg-slate-100 dark:hover:bg-gray-600 rounded-md" %></li> <% end %> </ul> </div> diff --git a/app/views/conferences/show.html.erb b/app/views/conferences/show.html.erb index 8c17f0e87eaa024531583e203a539f227c1f4963..0528867b2799f0209425e48ffdc4fbe9bd61a90d 100644 --- a/app/views/conferences/show.html.erb +++ b/app/views/conferences/show.html.erb @@ -17,7 +17,7 @@ current_time = Time.zone.now.in_time_zone(@conference.time_zone) <div> <a href="#now" onclick="document.querySelector('#now')?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' }); return false" class="underline text-blue-500">Jump to current time</a> </div> - <h1 class="text-2xl font-bold my-2"><%= @conference.name %></h1> + <h1 class="text-2xl font-bold my-2 dark:text-red-500"><%= @conference.name %></h1> <p class="text-xs mb-6"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="inline-block size-4 stroke-slate-500"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> @@ -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) %> <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 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-30"><%= date.strftime('%B %d, %Y') %></h3> <% =begin%> <ul class="list-disc"> @@ -71,7 +71,7 @@ current_time = Time.zone.now.in_time_zone(@conference.time_zone) =end %> <div class="day-wrapper flex relative"> - <div class="times sticky left-0 bg-white 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> <% # if current_time.strftime('%Y%m%d') == date.strftime('%Y%m%d') && current_time >= timeline_starts_at && current_time <= timeline_ends_at %> @@ -131,7 +131,7 @@ current_time = Time.zone.now.in_time_zone(@conference.time_zone) sessions = @sessions_by_date_and_stage[date][stage] %> <div class="stage"> - <h4 class="sticky md:top-[5.5rem] top-7 bg-white bg-opacity-70 w-full z-30"><%= stage.name %></h4> + <h4 class="sticky md:top-[5.5rem] top-7 bg-white dark:bg-gray-900 bg-opacity-70 dark:bg-opacity-70 w-full z-30"><%= stage.name %></h4> <div class="stage-sessions"> <% sessions.each do |session| %> <div class="session-holder hover:z-30 h-full" style=" diff --git a/app/views/conferences/stats.html.erb b/app/views/conferences/stats.html.erb index 8465f00dc867802462673280fa0f0324bdfd0266..5ae8cfba1e8c4e07965dc7d749c400d430889ac0 100644 --- a/app/views/conferences/stats.html.erb +++ b/app/views/conferences/stats.html.erb @@ -1,5 +1,5 @@ <div> - <h1>Statistics for <%= @conference.name %></h1> + <h1 class="dark:text-red-500">Statistics for <%= @conference.name %></h1> <div class="conference-stats"> <ul> <li><%= @assignees.count %> interpreters diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index b517dde8e4bb763aedfffe5731ba39fa3ea5e9b0..5fa03b782af2ea8e40716efc98d77c7ceecfeecb 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -1,6 +1,6 @@ <div> -<h1 class="text-xl my-4">Profile</h1> +<h1 class="text-xl my-4 dark:text-red-500">Profile</h1> <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> <%= render "devise/shared/error_messages", resource: resource %> @@ -33,6 +33,11 @@ <%= f.password_field :password_confirmation, autocomplete: "new-password" %> </div> + <div class="field"> + <%= f.label :darkmode %> + <%= f.select :darkmode, User.darkmodes.keys.map { |d| [d.humanize, d] } %> + </div> + <div class="field"> <%= f.label :avatar_color %> <%= f.color_field :avatar_color %> diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb index 5d98cd4b945fe559173183829dbe3674b12ee278..b532322b03529d3c772b9ba205e2ad29f27337e4 100644 --- a/app/views/devise/registrations/new.html.erb +++ b/app/views/devise/registrations/new.html.erb @@ -1,5 +1,5 @@ <div> -<h1 class="text-xl my-4">Sign Up</h1> +<h1 class="text-xl my-4 dark:text-red-500">Sign Up</h1> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= render "devise/shared/error_messages", resource: resource %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index a216b2d1e6271e331fee648c223f4e8191528051..70ca0530173d0ca5699ef60e32786f84287311d5 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,5 +1,5 @@ <div> -<h1 class="text-xl my-4">Log in</h1> +<h1 class="text-xl my-4 dark:text-red-500">Log in</h1> <%= form_for(resource, as: resource_name, url: user_session_path) do |f| %> <div class="field"> diff --git a/app/views/filedrop_files/download.html.erb b/app/views/filedrop_files/download.html.erb index 60788e4b97e71b53eed212342259dba7d003dc0c..a1ee394e5b8a7f4c732c01fbc236199e83dabd86 100644 --- a/app/views/filedrop_files/download.html.erb +++ b/app/views/filedrop_files/download.html.erb @@ -1,4 +1,4 @@ <div> - <h1 class="font-bold text-4xl">FiledropFiles#download</h1> + <h1 class="font-bold text-4xl dark:text-red-500">FiledropFiles#download</h1> <p>Find me in app/views/filedrop_files/download.html.erb</p> </div> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 7a482d3a8a2bd8f1a6854a15a9e3694f2b96e4d0..e2c68a9208b559b3bba7c6359754b2f862ce4e47 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -9,52 +9,65 @@ <%= stylesheet_link_tag "application" %> <%= javascript_importmap_tags %> + + <script type="text/javascript"> + function applyDarkmode() { + const userTheme = document.body.dataset.darkmode; + document.documentElement.classList.toggle( + 'dark', + userTheme === 'dark' || ((userTheme === 'auto') && window.matchMedia('(prefers-color-scheme: dark)').matches) + ); + } + </script> </head> - <body <%= tag.attributes(body_data_attributes) %>> - <nav class="bg-slate-100 text-gray-700 shadow w-full relative md:fixed z-50" data-controller="navigation"> - <div class="relative bg-slate-100 z-50 container mx-auto px-4 py-4 flex justify-between items-center"> + <body <%= tag.attributes(body_data_attributes) %> class="dark:bg-gray-900 dark:text-slate-300"> + <script type="text/javascript"> + applyDarkmode(); // Required to prevent flashing on load + </script> + <nav class="bg-slate-100 dark:bg-zinc-700 text-gray-700 dark:text-slate-300 shadow w-full relative md:fixed z-50" data-controller="navigation"> + <div class="relative bg-slate-100 dark:bg-zinc-700 z-50 container mx-auto px-4 py-4 flex justify-between items-center"> <div class="flex items-center space-x-4"> - <div class="text-xl font-bold text-black"><%= link_to 're:scheduled', '/', class: "!no-underline" %></div> + <div class="text-xl font-bold text-black dark:text-white"><%= link_to 're:scheduled', '/', class: "!no-underline" %></div> <div class="hidden md:flex space-x-4"> - <%= link_to 'Conferences', conferences_path, class: 'hover:text-gray-900' %> - <%= link_to 'Assignments', assignments_path, class: 'hover:text-gray-900' %> + <%= link_to 'Conferences', conferences_path, class: 'hover:text-gray-900 dark:hover:text-slate-200' %> + <%= link_to 'Assignments', assignments_path, class: 'hover:text-gray-900 dark:hover:text-slate-200' %> </div> </div> <div class="hidden md:flex items-center space-x-4 ml-0 lg:ml-8"> <% if user_signed_in? %> <span class="-mr-2 hidden lg:inline">logged in as</span> <%= render partial: 'application/user_avatar', locals: { user: current_user } %> - <%= link_to '<span class="hidden lg:inline">My </span>Profile'.html_safe, edit_user_registration_path, class: 'hover:text-gray-900', aria_label: "My Profile" %> - <%= link_to 'My Assignments', user_assignments_path(current_user), class: 'hover:text-gray-900' %> - <%= link_to 'Logout', destroy_user_session_path, data: { turbo_method: :delete }, class: 'hover:text-gray-900' %> + <%= link_to '<span class="hidden lg:inline">My </span>Profile'.html_safe, edit_user_registration_path, class: 'hover:text-gray-900 dark:hover:text-slate-200', aria_label: "My Profile" %> + <%= link_to 'My Assignments', user_assignments_path(current_user), class: 'hover:text-gray-900 dark:hover:text-slate-200' %> + <%= link_to 'Logout', destroy_user_session_path, data: { turbo_method: :delete }, class: 'hover:text-gray-900 dark:hover:text-slate-200' %> <% else %> <span class="px-2">not logged in</span> - <%= link_to 'Login', new_user_session_path, class: 'hover:text-gray-900' %> - <%= link_to 'Sign Up', new_user_registration_path, class: 'hover:text-gray-900' %> + <%= link_to 'Login', new_user_session_path, class: 'hover:text-gray-900 dark:hover:text-slate-200' %> + <%= link_to 'Sign Up', new_user_registration_path, class: 'hover:text-gray-900 dark:hover:text-slate-200' %> <% end %> </div> <div class="md:hidden"> - <button id="menu-button" class="text-gray-700 hover:text-gray-900 focus:outline-none" data-action="click->navigation#toggleMenu"> + <button id="menu-button" class="text-gray-700 dark:text-slate-400 hover:text-gray-900 dark:hover:text-white focus:outline-none" data-action="click->navigation#toggleMenu"> <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> </div> </div> - <div id="mobile-menu" class="absolute top-18 bg-slate-100 z-20 container mx-auto hidden md:hidden space-y-4 px-8 pb-4 shadow" data-navigation-target="mobileMenu"> - <%= link_to 'Conferences', conferences_path, class: 'block hover:text-gray-900' %> - <%= link_to 'Assignments', assignments_path, class: 'block hover:text-gray-900' %> + <div id="mobile-menu" class="absolute top-18 bg-slate-100 dark:bg-zinc-700 z-20 container mx-auto hidden md:hidden space-y-4 px-8 pb-4 shadow" data-navigation-target="mobileMenu"> + <%= link_to 'Conferences', conferences_path, class: 'block hover:text-gray-900 dark:hover:text-white' %> + <%= link_to 'Assignments', assignments_path, class: 'block hover:text-gray-900 dark:hover:text-white' %> <hr> <% if user_signed_in? %> <div>logged in as <%= render partial: 'application/user_avatar', locals: { user: current_user } %></div> - <%= link_to 'My Profile', edit_user_registration_path, class: 'block hover:text-gray-900' %> - <%= link_to 'My Assignments', user_assignments_path(current_user), class: 'block hover:text-gray-900' %> - <%= link_to 'Logout', destroy_user_session_path, data: { turbo_method: :delete }, class: 'block hover:text-gray-900' %> + <%= link_to 'My Profile', edit_user_registration_path, class: 'block hover:text-gray-900 dark:hover:text-white' %> + <%= link_to 'My Assignments', user_assignments_path(current_user), class: 'block hover:text-gray-900 dark:hover:text-white' %> + <%= link_to 'Logout', destroy_user_session_path, data: { turbo_method: :delete }, class: 'block hover:text-gray-900 dark:hover:text-white' %> <% else %> <div>not logged in</div> - <%= link_to 'Login', new_user_session_path, class: 'block hover:text-gray-900' %> - <%= link_to 'Sign Up', new_user_registration_path, class: 'block hover:text-gray-900' %> + <%= link_to 'Login', new_user_session_path, class: 'block hover:text-gray-900 dark:hover:text-white' %> + <%= link_to 'Sign Up', new_user_registration_path, class: 'block hover:text-gray-900 dark:hover:text-white ' %> <% end %> </div> </nav> diff --git a/app/views/sessions/_session.html.erb b/app/views/sessions/_session.html.erb index 623dd04fd51a2fe2bb0c3e4f599a5416ce68e151..b0584be9fa1e13b670837562f9931db3db6a9464 100644 --- a/app/views/sessions/_session.html.erb +++ b/app/views/sessions/_session.html.erb @@ -1,6 +1,6 @@ <% unassigned_users = User.all - session.assignments.collect(&:user) %> <%= turbo_frame_tag dom_id(session), method: "morph", class: "w-full", data: { controller: "session", language: session.language } do %> - <div class="session shadow hover:shadow-lg overflow-scroll text-sm w-full !h-full min-h-full hover:!min-h-max <%= session.translators_needed? ? "translators-needed" : "no-translators-needed" %> <%= session.backup_needed? ? "backup-needed" : "no-backup-needed" %> <%= session.assignees? ? "has-assignees" : "no-assignees" %> <%= (session.ends_at < Time.now ? "past" : "") %>"> + <div class="session dark:text-black shadow hover:shadow-lg overflow-scroll text-sm w-full !h-full min-h-full hover:!min-h-max <%= session.translators_needed? ? "translators-needed" : "no-translators-needed" %> <%= session.backup_needed? ? "backup-needed" : "no-backup-needed" %> <%= session.assignees? ? "has-assignees" : "no-assignees" %> <%= (session.ends_at < Time.now ? "past" : "") %>"> <h4> <small class="text-2xs uppercase font-bold <%= session.language=="de" ? "text-sky-700 border-sky-700" : "text-fuchsia-700 border-fuchsia-700" %> border bg-black/10 rounded-sm p-1 mr-1 lang-<%= session.language %>"><%= session.language %></small><% unless session.recorded %><span aria-label="Session is not recorded" title="Session is not recorded"><svg class="inline-block -mt-0.5 w-5 h-5" fill="#000000" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m255-1c-141 0-256 115-256 256s115 256 256 256 256-115 256-256-115-256-256-256zm0 17c63 0 121 25 163 65l-65 65-19-48c-0.85-2.6-4.3-5.1-7.7-5.1h-142c-3.4 0-6 1.7-7.7 5.1l-21 55h-49c-17 0-31 14-31 31v169c0 17 14 31 31 31h6.7l-34 34c-39-43-64-100-64-162 0-131 108-239 239-239zm60 239c0 33-26 60-60 60-14 0-26-4.4-36-12l84-83c7.3 9.9 12 22 12 36zm-119 0c0-33 26-60 60-60 14 0 26 4.5 36 12l-84 83c-7.4-9.9-12-22-12-36zm108-60c-13-11-30-17-48-17-43 0-77 34-77 77 0 18 6.2 35 17 48l-64 63h-25c-7.7 0-14-6-14-14v-169c0-7.7 6-14 14-14h55c3.4 0 6.8-2.6 7.7-5.1l21-55h130l19 50-36 36zm-97 120c13 11 30 17 48 17 43 0 77-34 77-77 0-18-6.1-35-16-48l38-38h49c7.7 0 14 6 14 14v169c0 7.7-6 14-14 14h-247l51-51zm48 179c-63 0-120-25-163-65l46-46h265c17 0 31-14 32-31v-169c0-17-14-31-31-31h-34l60-59c39 43 64 100 64 162-1e-3 131-108 239-239 239z"/><path d="m383 187c-9.4 0-17 7.7-17 17s7.7 17 17 17 17-7.7 17-17-7.7-17-17-17z"/></svg></span><% end %><%= render partial: 'shared/session_filedrop', locals: { session: } %> <%= link_to session.title, session.url, target: "_blank" %> diff --git a/app/views/sessions/show.html.erb b/app/views/sessions/show.html.erb index 39a2b539080bbdf53a0ad123bdb5962cec66db53..3ce9d3dd8f98f534d961bfe5db0521ed9b06d143 100644 --- a/app/views/sessions/show.html.erb +++ b/app/views/sessions/show.html.erb @@ -1,6 +1,6 @@ <div> <h6><%= link_to @session.conference.name, @session.conference %></h6> - <h1> + <h1 class="dark:text-red-500"> <%= @session.title %> <% unless @session.url.blank? %> <%= link_to "🔗 open in Fahrplan", @session.url, class: "ml-4 font-normal" %> @@ -15,9 +15,9 @@ <h3 class="mt-4">Comments <span class="font-normal">from Speakers' Filedrop</span></h2> <ul class="space-y-4 my-4"> <% @session.filedrop_comments.each do |comment| %> - <li class="bg-gray-100 shadow rounded-lg p-2"> - <div class="text-gray-900 whitespace-pre-wrap"><%= comment.body %></div> - <div class="text-gray-500 text-sm mt-2"> + <li class="text-gray-900 dark:text-slate-200 bg-gray-100 dark:bg-gray-600 shadow rounded-lg p-2"> + <div class="whitespace-pre-wrap"><%= comment.body %></div> + <div class="text-sm mt-2"> <%= comment.orig_created&.in_time_zone(@session.conference.time_zone || 'UTC')&.strftime("%B %d, %Y %H:%M") %> </div> </li> @@ -29,13 +29,13 @@ <h3 class="mt-4">Files <span class="font-normal">from Speakers' Filedrop</span></h3> <ul class="space-y-4 my-4"> <% @session.filedrop_files.each do |file| %> - <li class="bg-white shadow rounded-lg p-4"> + <li class="text-gray-500 dark:text-slate-400 shadow dark:shadow-gray-500 rounded-lg p-4"> <div class="flex flex-wrap justify-between items-start max-w-full"> <div> - <div class="text-gray-900 text-lg font-semibold"><%= file.name %></div> - <div class="text-gray-500 text-sm">Size: <%= number_to_human_size(file.size) %></div> - <div class="text-gray-500 text-sm">Date: <%=file.orig_created&.in_time_zone(@session.conference.time_zone || 'UTC')&.strftime("%B %d, %Y %H:%M") %></div> - <div class="text-gray-500 text-sm">Checksum: <%= file.checksum %></div> + <div class="text-gray-900 dark:text-slate-300 text-lg font-semibold"><%= file.name %></div> + <div class="text-sm">Size: <%= number_to_human_size(file.size) %></div> + <div class="text-sm">Date: <%=file.orig_created&.in_time_zone(@session.conference.time_zone || 'UTC')&.strftime("%B %d, %Y %H:%M") %></div> + <div class="text-sm">Checksum: <%= file.checksum %></div> </div> <div class="mt-2 sm:mt-0 flex-shrink-0"> <%= link_to 'Download', download_filedrop_file_path(file), class: "bg-blue-500 text-white px-3 py-2 rounded" %> diff --git a/app/views/shared/_flash.html.erb b/app/views/shared/_flash.html.erb index aff4cb59ee2cfe637e815914d48344ea6fba98e7..ef5b20ca0201cda70d3e07144c82b6dfda08c51b 100644 --- a/app/views/shared/_flash.html.erb +++ b/app/views/shared/_flash.html.erb @@ -1,4 +1,4 @@ -<div id="flash" class="relative top-0.5 md:top-16"> +<div id="flash" class="relative top-0.5 md:top-16 dark:text-black"> <% flash.each do |type, message| %> <div class="flash alert alert-<%= type %>"> <%= message %> diff --git a/app/views/speakers/show.html.erb b/app/views/speakers/show.html.erb index 5780d9ef422e010d6201f1c3b5cae3eecb3ddade..aa4a48497e6c726139a7651e27fad6d374eb4cee 100644 --- a/app/views/speakers/show.html.erb +++ b/app/views/speakers/show.html.erb @@ -1,5 +1,5 @@ <div> - <h1 class="font-bold text-4xl"><%= @speaker.name %></h1> + <h1 class="font-bold text-4xl dark:text-red-500"><%= @speaker.name %></h1> <h2 class="font-medium text-2xl"><%= @speaker.position %></h2> <p><%= @speaker.description.html_safe %></p> <% # = link_to "#{@speaker.name} at #{@speaker.conference.name}", %> diff --git a/app/views/users/leaderboard.html.erb b/app/views/users/leaderboard.html.erb index fb22a0c21453eb21c290e475ac826bd3d53613c8..0bf5ae0ab64d953afc95d7522e081c57deccd1f8 100644 --- a/app/views/users/leaderboard.html.erb +++ b/app/views/users/leaderboard.html.erb @@ -1,5 +1,5 @@ <div class="w-full"> - <h1 class="text-xl my-4">Leaderboard</h1> + <h1 class="text-xl my-4 dark:text-red-500">Leaderboard</h1> <dl class="w-full max-w-4xl mx-auto"> <% top_workload = @workload_data.values.max %> <% @workload_data.each_with_index do |(username, workload), index| %> diff --git a/app/views/users/login.html.erb b/app/views/users/login.html.erb index 7c99ca874b99aa6b93dd46f34928f750ed7d2554..6b50d7e65fdd53220e6d18e4b4d04253c507b199 100644 --- a/app/views/users/login.html.erb +++ b/app/views/users/login.html.erb @@ -1,5 +1,5 @@ <div> - <h1 class="font-bold text-4xl mb-8">Choose User</h1> + <h1 class="font-bold text-4xl mb-8 dark:text-red-500">Choose User</h1> <ul class="flex flex-wrap gap-2"> <% @users.each do |user| %> <li> diff --git a/app/views/users/profile.html.erb b/app/views/users/profile.html.erb index b79fdb86c2afaa8e3df9e7fd7153528a310986de..b58bff8f7a0c01e49bac23dfc83f68b89dacfd61 100644 --- a/app/views/users/profile.html.erb +++ b/app/views/users/profile.html.erb @@ -1,5 +1,5 @@ <div> - <h1 class="font-bold text-4xl">Profile</h1> + <h1 class="font-bold text-4xl dark:text-red-500">Profile</h1> <%= form_with(model: @user, url: update_profile_path, local: true) do |form| %> <div class="field"> diff --git a/config/tailwind.config.js b/config/tailwind.config.js index 06dd449652a9224fd86e90e08ccd7448d3bb7fde..71a0f8bfa4616b3b8b9358321f268b3cbb85f67c 100644 --- a/config/tailwind.config.js +++ b/config/tailwind.config.js @@ -7,6 +7,7 @@ module.exports = { './app/javascript/**/*.js', './app/views/**/*.{erb,haml,html,slim}' ], + darkMode: 'selector', theme: { extend: { keyframes: { diff --git a/db/migrate/20250101154742_add_darkmode_to_users.rb b/db/migrate/20250101154742_add_darkmode_to_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..72aaf7eea91851f26e4cf8395131768e863126ed --- /dev/null +++ b/db/migrate/20250101154742_add_darkmode_to_users.rb @@ -0,0 +1,5 @@ +class AddDarkmodeToUsers < ActiveRecord::Migration[7.1] + def change + add_column :users, :darkmode, :integer, null: false, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 707b0988ada51f26d198e3b70667b2cb7ccd14d7..d8b064ff212cc0c9f7ee77bfb39ea8c6a0fb18ab 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_12_30_120900) do +ActiveRecord::Schema[7.1].define(version: 2025_01_01_154742) do create_table "assignments", force: :cascade do |t| t.integer "user_id", null: false t.integer "session_id", null: false @@ -307,6 +307,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_12_30_120900) do t.string "invitation_token" t.string "languages_from" t.string "languages_to" + t.integer "darkmode", default: 0, null: false end add_foreign_key "assignments", "sessions"