diff --git a/app/frontend/styles/_data_box.scss b/app/frontend/styles/_data_box.scss new file mode 100644 index 000000000..0844ffa51 --- /dev/null +++ b/app/frontend/styles/_data_box.scss @@ -0,0 +1,66 @@ +.app-data-box-group { + @include govuk-font($size: 19); + font-weight: bold; + white-space: nowrap; +} + +@media (min-width: 54.0625em) { + .app-data-box-group-one-third { + display: flex; + justify-content: space-between; + column-gap: govuk-spacing(4); + width: 100%; + min-width: 733.33px; + } +} +@media (min-width: 54.0625em) { + .app-data-box-one-third { + width: 33.3333%; + float: left; + } +} +@media (min-width: 54.0625em) { + .app-data-box__underline { + min-width: 733.33px; + } +} +@media (min-width: 54.0625em) { + .app-data-box-group-one-half { + display: flex; + justify-content: space-between; + column-gap: govuk-spacing(4); + width: 100%; + min-width: 733.33px; + } +} +@media (min-width: 54.0625em) { + .app-data-box-one-half { + width: 50%; + float: left; + } +} +@media (min-width: 54.0625em) { + .app-data-box-one-half__underline { + min-width: 733.33px; + } +} + +.app-data-box__upper { + @include govuk-responsive-margin(2, "bottom"); + @include govuk-responsive-padding(4); + + background-color: govuk-colour("light-grey"); + color: govuk-colour("blue"); +} + +.app-data-box__lower { + @include govuk-responsive-margin(4, "bottom"); + @include govuk-responsive-padding(4); + + background-color: govuk-colour("blue"); +} + +.app-data-box__count { + font-size: 48px; + color: govuk-colour("blue"); +} diff --git a/app/frontend/styles/application.scss b/app/frontend/styles/application.scss index ddf368807..d405c3960 100644 --- a/app/frontend/styles/application.scss +++ b/app/frontend/styles/application.scss @@ -25,6 +25,7 @@ $govuk-breakpoints: ( @import "accessible-autocomplete"; @import "button"; @import "card"; +@import "data_box"; @import "document-list"; @import "feedback"; @import "filter"; diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb new file mode 100644 index 000000000..38891466e --- /dev/null +++ b/app/helpers/home_helper.rb @@ -0,0 +1,71 @@ +module HomeHelper + def data_count(user, type) + if user.data_provider? + case type + when "lettings" then user.lettings_logs.in_progress.where(created_by: user).count + when "sales" then user.sales_logs.in_progress.where(created_by: user).count + when "misc" then user.lettings_logs.completed.where(created_by: user).count + end + else + case type + when "lettings" then user.lettings_logs.in_progress.count + when "sales" then user.sales_logs.in_progress.count + when "schemes" then user.schemes.incomplete.count + end + end + end + + def heading_for_user_role(user) + ROLE_HEADINGS[user.role] + end + + def data_subheading(user, type) + case type + when "schemes" + "Incomplete schemes" + when "misc" + "Your completed lettings" + else + "#{user.role == 'data_provider' ? :"Your " : nil}#{type} in progress".capitalize + end + end + + def data_path(user, type) + if user.data_provider? + case type + when "lettings" then lettings_logs_path(status: [:in_progress], assigned_to: "you") + when "sales" then sales_logs_path(status: [:in_progress], assigned_to: "you") + when "misc" then lettings_logs_path(status: [:completed], assigned_to: "you") + end + else + case type + when "lettings" then lettings_logs_path(status: [:in_progress]) + when "sales" then sales_logs_path(status: [:in_progress]) + when "schemes" then schemes_path(status: [:incomplete]) + end + end + end + + def view_all_path(type) + case type + when "lettings" then clear_filters_path(filter_type: "lettings_logs") + when "sales" then clear_filters_path(filter_type: "sales_logs") + when "schemes" then clear_filters_path(filter_type: "schemes") + when "misc" then clear_filters_path(filter_type: "schemes") + end + end + + def view_all_text(type) + if type == "misc" + "View all schemes" + else + "View all #{type}" + end + end + + ROLE_HEADINGS = { + "data_provider" => "Complete your logs", + "data_coordinator" => "Manage your data", + "support" => "Manage all data", + }.freeze +end diff --git a/app/views/home/_data_box.html.erb b/app/views/home/_data_box.html.erb new file mode 100644 index 000000000..f1d04fb2f --- /dev/null +++ b/app/views/home/_data_box.html.erb @@ -0,0 +1,9 @@ +
+
+ <%= govuk_link_to data_count(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state govuk-link--no-underline" %> +
+ <%= govuk_link_to data_subheading(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state" %> +
+
+ <%= govuk_link_to view_all_text(type), view_all_path(type), class: "govuk-link--inverse" %> +
diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index e87fde287..87e058969 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -1,8 +1,56 @@ -

<%= "Welcome back, #{@current_user.name}" %>

-
- <%= render partial: "layouts/collection_resources" %> -
- <%= render partial: "home/upcoming_deadlines" %> +
+
+
+ <%= "Welcome back, #{@current_user.name}" %> +

<%= heading_for_user_role(@current_user) %>

+
+
+
+ <% if @current_user.support? || (@current_user.data_coordinator? && @current_user.sales_logs.present?) %> +
+
+ <%= render partial: "home/data_box", locals: { type: "lettings" } %> +
+
+ <%= render partial: "home/data_box", locals: { type: "sales" } %> +
+
+ <%= render partial: "home/data_box", locals: { type: "schemes" } %> +
+
+ <% else %> +
+
+ <%= render partial: "home/data_box", locals: { type: "lettings" } %> +
+ <% if @current_user.data_coordinator? %> +
+ <%= render partial: "home/data_box", locals: { type: "schemes" } %> +
+ <% elsif @current_user.sales_logs.present? %> +
+ <%= render partial: "home/data_box", locals: { type: "sales" } %> +
+ <% else %> +
+ <%= render partial: "home/data_box", locals: { type: "misc" } %> +
+ <% end %> +
+ <% end %> +
+
+
+
+
+
+
+
+ <%= render partial: "layouts/collection_resources" %> +
+ <%= render partial: "home/upcoming_deadlines" %> +
+
diff --git a/spec/features/home_page_spec.rb b/spec/features/home_page_spec.rb new file mode 100644 index 000000000..908961e33 --- /dev/null +++ b/spec/features/home_page_spec.rb @@ -0,0 +1,158 @@ +require "rails_helper" +require_relative "form/helpers" + +RSpec.describe "Home Page Features" do + include Helpers + + context "when the user is a data provider" do + let(:user) { FactoryBot.create(:user, name: "Provider") } + + before do + create_list(:lettings_log, 6, :in_progress, owning_organisation: user.organisation, created_by: user) + create_list(:lettings_log, 2, :in_progress, owning_organisation: user.organisation) + create_list(:lettings_log, 4, :completed, owning_organisation: user.organisation, created_by: user) + create_list(:lettings_log, 2, :completed) + sign_in user + visit("/") + end + + it "displays the correct welcome text" do + expect(page).to have_current_path("/") + expect(page).to have_content("Welcome back, Provider") + expect(page).to have_content("Complete your logs") + end + + context "when their organisation has submitted sales logs" do + before do + create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation, created_by: user) + create_list(:sales_log, 3, :completed, owning_organisation: user.organisation, created_by: user) + visit("/") + end + + it "displays correct data boxes, counts and links" do + data_boxes = page.find_all(class: "app-data-box-one-half") + expect(data_boxes.count).to eq(2) + expect(data_boxes[0].all("a").map(&:text)).to eq(["6", "Your lettings in progress", "View all lettings"]) + expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress], assigned_to: "you"), lettings_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "lettings_logs")]) + expect(data_boxes[1].all("a").map(&:text)).to eq(["5", "Your sales in progress", "View all sales"]) + expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress], assigned_to: "you"), sales_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "sales_logs")]) + end + end + + context "when their organisation has never submitted sales logs" do + before do + visit("/") + end + + it "displays correct data boxes, counts and links" do + data_boxes = page.find_all(class: "app-data-box-one-half") + expect(data_boxes.count).to eq(2) + expect(data_boxes[0].all("a").map(&:text)).to eq(["6", "Your lettings in progress", "View all lettings"]) + expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress], assigned_to: "you"), lettings_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "lettings_logs")]) + expect(data_boxes[1].all("a").map(&:text)).to eq(["4", "Your completed lettings", "View all schemes"]) + expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:completed], assigned_to: "you"), lettings_logs_path(status: [:completed], assigned_to: "you"), clear_filters_path(filter_type: "schemes")]) + end + end + end + + context "when the user is a data coordinator" do + before do + create_list(:lettings_log, 6, :in_progress, owning_organisation: user.organisation) + create_list(:lettings_log, 2, :in_progress, owning_organisation: user.organisation, created_by: user) + create_list(:lettings_log, 4, :completed, owning_organisation: user.organisation) + create_list(:lettings_log, 2, :completed) + create_list(:scheme, 1, :incomplete, owning_organisation: user.organisation) + sign_in user + visit("/") + end + + let(:user) { FactoryBot.create(:user, :data_coordinator, name: "Coordinator") } + + it "displays the correct welcome text" do + expect(page).to have_current_path("/") + expect(page).to have_content("Welcome back, Coordinator") + expect(page).to have_content("Manage your data") + end + + context "when their organisation has submitted sales logs" do + before do + create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation) + create_list(:sales_log, 3, :completed, owning_organisation: user.organisation) + visit("/") + end + + it "displays correct data boxes, counts and links" do + data_boxes = page.find_all(class: "app-data-box-one-third") + expect(data_boxes.count).to eq(3) + expect(data_boxes[0].all("a").map(&:text)).to eq(["8", "Lettings in progress", "View all lettings"]) + expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")]) + expect(data_boxes[1].all("a").map(&:text)).to eq(["5", "Sales in progress", "View all sales"]) + expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress]), sales_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "sales_logs")]) + expect(data_boxes[2].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"]) + expect(data_boxes[2].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")]) + end + end + + context "when their organisation has never submitted sales logs" do + before do + visit("/") + end + + it "displays correct data boxes, counts and links" do + data_boxes = page.find_all(class: "app-data-box-one-half") + expect(data_boxes.count).to eq(2) + expect(data_boxes[0].all("a").map(&:text)).to eq(["8", "Lettings in progress", "View all lettings"]) + expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")]) + expect(data_boxes[1].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"]) + expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")]) + end + end + end + + context "when the user is a support user" do + let(:support_user) { FactoryBot.create(:user, :support, name: "Support") } + let(:notify_client) { instance_double(Notifications::Client) } + let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" } + let(:devise_notify_mailer) { DeviseNotifyMailer.new } + let(:otp) { "999111" } + + before do + create_list(:lettings_log, 2, :in_progress) + create_list(:lettings_log, 1, :completed) + create_list(:sales_log, 3, :in_progress) + create_list(:sales_log, 1, :completed) + create_list(:scheme, 1, :incomplete) + completed_scheme = create(:scheme) + create(:location, scheme: completed_scheme) + allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) + allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) + allow(Devise).to receive(:friendly_token).and_return(confirmation_token) + allow(notify_client).to receive(:send_email).and_return(true) + allow(SecureRandom).to receive(:random_number).and_return(otp) + visit("/lettings-logs") + fill_in("user[email]", with: support_user.email) + fill_in("user[password]", with: support_user.password) + click_button("Sign in") + fill_in("code", with: otp) + click_button("Submit") + visit("/") + end + + it "displays the correct welcome text" do + expect(page).to have_current_path("/") + expect(page).to have_content("Welcome back, Support") + expect(page).to have_content("Manage all data") + end + + it "displays correct data boxes, counts and links" do + data_boxes = page.find_all(class: "app-data-box-one-third") + expect(data_boxes.count).to eq(3) + expect(data_boxes[0].all("a").map(&:text)).to eq(["2", "Lettings in progress", "View all lettings"]) + expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")]) + expect(data_boxes[1].all("a").map(&:text)).to eq(["3", "Sales in progress", "View all sales"]) + expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress]), sales_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "sales_logs")]) + expect(data_boxes[2].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"]) + expect(data_boxes[2].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")]) + end + end +end