diff --git a/backend/app/assets/config/solidus_backend_manifest.js b/backend/app/assets/config/solidus_backend_manifest.js index 49d989282a6..71a745f44f1 100644 --- a/backend/app/assets/config/solidus_backend_manifest.js +++ b/backend/app/assets/config/solidus_backend_manifest.js @@ -1,9 +1,7 @@ //= link_tree ../images +//= link_tree "../stylesheets/spree/backend/themes" .css //= link spree/backend/all.js //= link spree/backend/all.css //= link solidus_admin/select2_locales - -//= link spree/backend/themes/classic.css -//= link spree/backend/themes/solidus_admin.css diff --git a/backend/app/assets/stylesheets/spree/backend/components/_navigation.scss b/backend/app/assets/stylesheets/spree/backend/components/_navigation.scss index c8f22ae2610..a10809a5c21 100644 --- a/backend/app/assets/stylesheets/spree/backend/components/_navigation.scss +++ b/backend/app/assets/stylesheets/spree/backend/components/_navigation.scss @@ -122,6 +122,22 @@ nav.menu { @media print { display: none } + + + .dark-only { + display: none; + @media (prefers-color-scheme: dark) { + display: block; + } + } + + .light-only { + display: block; + @media (prefers-color-scheme: dark) { + display: none; + } + } + } .admin-nav-header { @@ -301,7 +317,8 @@ nav.menu { } .admin-navbar-selection { - margin: 0 1.5em; + padding: 0 1.5em; + width: 100%; position: relative; overflow: hidden; display: inline-flex; @@ -323,7 +340,7 @@ nav.menu { padding: .5rem 0 .5rem .25rem; } - .admin-nav-hidden & { + .admin-nav-hidden & { position: relative; select { diff --git a/backend/app/assets/stylesheets/spree/backend/components/_navigation_solidus_admin.scss b/backend/app/assets/stylesheets/spree/backend/components/_navigation_solidus_admin.scss index ee2d567cbd3..ae54248ec34 100644 --- a/backend/app/assets/stylesheets/spree/backend/components/_navigation_solidus_admin.scss +++ b/backend/app/assets/stylesheets/spree/backend/components/_navigation_solidus_admin.scss @@ -19,6 +19,20 @@ $color-navbar-hover: $color-navbar !default; min-height: 100vh; border-right: $color-light-accent 1px solid; + .dark-only { + display: none; + @media (prefers-color-scheme: dark) { + display: block; + } + } + + .light-only { + display: none; + @media (prefers-color-scheme: light) { + display: block; + } + } + &--wrapper { position: absolute; top: 0; diff --git a/backend/app/assets/stylesheets/spree/backend/themes/classic_dark.css.scss b/backend/app/assets/stylesheets/spree/backend/themes/classic_dark.css.scss new file mode 100644 index 00000000000..5549b4c636f --- /dev/null +++ b/backend/app/assets/stylesheets/spree/backend/themes/classic_dark.css.scss @@ -0,0 +1,16 @@ +@import 'spree/backend/themes/classic'; + +html { + background-color: #fff; + color: #fff; + -webkit-filter: invert(100%); + filter: invert(100%) hue-rotate(180deg); + + img { + filter: invert(100%) hue-rotate(-180deg); + } + + .brand-link img { + filter: invert(0%) hue-rotate(0deg); + } +} diff --git a/backend/app/assets/stylesheets/spree/backend/themes/classic_dimmed.css.scss b/backend/app/assets/stylesheets/spree/backend/themes/classic_dimmed.css.scss new file mode 100644 index 00000000000..8dfc79471f8 --- /dev/null +++ b/backend/app/assets/stylesheets/spree/backend/themes/classic_dimmed.css.scss @@ -0,0 +1,16 @@ +@import 'spree/backend/themes/classic'; + +html { + background-color: #fff; + color: #fff; + -webkit-filter: invert(85%); + filter: invert(85%) hue-rotate(180deg); + + img { + filter: invert(100%) hue-rotate(-180deg); + } + + .brand-link img { + filter: invert(0%) hue-rotate(0deg); + } +} diff --git a/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin.css.scss b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin.css.scss index 17955943be8..636633c325b 100644 --- a/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin.css.scss +++ b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin.css.scss @@ -1,6 +1,7 @@ @import "spree/backend/globals"; @import "./solidus_admin/variables"; +@import "./solidus_admin/colors"; @import "spree/backend/vendor"; @import "spree/backend/shared"; diff --git a/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin/_tables.scss b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin/_tables.scss index 9309eb426d7..618155a12f0 100644 --- a/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin/_tables.scss +++ b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin/_tables.scss @@ -1,3 +1,5 @@ +@import "./colors"; + table.index { // Borders border-collapse: separate; diff --git a/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin_dark.css.scss b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin_dark.css.scss new file mode 100644 index 00000000000..4728b02308d --- /dev/null +++ b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin_dark.css.scss @@ -0,0 +1,16 @@ +@import "./solidus_admin"; + +html { + background-color: #fff; + color: #fff; + -webkit-filter: invert(100%); + filter: invert(100%) hue-rotate(180deg); + + img { + filter: invert(100%) hue-rotate(-180deg); + } + + .brand-link img { + filter: invert(0%) hue-rotate(0deg); + } +} diff --git a/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin_dimmed.css.scss b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin_dimmed.css.scss new file mode 100644 index 00000000000..34b20be1d4e --- /dev/null +++ b/backend/app/assets/stylesheets/spree/backend/themes/solidus_admin_dimmed.css.scss @@ -0,0 +1,16 @@ +@import "./solidus_admin"; + +html { + background-color: #fff; + color: #fff; + -webkit-filter: invert(85%); + filter: invert(85%) hue-rotate(180deg); + + img { + filter: invert(100%) hue-rotate(-180deg); + } + + .brand-link img { + filter: invert(0%) hue-rotate(0deg); + } +} diff --git a/backend/app/controllers/spree/admin/locale_controller.rb b/backend/app/controllers/spree/admin/locale_controller.rb index 59397f1916e..69fe5a3e7f7 100644 --- a/backend/app/controllers/spree/admin/locale_controller.rb +++ b/backend/app/controllers/spree/admin/locale_controller.rb @@ -11,9 +11,15 @@ def set if locale_is_available?(requested_locale) I18n.locale = requested_locale session[set_user_language_locale_key] = requested_locale - render json: { locale: requested_locale, location: spree.admin_url } + respond_to do |format| + format.json { render json: { locale: requested_locale, location: spree.admin_url } } + format.html { redirect_back_or_to spree.admin_url, notice: t('spree.locale_changed') } + end else - render json: { locale: I18n.locale }, status: 404 + respond_to do |format| + format.json { render json: { locale: I18n.locale }, status: 404 } + format.html { redirect_back_or_to spree.admin_url, error: t('spree.error') } + end end end diff --git a/backend/app/controllers/spree/admin/theme_controller.rb b/backend/app/controllers/spree/admin/theme_controller.rb new file mode 100644 index 00000000000..b00852afe91 --- /dev/null +++ b/backend/app/controllers/spree/admin/theme_controller.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Spree + module Admin + class ThemeController < Spree::Admin::BaseController + skip_before_action :authorize_admin, only: [:set] + + def set + requested_theme = params[:switch_to_theme].presence + + # Avoid interpolating user content into the session key + system_theme = params[:system_theme].presence == "dark" ? "dark" : "light" + session_key = :"admin_#{system_theme}_theme" + + if theme_is_available?(requested_theme) + session[session_key] = requested_theme + redirect_back_or_to spree.admin_url, notice: t('spree.theme_changed') + else + redirect_back_or_to spree.admin_url, error: t('spree.error') + end + end + + private + + def theme_is_available?(theme) + theme && Spree::Backend::Config.themes.key?(theme.to_sym) + end + end + end +end diff --git a/backend/app/views/spree/admin/shared/_head.html.erb b/backend/app/views/spree/admin/shared/_head.html.erb index 1287add73a8..4bcfd5a455b 100644 --- a/backend/app/views/spree/admin/shared/_head.html.erb +++ b/backend/app/views/spree/admin/shared/_head.html.erb @@ -6,7 +6,8 @@ <%= admin_page_title %> <%= favicon_link_tag 'favicon.ico' %> -<%= stylesheet_link_tag Spree::Backend::Config.theme_path, media: 'all', data: {turbolinks_track: 'reload'} %> +<%= stylesheet_link_tag Spree::Backend::Config.theme_path(session[:admin_light_theme]), media: '(prefers-color-scheme: light)', data: {turbolinks_track: 'reload'} %> +<%= stylesheet_link_tag Spree::Backend::Config.theme_path(session[:admin_dark_theme]), media: '(prefers-color-scheme: dark)', data: {turbolinks_track: 'reload'} %> <%= javascript_include_tag 'spree/backend/all', data: {turbolinks_track: 'reload'} %> <%- if Rails.env.test? %> diff --git a/backend/app/views/spree/admin/shared/_js_locale_data.html.erb b/backend/app/views/spree/admin/shared/_js_locale_data.html.erb index b92b6ca38c2..6727676860e 100644 --- a/backend/app/views/spree/admin/shared/_js_locale_data.html.erb +++ b/backend/app/views/spree/admin/shared/_js_locale_data.html.erb @@ -33,7 +33,7 @@ -<% if I18n.locale != :en %> - <%= javascript_include_tag "solidus_admin/select2_locales/select2_locale_#{I18n.locale}", - data: {turbolinks_track: 'reload'} %> +<% if I18n.locale != :en && I18n.locale %> + <% select2_locale_path = "solidus_admin/select2_locales/select2_locale_#{I18n.locale}" %> + <%= javascript_include_tag select2_locale_path, data: {turbolinks_track: 'reload'} if Rails.application.assets.find_asset(select2_locale_path) %> <% end %> diff --git a/backend/app/views/spree/admin/shared/_locale_selection.html.erb b/backend/app/views/spree/admin/shared/_locale_selection.html.erb index 3359def1a9d..e9dc4bbcfab 100644 --- a/backend/app/views/spree/admin/shared/_locale_selection.html.erb +++ b/backend/app/views/spree/admin/shared/_locale_selection.html.erb @@ -1,16 +1,14 @@ -<% available_locales = Spree.i18n_available_locales %> -<% if available_locales.size > 1 %> - +<% available_locale_options_for_select = Spree.i18n_available_locales.map { + [I18n.t('spree.i18n.this_file_language', locale: _1, default: _1.to_s, fallback: false), _1] +}.sort %> + +<% if available_locale_options_for_select.size > 1 %> + <%= form_tag(admin_set_locale_path(format: :html), method: :put, style: "width: 100%;") do %> + + <% end %> <% end %> diff --git a/backend/app/views/spree/admin/shared/_locale_selection_solidus_admin.html.erb b/backend/app/views/spree/admin/shared/_locale_selection_solidus_admin.html.erb new file mode 100644 index 00000000000..c56de0ca7ac --- /dev/null +++ b/backend/app/views/spree/admin/shared/_locale_selection_solidus_admin.html.erb @@ -0,0 +1,17 @@ +<% available_locale_options_for_select = Spree.i18n_available_locales.map { + [I18n.t('spree.i18n.this_file_language', locale: _1, default: _1.to_s, fallback: false), _1] +}.sort %> + +<% if available_locale_options_for_select.size > 1 %> +
  • + <%= form_tag(admin_set_locale_path(format: :html), method: :put, style: "width: 100%;") do %> + + <% end %> +
  • +<% end %> diff --git a/backend/app/views/spree/admin/shared/_navigation.html.erb b/backend/app/views/spree/admin/shared/_navigation.html.erb index 9f15ae2861c..36bb36e72e3 100644 --- a/backend/app/views/spree/admin/shared/_navigation.html.erb +++ b/backend/app/views/spree/admin/shared/_navigation.html.erb @@ -7,6 +7,7 @@ <%= t('spree.minimize_menu') %> <% end %> <%= render partial: 'spree/admin/shared/locale_selection' %> + <%= render partial: 'spree/admin/shared/theme_selection' %> <% if lookup_context.exists?('spree/admin/shared/_navigation_footer') %> <%= render partial: 'spree/admin/shared/navigation_footer' %> <% else %> diff --git a/backend/app/views/spree/admin/shared/_navigation_solidus_admin.html.erb b/backend/app/views/spree/admin/shared/_navigation_solidus_admin.html.erb index 954af2e7250..44af1123fff 100644 --- a/backend/app/views/spree/admin/shared/_navigation_solidus_admin.html.erb +++ b/backend/app/views/spree/admin/shared/_navigation_solidus_admin.html.erb @@ -49,32 +49,8 @@