diff --git a/app/components/routes_section_component/view.html.erb b/app/components/routes_section_component/view.html.erb
new file mode 100644
index 000000000..db788650c
--- /dev/null
+++ b/app/components/routes_section_component/view.html.erb
@@ -0,0 +1,3 @@
+
<%= t("pages.routes_section.heading") %>
+<%= t("pages.routes_section.#{message_key}", routes_path: routes_path(form_id: @page.form_id, anchor: @page.page_position_id)) %>
+
diff --git a/app/components/routes_section_component/view.rb b/app/components/routes_section_component/view.rb
new file mode 100644
index 000000000..1542e2daa
--- /dev/null
+++ b/app/components/routes_section_component/view.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module RoutesSectionComponent
+ class View < ApplicationComponent
+ include Rails.application.routes.url_helpers
+
+ def initialize(page:, draft_question:)
+ super()
+ @page = page
+ @draft_question = draft_question
+ end
+
+ def render?
+ message_key.present?
+ end
+
+ def message_key
+ @message_key ||= if @page.routing_conditions.any?
+ "has_routes_html"
+ elsif selection_question_with_one_option_only?
+ "conditional_routes_html"
+ elsif @page.has_next_page?
+ "skip_questions_html"
+ end
+ end
+
+ private
+
+ def selection_question_with_one_option_only?
+ @draft_question.answer_type == "selection" &&
+ @draft_question.answer_settings[:only_one_option] == "true" &&
+ @draft_question.answer_settings[:selection_options].length <= 10
+ end
+ end
+end
diff --git a/app/views/pages/_form.html.erb b/app/views/pages/_form.html.erb
index bb4b64612..0e5383f22 100644
--- a/app/views/pages/_form.html.erb
+++ b/app/views/pages/_form.html.erb
@@ -52,6 +52,8 @@
<%= t("pages.answer_settings") %>
<%= render PageSettingsSummaryComponent::View.new(draft_question:, errors: question_input.errors) %>
+ <%= render RoutesSectionComponent::View.new(page: page_object, draft_question:) unless is_new_page %>
+
-
<%= f.govuk_submit t('pages.submit_save'), class: "govuk-!-margin-bottom-3", name: "submit_type", value: "save" %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 5f13ac5f5..0e1ed0b7d 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -2070,6 +2070,11 @@ en:
skip_later: If you need to, you can make them skip one or more questions that only people on route 1 need to answer.
will_continue_to: People who select any other answer will continue to question %{next_question_number} and through the rest of the form.
will_continue_to_end_of_form: People who select any other answer will continue to the end of the form.
+ routes_section:
+ conditional_routes_html: If you need people to skip some questions or exit the form based on their answer to this question, edit question routes.
+ has_routes_html: 'This question has routes: Edit question routes'
+ heading: Routes
+ skip_questions_html: If you need people to skip some questions after this one, edit question routes.
submit_save: Save question
payment_link_input:
body_html: |
diff --git a/spec/components/routes_section_component/routes_section_component_preview.rb b/spec/components/routes_section_component/routes_section_component_preview.rb
new file mode 100644
index 000000000..89e8c4f6c
--- /dev/null
+++ b/spec/components/routes_section_component/routes_section_component_preview.rb
@@ -0,0 +1,24 @@
+class RoutesSectionComponent::RoutesSectionComponentPreview < ViewComponent::Preview
+ include FactoryBot::Syntax::Methods
+
+ def with_selection_question_with_one_option_only
+ page = build(:page, id: 1, form_id: 1, position: 1, routing_conditions: [])
+ draft_question = build(:selection_draft_question, only_one_option: "true")
+ render(RoutesSectionComponent::View.new(page:, draft_question:))
+ end
+
+ def with_question_that_is_not_selection_with_one_option_only
+ page = build(:page, id: 1, form_id: 1, position: 1, routing_conditions: [])
+ draft_question = build(:draft_question, answer_type: "email")
+ page.define_singleton_method(:has_next_page?) { true }
+
+ render(RoutesSectionComponent::View.new(page:, draft_question:))
+ end
+
+ def with_routes
+ condition = build(:condition, id: 1, routing_page_id: 1, check_page_id: 1, answer_value: "Option 1", skip_to_end: true)
+ page = build(:page, id: 1, form_id: 1, position: 1, routing_conditions: [condition])
+ draft_question = build(:selection_draft_question, only_one_option: "true")
+ render(RoutesSectionComponent::View.new(page:, draft_question:))
+ end
+end
diff --git a/spec/components/routes_section_component/view_spec.rb b/spec/components/routes_section_component/view_spec.rb
new file mode 100644
index 000000000..8e3e3b834
--- /dev/null
+++ b/spec/components/routes_section_component/view_spec.rb
@@ -0,0 +1,119 @@
+require "rails_helper"
+
+RSpec.describe RoutesSectionComponent::View, type: :component do
+ include Rails.application.routes.url_helpers
+
+ let(:question_page) { create :page }
+ let(:form) { create :form, pages: [question_page, create(:page)] }
+ let(:draft_question) { build :draft_question, answer_type: "email" }
+ let(:question_routes_path) { routes_path(form_id: form.id, anchor: question_page.page_position_id) }
+
+ before do
+ form
+ render_inline(described_class.new(page: question_page, draft_question:))
+ end
+
+ context "when the question has no routes" do
+ context "when the question is a selection question with one option only" do
+ let(:draft_question) { build :selection_draft_question, only_one_option: "true" }
+
+ it "contains the routes heading" do
+ expect(page).to have_css("h2", text: I18n.t("pages.routes_section.heading"))
+ end
+
+ it "contains a link to the question's routes" do
+ expect(page).to have_link("edit question routes", href: question_routes_path)
+ end
+ end
+
+ context "when the question is a selection question with one option only and more than 10 options" do
+ let(:draft_question) { build :selection_draft_question, only_one_option: "true", selection_options: (1..11).map { |i| { name: "Option #{i}", value: "option #{i}" } } }
+
+ it "contains the text about skipping questions" do
+ expect(page).to have_text("If you need people to skip some questions after this one, edit question routes.")
+ end
+
+ context "when the question is the last question in the form" do
+ let(:form) { create :form, pages: [question_page] }
+
+ it "does not render" do
+ expect(page).not_to have_css("h2", text: I18n.t("pages.routes_section.heading"))
+ end
+ end
+ end
+
+ context "when the question is a selection question with multiple options" do
+ let(:draft_question) { build :selection_draft_question, only_one_option: "false" }
+
+ it "contains the routes heading" do
+ expect(page).to have_css("h2", text: I18n.t("pages.routes_section.heading"))
+ end
+
+ it "contains the text about skipping questions" do
+ expect(page).to have_text("If you need people to skip some questions after this one, edit question routes.")
+ end
+
+ it "contains a link to the question's routes" do
+ expect(page).to have_link("edit question routes", href: question_routes_path)
+ end
+ end
+
+ context "when the question is not a selection question" do
+ it "contains the routes heading" do
+ expect(page).to have_css("h2", text: I18n.t("pages.routes_section.heading"))
+ end
+
+ it "contains the text about skipping questions" do
+ expect(page).to have_text("If you need people to skip some questions after this one, edit question routes.")
+ end
+
+ it "contains a link to the question's routes" do
+ expect(page).to have_link("edit question routes", href: question_routes_path)
+ end
+ end
+
+ context "when the question is not a selection question and is the last question in the form" do
+ let(:form) { create :form, pages: [question_page] }
+
+ it "does not render" do
+ expect(page).not_to have_css("h2", text: I18n.t("pages.routes_section.heading"))
+ end
+ end
+ end
+
+ context "when the question has routes" do
+ let(:other_page) { create :page }
+ let(:form) do
+ create(:form, pages: [question_page, other_page]).tap do
+ create :condition, routing_page: question_page, check_page: question_page, answer_value: "Option 1", goto_page: other_page
+ question_page.reload
+ end
+ end
+ let(:draft_question) { build :selection_draft_question, only_one_option: "true" }
+
+ it "contains the routes heading" do
+ expect(page).to have_css("h2", text: I18n.t("pages.routes_section.heading"))
+ end
+
+ it "contains the text saying the question has routes" do
+ expect(page).to have_text("This question has routes: Edit question routes")
+ end
+
+ it "contains a link to the question's routes" do
+ expect(page).to have_link("Edit question routes", href: question_routes_path)
+ end
+
+ context "when the question is the last question in the form" do
+ let(:form) do
+ create(:form, pages: [question_page]).tap do
+ create :condition, routing_page: question_page, check_page: question_page, answer_value: "Option 1", skip_to_end: true
+ question_page.reload
+ end
+ end
+
+ it "contains the text saying the question has routes" do
+ expect(page).to have_text("This question has routes: Edit question routes")
+ end
+ end
+ end
+end
diff --git a/spec/views/pages/edit.html.erb_spec.rb b/spec/views/pages/edit.html.erb_spec.rb
index f3bf777a3..c7b67f665 100644
--- a/spec/views/pages/edit.html.erb_spec.rb
+++ b/spec/views/pages/edit.html.erb_spec.rb
@@ -67,4 +67,16 @@
expect(rendered).not_to have_text(I18n.t("helpers.hint.pages_question_input.is_optional_options.true"))
end
end
+
+ describe "routes section" do
+ let(:form) { create :form, pages: [page, create(:page)] }
+
+ it "contains the routes section" do
+ expect(rendered).to have_css("h2", text: I18n.t("pages.routes_section.heading"))
+ end
+
+ it "contains a link to the question's routes" do
+ expect(rendered).to have_link("edit question routes", href: routes_path(form_id: form.id, anchor: page.page_position_id))
+ end
+ end
end