diff --git a/app/components/cms/curriculum_key_stages_component.rb b/app/components/cms/curriculum_key_stages_component.rb
new file mode 100644
index 0000000000..44e8427108
--- /dev/null
+++ b/app/components/cms/curriculum_key_stages_component.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class Cms::CurriculumKeyStagesComponent < ViewComponent::Base
+ delegate :cms_color_theme_class, to: :helpers
+
+ def initialize(title:, background_color:)
+ @title = title
+ @background_color = background_color
+
+ @key_stages = begin
+ CurriculumClient::Queries::KeyStage.all.key_stages
+ rescue
+ []
+ end
+ end
+
+ def box_classes(key_stage)
+ classes = ["curriculum-card"]
+ classes << if ["1", "2"].include?(key_stage.level)
+ cms_color_theme_class("orange", "left")
+ else
+ cms_color_theme_class("green", "left")
+ end
+ end
+
+ def render?
+ @key_stages.any?
+ end
+end
diff --git a/app/components/cms/curriculum_key_stages_component/curriculum_key_stages_component.html.erb b/app/components/cms/curriculum_key_stages_component/curriculum_key_stages_component.html.erb
new file mode 100644
index 0000000000..9ca9279db8
--- /dev/null
+++ b/app/components/cms/curriculum_key_stages_component/curriculum_key_stages_component.html.erb
@@ -0,0 +1,24 @@
+<%= render GovGridRowComponent.new(background_color: @background_color, additional_classes: "cms-curriculum-key-stages") do |row| %>
+ <%= row.with_column("full") do %>
+
<%= @title %>
+
+ <% @key_stages.each do |key_stage| %>
+
+ <%= content_tag :div, class: box_classes(key_stage) do %>
+
+ <%= link_to key_stage.title, curriculum_key_stage_units_path(key_stage_slug: key_stage.slug), class: 'govuk-link ncce-link' %>
+
+
+ Year <%= key_stage.years %>,
+ Age <%= key_stage.ages %>
+
+
+ Units: <%= key_stage.unit_count %>
+ Lessons: <%= key_stage.lesson_count %>
+
+ <% end %>
+
+ <% end %>
+
+ <% end %>
+<% end %>
diff --git a/app/components/cms/curriculum_key_stages_component/curriculum_key_stages_component.scss b/app/components/cms/curriculum_key_stages_component/curriculum_key_stages_component.scss
new file mode 100644
index 0000000000..7308396317
--- /dev/null
+++ b/app/components/cms/curriculum_key_stages_component/curriculum_key_stages_component.scss
@@ -0,0 +1,57 @@
+.cms-curriculum-key-stages {
+
+ .curriculum-card {
+ background-color: $concrete;
+ border-left-style: solid;
+ border-left-width: 9px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ padding: 20px 10px;
+ position: relative;
+
+ @include govuk-media-query($from: tablet) {
+ margin-bottom: 0;
+ min-height: 5.5rem;
+ }
+
+ @include govuk-media-query($from: desktop) {
+ padding: 20px 10px 20px 25px;
+ min-height: inherit;
+ }
+
+ &__title {
+ font-weight: 500;
+ margin-bottom: 0.5rem;
+ margin-top: 0;
+
+ @include govuk-media-query($from: desktop) {
+ margin-bottom: 1rem;
+ }
+ }
+
+ &__details {
+ display: flex;
+ flex-wrap: wrap;
+ margin-bottom: 0;
+ flex-direction: row;
+
+ @include govuk-media-query($from: tablet) {
+ flex-direction: column;
+ }
+
+ @include govuk-media-query($from: desktop) {
+ flex-direction: row;
+ }
+ }
+
+ &__counts {
+ padding-top: 16px;
+ display: flex;
+ flex-wrap: wrap;
+ margin-bottom: 0;
+ flex-direction: column;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/components/cms/horizontal_link_card_component/horizontal_link_card_component.scss b/app/components/cms/horizontal_link_card_component/horizontal_link_card_component.scss
index 8aed012f6c..b28fb7e38e 100644
--- a/app/components/cms/horizontal_link_card_component/horizontal_link_card_component.scss
+++ b/app/components/cms/horizontal_link_card_component/horizontal_link_card_component.scss
@@ -3,6 +3,13 @@
padding: 20px;
border-left-width: 13px;
+ .ncce-link {
+ color: $hyper-link-blue;
+ &:visited {
+ color: $hyper-link-blue;
+ }
+ }
+
h2 {
@extend .govuk-heading-m;
}
diff --git a/app/services/cms/dynamic_components/blocks/curriculum_key_stages.rb b/app/services/cms/dynamic_components/blocks/curriculum_key_stages.rb
new file mode 100644
index 0000000000..774329c52d
--- /dev/null
+++ b/app/services/cms/dynamic_components/blocks/curriculum_key_stages.rb
@@ -0,0 +1,18 @@
+module Cms
+ module DynamicComponents
+ module Blocks
+ class CurriculumKeyStages
+ attr_accessor :title, :background_color
+
+ def initialize(title:, background_color:)
+ @title = title
+ @background_color = background_color
+ end
+
+ def render
+ Cms::CurriculumKeyStagesComponent.new(title:, background_color:)
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/cms/providers/strapi/factories/blocks_factory.rb b/app/services/cms/providers/strapi/factories/blocks_factory.rb
index ea108d0ba2..44556744a2 100644
--- a/app/services/cms/providers/strapi/factories/blocks_factory.rb
+++ b/app/services/cms/providers/strapi/factories/blocks_factory.rb
@@ -69,6 +69,8 @@ def self.generate_component(component_name, strapi_data)
to_button_block(strapi_data)
when "feedback-banner"
to_feedback_banner(strapi_data)
+ when "curriculum-key-stages"
+ to_curriculum_key_stages(strapi_data)
end
end
@@ -99,6 +101,13 @@ def self.to_text_with_testimonial(strapi_data)
)
end
+ def self.to_curriculum_key_stages(strapi_data)
+ DynamicComponents::Blocks::CurriculumKeyStages.new(
+ title: strapi_data[:title],
+ background_color: extract_color_name(strapi_data, :bkColor)
+ )
+ end
+
def self.to_full_width_image_banner(strapi_data)
DynamicComponents::Blocks::FullWidthImageBanner.new(
background_image: to_image(strapi_data, :backgroundImage, default_size: :original),
diff --git a/app/services/cms/providers/strapi/mocks/dynamic_components/blocks/curriculum_key_stages.rb b/app/services/cms/providers/strapi/mocks/dynamic_components/blocks/curriculum_key_stages.rb
new file mode 100644
index 0000000000..68edc62b07
--- /dev/null
+++ b/app/services/cms/providers/strapi/mocks/dynamic_components/blocks/curriculum_key_stages.rb
@@ -0,0 +1,18 @@
+module Cms
+ module Providers
+ module Strapi
+ module Mocks
+ module DynamicComponents
+ module Blocks
+ class CurriculumKeyStages < StrapiMock
+ strapi_component "blocks.curriculum-key-stages"
+
+ attribute(:title) { Faker::Lorem.sentence }
+ attribute(:bkColor) { nil }
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/cms/providers/strapi/queries/components/blocks/curriculum_key_stages.rb b/app/services/cms/providers/strapi/queries/components/blocks/curriculum_key_stages.rb
new file mode 100644
index 0000000000..6186dbcf17
--- /dev/null
+++ b/app/services/cms/providers/strapi/queries/components/blocks/curriculum_key_stages.rb
@@ -0,0 +1,22 @@
+module Cms
+ module Providers
+ module Strapi
+ module Queries
+ module Components
+ module Blocks
+ class CurriculumKeyStages < BaseComponentQuery
+ def self.name = "ComponentBlocksCurriculumKeyStages"
+
+ def self.base_fields
+ <<~GRAPHQL.freeze
+ cks__title: title
+ bkColor
+ GRAPHQL
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/cms/providers/strapi/queries/dynamic_zone.rb b/app/services/cms/providers/strapi/queries/dynamic_zone.rb
index 95b9c5f423..5938cfa421 100644
--- a/app/services/cms/providers/strapi/queries/dynamic_zone.rb
+++ b/app/services/cms/providers/strapi/queries/dynamic_zone.rb
@@ -7,6 +7,7 @@ class DynamicZone
Components::Blocks::ButtonBlock,
Components::Blocks::CommunityActivityList,
Components::Blocks::CourseCardsSection,
+ Components::Blocks::CurriculumKeyStages,
Components::Blocks::EnrolmentSplitCourseCard,
Components::Blocks::EnrolmentTestimonial,
Components::Blocks::FeedbackBanner,
diff --git a/app/webpacker/stylesheets/components/cms/_shared.scss b/app/webpacker/stylesheets/components/cms/_shared.scss
index 3e9d318553..96d73b6162 100644
--- a/app/webpacker/stylesheets/components/cms/_shared.scss
+++ b/app/webpacker/stylesheets/components/cms/_shared.scss
@@ -12,7 +12,9 @@
"standard": $lime-green,
"i-belong": $orange,
"isaac": $brand-yellow,
- "cqf": $pink
+ "cqf": $pink,
+ "orange": $orange,
+ "green": $lime-green
);
$sides: ("left", "right", "top", "bottom");
diff --git a/previews/components/cms/curriculum_key_stage_component_preview.rb b/previews/components/cms/curriculum_key_stage_component_preview.rb
new file mode 100644
index 0000000000..cc4e3085b7
--- /dev/null
+++ b/previews/components/cms/curriculum_key_stage_component_preview.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class Cms::CurriculumKeyStagesComponentPreview < ViewComponent::Preview
+ def default
+ render(Cms::CurriculumKeyStagesComponent.new(title: "title", bk_color: "bk_color"))
+ end
+end
diff --git a/spec/components/cms/curriculum_key_stage_component_spec.rb b/spec/components/cms/curriculum_key_stage_component_spec.rb
new file mode 100644
index 0000000000..bf9c38207f
--- /dev/null
+++ b/spec/components/cms/curriculum_key_stage_component_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+RSpec.describe Cms::CurriculumKeyStagesComponent, type: :component do
+ let(:key_stages_json_response) { File.new("spec/support/curriculum/responses/key_stages.json").read }
+
+ before do
+ client = CurriculumClient::Connection.connect(ENV.fetch("CURRICULUM_TEST_SCHEMA_PATH"))
+ allow(CurriculumClient::Connection).to receive(:connect).and_return(client)
+ end
+
+ context "when curriculum is enabled" do
+ before do
+ stub_a_valid_request(key_stages_json_response)
+ render_inline(described_class.new(
+ title: "Choose resources by key stage",
+ background_color: nil
+ ))
+ end
+ it "renders the title" do
+ expect(page).to have_css("h2.govuk-heading-m", text: "Choose resources by key stage")
+ end
+ it "renders the key stages" do
+ expect(page).to have_css(".curriculum-card", count: 4)
+ end
+
+ it "sets key_stage 1 and 2 cards to orange" do
+ expect(page).to have_css(".cms-color-theme__border--orange-left", text: "Key Stage 1")
+ expect(page).to have_css(".cms-color-theme__border--orange-left", text: "Key Stage 2")
+ end
+
+ it "sets key_stage 3 and 4 cards to green" do
+ expect(page).to have_css(".cms-color-theme__border--green-left", text: "Key Stage 3")
+ expect(page).to have_css(".cms-color-theme__border--green-left", text: "Key Stage 4")
+ end
+ end
+
+ context "when curriculum returns no keyStages" do
+ before do
+ stub_a_valid_request("{\"data\": { \"keyStages\": [] }}")
+ render_inline(described_class.new(
+ title: "Choose resources by key stage",
+ background_color: nil
+ ))
+ end
+
+ it "does not render the title" do
+ expect(page).not_to have_css("h2.govuk-heading-m", text: "Choose resources by key stage")
+ end
+ end
+
+ context "when curriculum returns an error" do
+ before do
+ stub_an_invalid_request
+ render_inline(described_class.new(
+ title: "Choose resources by key stage",
+ background_color: nil
+ ))
+ end
+
+ it "renders the title" do
+ expect(page).not_to have_css("h2.govuk-heading-m", text: "Choose resources by key stage")
+ end
+ end
+end
diff --git a/spec/services/cms/dynamic_components/blocks/curriculum_key_stages_spec.rb b/spec/services/cms/dynamic_components/blocks/curriculum_key_stages_spec.rb
new file mode 100644
index 0000000000..5e5ea09508
--- /dev/null
+++ b/spec/services/cms/dynamic_components/blocks/curriculum_key_stages_spec.rb
@@ -0,0 +1,18 @@
+require "rails_helper"
+
+RSpec.describe Cms::DynamicComponents::Blocks::CurriculumKeyStages do
+ let(:key_stages_json_response) { File.new("spec/support/curriculum/responses/key_stages.json").read }
+
+ before do
+ client = CurriculumClient::Connection.connect(ENV.fetch("CURRICULUM_TEST_SCHEMA_PATH"))
+ allow(CurriculumClient::Connection).to receive(:connect).and_return(client)
+ stub_a_valid_request(key_stages_json_response)
+ @comp = Cms::Providers::Strapi::Factories::ComponentFactory.process_component(
+ Cms::Mocks::DynamicComponents::Blocks::CurriculumKeyStages.generate_raw_data
+ )
+ end
+
+ it "should render as Cms::CurriculumKeyStagesComponent" do
+ expect(@comp.render).to be_a(Cms::CurriculumKeyStagesComponent)
+ end
+end
diff --git a/spec/services/cms/providers/strapi/queries/components/blocks/curriculum_key_stages_spec.rb b/spec/services/cms/providers/strapi/queries/components/blocks/curriculum_key_stages_spec.rb
new file mode 100644
index 0000000000..9c87442ae1
--- /dev/null
+++ b/spec/services/cms/providers/strapi/queries/components/blocks/curriculum_key_stages_spec.rb
@@ -0,0 +1,9 @@
+require "rails_helper"
+
+RSpec.describe Cms::Providers::Strapi::Queries::Components::Blocks::CurriculumKeyStages do
+ it_should_behave_like "a strapi graphql component",
+ %w[
+ title
+ bkColor
+ ]
+end
diff --git a/spec/support/curriculum/curriculum_stubs.rb b/spec/support/curriculum/curriculum_stubs.rb
index 6b4b1ec51f..1ab54ebffd 100644
--- a/spec/support/curriculum/curriculum_stubs.rb
+++ b/spec/support/curriculum/curriculum_stubs.rb
@@ -19,7 +19,7 @@ def stub_a_valid_schema_request
def stub_an_invalid_request(status = 404)
stub_request(:post, URL)
.to_return(
- {status:, body: response, headers: {}}
+ {status:, body: "{}", headers: {}}
)
end