diff --git a/app/controllers/spree/admin/base_controller.rb b/app/controllers/spree/admin/base_controller.rb index e542b797be..4dbfccc8b4 100644 --- a/app/controllers/spree/admin/base_controller.rb +++ b/app/controllers/spree/admin/base_controller.rb @@ -19,6 +19,7 @@ module Spree before_action :authorize_admin before_action :set_locale before_action :warn_invalid_order_cycles, if: :html_request? + before_action :check_updated_tos_accepted, if: :html_request? # Warn the user when they have an active order cycle with hubs that are not ready # for checkout (ie. does not have valid shipping and payment methods). @@ -110,6 +111,24 @@ module Spree name = controller_name.classify "::Api::Admin::#{prefix}#{name}Serializer".constantize end + + def check_updated_tos_accepted + @terms_of_service_banner = false + + return unless spree_user_signed_in? + + return if accepted_tos? + + @terms_of_service_banner = true + end + + def accepted_tos? + file_uploaded_at = TermsOfServiceFile.updated_at + + current_spree_user.terms_of_service_accepted_at.present? && + current_spree_user.terms_of_service_accepted_at > file_uploaded_at && + current_spree_user.terms_of_service_accepted_at < DateTime.now + end end end end diff --git a/app/views/admin/_terms_of_service_banner.html.haml b/app/views/admin/_terms_of_service_banner.html.haml new file mode 100644 index 0000000000..17b3603986 --- /dev/null +++ b/app/views/admin/_terms_of_service_banner.html.haml @@ -0,0 +1,9 @@ +.banner-container + - if @terms_of_service_banner == true + %div{ class: "terms-of-service-banner", data: { controller: "terms-of-service-banner", "terms-of-service-banner-url-value": accept_terms_of_services_admin_user_path(current_spree_user&.id) }} + .column-left + %p= t("admin.terms_of_service_have_been_updated_html", tos_link: link_to(t("admin.terms_of_service"), TermsOfServiceFile.current_url, target: "_blank")) + .column-right + %button{ data: { action: "click->terms-of-service-banner#accept click->terms-of-service-banner#close_banner" } } + = t("admin.accept_terms_of_service") + diff --git a/app/views/spree/layouts/_admin_body.html.haml b/app/views/spree/layouts/_admin_body.html.haml index 76f1f77e26..e730e1286b 100644 --- a/app/views/spree/layouts/_admin_body.html.haml +++ b/app/views/spree/layouts/_admin_body.html.haml @@ -59,6 +59,8 @@ %span= yield :sidebar_title = yield :sidebar + = render partial: "admin/terms_of_service_banner" + %script = raw "Spree.api_key = \"#{spree_current_user.try(:spree_api_key).to_s}\";" diff --git a/app/webpacker/css/admin/all.scss b/app/webpacker/css/admin/all.scss index 942e7422e4..56d522ae75 100644 --- a/app/webpacker/css/admin/all.scss +++ b/app/webpacker/css/admin/all.scss @@ -112,6 +112,7 @@ @import "side_menu"; @import "tables"; @import "tag_rules"; +@import "terms_of_service_banner"; @import "terms_of_service_files"; @import "validation"; @import "variant_overrides"; diff --git a/app/webpacker/css/admin/terms_of_service_banner.scss b/app/webpacker/css/admin/terms_of_service_banner.scss new file mode 100644 index 0000000000..ec46c268e0 --- /dev/null +++ b/app/webpacker/css/admin/terms_of_service_banner.scss @@ -0,0 +1,27 @@ +.banner-container { + position: fixed; + bottom: 0; + left: 0; + width: 100%; + z-index: 1000; + + .terms-of-service-banner { + padding: 18px; + text-align: center; + font-size: 120%; + color: white; + font-weight: 600; + margin-top: 0; + background-color: rgba($color-notice, 0.8); + display: flex; + + .column-left { + width: 70%; + } + + .column-right { + width: 30%; + text-align: center; + } + } +} diff --git a/config/locales/en.yml b/config/locales/en.yml index c1505a3377..7963e7c36e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -653,6 +653,9 @@ en: available_units: "Available Units" + terms_of_service_have_been_updated_html: "Terms of Service have been updated: %{tos_link}" + terms_of_service: Terms of Service + accept_terms_of_service: Accept terms of service shopfront_settings: embedded_shopfront_settings: "Embedded Shopfront Settings" enable_embedded_shopfronts: "Enable Embedded Shopfronts" diff --git a/spec/requests/spree/admin/overview_spec.rb b/spec/requests/spree/admin/overview_spec.rb new file mode 100644 index 0000000000..b75c62539d --- /dev/null +++ b/spec/requests/spree/admin/overview_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "/admin", type: :request do + let(:enterprise) { create(:supplier_enterprise, name: "Feedme") } + let(:enterprise_user) { create(:user, enterprise_limit: 1) } + + before do + enterprise_user.enterprise_roles.build(enterprise:).save + sign_in enterprise_user + end + + describe "GET /admin" do + before do + allow(TermsOfServiceFile).to receive(:updated_at).and_return(2.hours.ago) + end + + it "loads the dashboard page" do + get "/admin" + + expect(response).to render_template("spree/admin/overview/single_enterprise_dashboard") + end + + # The banner will show on all admin page, we are just testing it here + describe "terms of service updated banner" do + context "when terms of service has been updated" do + it "shows accept new ToS banner" do + enterprise_user.update(terms_of_service_accepted_at: nil) + + get "/admin" + + expect(response.body).to include("Terms of Service have been updated") + end + + context "when user has accepted new terms of service" do + it "doesn't show accept new ToS banner" do + enterprise_user.update(terms_of_service_accepted_at: 1.hour.ago) + + get "/admin" + + expect(response.body).to_not include("Terms of Service have been updated") + end + end + + # Shouldn't be possible + context "when user has accepted new terms of service in the future" do + it "shows accept new ToS banner" do + enterprise_user.update(terms_of_service_accepted_at: 1.hour.from_now) + + get "/admin" + + expect(response.body).to include("Terms of Service have been updated") + end + end + end + end + end +end