diff --git a/app/assets/stylesheets/global.scss b/app/assets/stylesheets/global.scss index df7f93d..8f2fa35 100644 --- a/app/assets/stylesheets/global.scss +++ b/app/assets/stylesheets/global.scss @@ -95,8 +95,8 @@ button, input[type=submit] { border-radius: $border-radius; padding: 8px 16px; cursor: pointer; - - @media (prefers-color-scheme: dark) { + + [data-theme="dark"] & { color: $white; border: 1px solid $light; @@ -104,7 +104,7 @@ button, input[type=submit] { border-color: $white; } } - + } input[type=text] { @@ -114,7 +114,7 @@ input[type=text] { border-bottom: 1px solid $dark; outline: none; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { color: $light; border-bottom: 1px solid $light; } @@ -130,7 +130,7 @@ textarea { padding: 0 8px; resize: none; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { color: $light; } } @@ -139,14 +139,10 @@ textarea { display: none; } -@media (prefers-color-scheme: dark) { - //transition: all 1s; - - body { - background: $dark; - color: $light; - transition: ease all 1s; - } +body[data-theme="dark"] { + background: $dark; + color: $light; + transition: ease all 1s; a { color: $light; diff --git a/app/assets/stylesheets/home.scss b/app/assets/stylesheets/home.scss index f9512fb..f8f1075 100644 --- a/app/assets/stylesheets/home.scss +++ b/app/assets/stylesheets/home.scss @@ -20,7 +20,7 @@ border: 1px solid $dark; padding: 10px; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { border: 1px solid $light; } @@ -60,7 +60,7 @@ } } - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { .primary-link, .secondary-link { border-color: lightgray; @@ -79,5 +79,28 @@ margin-top: 20px; opacity: 0.4; } + + .theme-toggle { + border: none !important; + background: none; + padding: 4px 8px; + cursor: pointer; + color: gray; + font-size: 14px; + line-height: 30px; + + &:hover { + color: black; + background: lightgray; + border-radius: $border-radius; + } + + [data-theme="dark"] & { + &:hover { + color: white; + background: #202020; + } + } + } } diff --git a/app/assets/stylesheets/mixins.scss b/app/assets/stylesheets/mixins.scss index 22b679b..656e5c6 100644 --- a/app/assets/stylesheets/mixins.scss +++ b/app/assets/stylesheets/mixins.scss @@ -34,26 +34,22 @@ } @mixin logo-darkmode { - @media (prefers-color-scheme: dark) { - .logo { - &.light { - display: none; - } - &.dark { - display: block; - } + .logo { + &.light { + display: block; + } + &.dark { + display: none; } - - transition: ease all 1s; } - @media (prefers-color-scheme: light) { + [data-theme="dark"] & { .logo { &.light { - display: block; + display: none; } &.dark { - display: none; + display: block; } } @@ -84,7 +80,7 @@ } } - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { textarea { background: #202020; color: lightgray; diff --git a/app/assets/stylesheets/sessions/index.scss b/app/assets/stylesheets/sessions/index.scss index 9f9facf..3dff913 100644 --- a/app/assets/stylesheets/sessions/index.scss +++ b/app/assets/stylesheets/sessions/index.scss @@ -29,7 +29,7 @@ } } - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { .primary-link, .secondary-link { border-color: lightgray; diff --git a/app/assets/stylesheets/sessions/sessions.scss b/app/assets/stylesheets/sessions/sessions.scss index eedc8bc..ba72c9b 100644 --- a/app/assets/stylesheets/sessions/sessions.scss +++ b/app/assets/stylesheets/sessions/sessions.scss @@ -44,10 +44,9 @@ opacity: 1; } - @media (prefers-color-scheme: light) { - color: $dark; - } - @media (prefers-color-scheme: dark) { + color: $dark; + + [data-theme="dark"] & { color: $light; } @@ -127,7 +126,7 @@ border-radius: $border-radius; max-height: 100px; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { border: 1px solid $border-color-dark; } @@ -162,7 +161,7 @@ justify-content: flex-start; border-left: 1px solid $border-color-dark; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { border-left: 1px solid $border-color-dark; } @@ -181,9 +180,8 @@ background: black; color: white; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { background: rgba(255, 255, 255, 0.4); - // color: black; } } } diff --git a/app/assets/stylesheets/user/index.scss b/app/assets/stylesheets/user/index.scss index 53d991f..bf529d5 100644 --- a/app/assets/stylesheets/user/index.scss +++ b/app/assets/stylesheets/user/index.scss @@ -39,18 +39,36 @@ opacity: 1; } - @media (prefers-color-scheme: light) { - border: 1px solid black; - color: black; - } + border: 1px solid black; + color: black; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { border: 1px solid white; color: white; } } } + .theme-options { + display: flex; + gap: 16px; + margin-top: 5px; + + label { + display: flex; + align-items: center; + gap: 4px; + cursor: pointer; + } + + input[type="radio"] { + width: auto; + margin: 0; + padding: 0; + border: none; + } + } + .actions { input[type="submit"] { width: 100%; @@ -65,13 +83,11 @@ opacity: 1; } - @media (prefers-color-scheme: light) { - border: 1px solid black; - color: white; - background: black; - } + border: 1px solid black; + color: white; + background: black; - @media (prefers-color-scheme: dark) { + [data-theme="dark"] & { border: 1px solid white; color: black; background: white; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 857932b..49ab438 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,8 +1,13 @@ class ApplicationController < ActionController::Base before_action :authenticate_user! + before_action :configure_permitted_parameters, if: :devise_controller? protected + def configure_permitted_parameters + devise_parameter_sanitizer.permit(:account_update, keys: [:theme]) + end + rescue_from CanCan::AccessDenied do |_exception| redirect_to root_path, flash: { error: 'You are not authorized to perform this action.' } end diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb new file mode 100644 index 0000000..0a7ce20 --- /dev/null +++ b/app/controllers/users/registrations_controller.rb @@ -0,0 +1,7 @@ +class Users::RegistrationsController < Devise::RegistrationsController + protected + + def after_update_path_for(resource) + edit_user_registration_path + end +end diff --git a/app/controllers/users/themes_controller.rb b/app/controllers/users/themes_controller.rb new file mode 100644 index 0000000..5f61c44 --- /dev/null +++ b/app/controllers/users/themes_controller.rb @@ -0,0 +1,9 @@ +class Users::ThemesController < ApplicationController + def update + new_theme = params[:theme] + if %w[light dark system].include?(new_theme) + current_user.update!(theme: new_theme) + end + head :ok + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be79..6fd0189 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,5 @@ module ApplicationHelper + def theme_preference + current_user&.theme || "system" + end end diff --git a/app/javascript/application.js b/app/javascript/application.js index 7ca6576..12fff96 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -3,4 +3,7 @@ import '@hotwired/turbo-rails' import 'jquery' import 'sortablejs' -import 'controllers' \ No newline at end of file +import toastr from 'toastr' +import 'controllers' + +window.toastr = toastr \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 260c72e..cc5dda8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,6 +7,8 @@ class User < ApplicationRecord has_many :writing_sessions, dependent: :destroy has_many :stories, dependent: :destroy + validates :theme, inclusion: { in: %w[light dark system] } + after_create :subscribe_to_mailing def password_required? diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index a150a3e..c66f04c 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -2,6 +2,11 @@