diff --git a/.nycrc b/.nycrc index 9d1de5c109..2dccfb78f0 100644 --- a/.nycrc +++ b/.nycrc @@ -1,6 +1,6 @@ { "all": true, - "branches": 95, + "branches": 90, "lines": 95, "check-coverage": true, "compact": false, diff --git a/Gemfile b/Gemfile index 267a4af108..2745929e8b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" ruby "~> 3.2.0" -gem "rails", "7.2.1" +gem "rails", "7.2.1.1" gem "addressable" gem "bootsnap", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 6e44a046d8..f48ce5677b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,29 +1,29 @@ GEM remote: https://rubygems.org/ specs: - actioncable (7.2.1) - actionpack (= 7.2.1) - activesupport (= 7.2.1) + actioncable (7.2.1.1) + actionpack (= 7.2.1.1) + activesupport (= 7.2.1.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.2.1) - actionpack (= 7.2.1) - activejob (= 7.2.1) - activerecord (= 7.2.1) - activestorage (= 7.2.1) - activesupport (= 7.2.1) + actionmailbox (7.2.1.1) + actionpack (= 7.2.1.1) + activejob (= 7.2.1.1) + activerecord (= 7.2.1.1) + activestorage (= 7.2.1.1) + activesupport (= 7.2.1.1) mail (>= 2.8.0) - actionmailer (7.2.1) - actionpack (= 7.2.1) - actionview (= 7.2.1) - activejob (= 7.2.1) - activesupport (= 7.2.1) + actionmailer (7.2.1.1) + actionpack (= 7.2.1.1) + actionview (= 7.2.1.1) + activejob (= 7.2.1.1) + activesupport (= 7.2.1.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.2.1) - actionview (= 7.2.1) - activesupport (= 7.2.1) + actionpack (7.2.1.1) + actionview (= 7.2.1.1) + activesupport (= 7.2.1.1) nokogiri (>= 1.8.5) racc rack (>= 2.2.4, < 3.2) @@ -32,35 +32,35 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (7.2.1) - actionpack (= 7.2.1) - activerecord (= 7.2.1) - activestorage (= 7.2.1) - activesupport (= 7.2.1) + actiontext (7.2.1.1) + actionpack (= 7.2.1.1) + activerecord (= 7.2.1.1) + activestorage (= 7.2.1.1) + activesupport (= 7.2.1.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.2.1) - activesupport (= 7.2.1) + actionview (7.2.1.1) + activesupport (= 7.2.1.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.2.1) - activesupport (= 7.2.1) + activejob (7.2.1.1) + activesupport (= 7.2.1.1) globalid (>= 0.3.6) - activemodel (7.2.1) - activesupport (= 7.2.1) - activerecord (7.2.1) - activemodel (= 7.2.1) - activesupport (= 7.2.1) + activemodel (7.2.1.1) + activesupport (= 7.2.1.1) + activerecord (7.2.1.1) + activemodel (= 7.2.1.1) + activesupport (= 7.2.1.1) timeout (>= 0.4.0) - activestorage (7.2.1) - actionpack (= 7.2.1) - activejob (= 7.2.1) - activerecord (= 7.2.1) - activesupport (= 7.2.1) + activestorage (7.2.1.1) + actionpack (= 7.2.1.1) + activejob (= 7.2.1.1) + activerecord (= 7.2.1.1) + activesupport (= 7.2.1.1) marcel (~> 1.0) - activesupport (7.2.1) + activesupport (7.2.1.1) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) @@ -98,6 +98,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) + chartkick (5.1.1) climate_control (1.2.0) coderay (1.1.3) concurrent-ruby (1.3.4) @@ -130,7 +131,7 @@ GEM i18n (>= 1.8.11, < 2) ffi (1.16.3) find_a_port (1.0.1) - gds-api-adapters (96.0.3) + gds-api-adapters (97.0.0) addressable link_header null_logger @@ -160,7 +161,8 @@ GEM govuk_personalisation (1.0.0) plek (>= 1.9.0) rails (>= 6, < 8) - govuk_publishing_components (44.1.0) + govuk_publishing_components (44.4.1) + chartkick govuk_app_config govuk_personalisation (>= 0.7.0) kramdown @@ -231,16 +233,17 @@ GEM marcel (1.0.4) matrix (0.4.2) method_source (1.0.0) - mime-types (3.5.2) + mime-types (3.6.0) + logger mime-types-data (~> 3.2015) - mime-types-data (3.2024.0903) + mime-types-data (3.2024.1001) mini_mime (1.1.5) mini_portile2 (2.8.7) minitest (5.25.1) msgpack (1.7.2) multi_xml (0.7.1) bigdecimal (~> 3.1) - net-imap (0.4.16) + net-imap (0.5.0) date net-protocol net-pop (0.1.2) @@ -505,7 +508,7 @@ GEM puma (6.4.3) nio4r (~> 2.0) racc (1.8.1) - rack (3.1.7) + rack (3.1.8) rack-proxy (0.7.7) rack rack-session (2.0.0) @@ -515,20 +518,20 @@ GEM rackup (2.1.0) rack (>= 3) webrick (~> 1.8) - rails (7.2.1) - actioncable (= 7.2.1) - actionmailbox (= 7.2.1) - actionmailer (= 7.2.1) - actionpack (= 7.2.1) - actiontext (= 7.2.1) - actionview (= 7.2.1) - activejob (= 7.2.1) - activemodel (= 7.2.1) - activerecord (= 7.2.1) - activestorage (= 7.2.1) - activesupport (= 7.2.1) + rails (7.2.1.1) + actioncable (= 7.2.1.1) + actionmailbox (= 7.2.1.1) + actionmailer (= 7.2.1.1) + actionpack (= 7.2.1.1) + actiontext (= 7.2.1.1) + actionview (= 7.2.1.1) + activejob (= 7.2.1.1) + activemodel (= 7.2.1.1) + activerecord (= 7.2.1.1) + activestorage (= 7.2.1.1) + activesupport (= 7.2.1.1) bundler (>= 1.15.0) - railties (= 7.2.1) + railties (= 7.2.1.1) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -548,9 +551,9 @@ GEM csv (~> 3.2) i18n-tasks rails-i18n - railties (7.2.1) - actionpack (= 7.2.1) - activesupport (= 7.2.1) + railties (7.2.1.1) + actionpack (= 7.2.1.1) + activesupport (= 7.2.1.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -696,7 +699,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.18) + zeitwerk (2.7.0) PLATFORMS ruby @@ -726,7 +729,7 @@ DEPENDENCIES pact_broker-client plek pry-byebug - rails (= 7.2.1) + rails (= 7.2.1.1) rails-controller-testing rails-i18n rails_translation_manager diff --git a/app/assets/images/landing_page/placeholder/chart.png b/app/assets/images/landing_page/placeholder/chart.png new file mode 100644 index 0000000000..e476466fb9 Binary files /dev/null and b/app/assets/images/landing_page/placeholder/chart.png differ diff --git a/app/assets/javascripts/modules/app-b-main-navigation.js b/app/assets/javascripts/modules/app-b-main-navigation.js new file mode 100644 index 0000000000..647620d87d --- /dev/null +++ b/app/assets/javascripts/modules/app-b-main-navigation.js @@ -0,0 +1,26 @@ +window.GOVUK = window.GOVUK || {} +window.GOVUK.Modules = window.GOVUK.Modules || {}; + +(function (Modules) { + 'use strict' + + function AppBMainNavigation (module) { + this.module = module + this.module.button = this.module.querySelector('button') + this.module.nav = this.module.querySelector('#app-b-main-nav__nav') + this.module.nav.classList.add('app-b-main-nav__nav--hidden') + this.module.button.classList.remove('js-app-b-main-nav__button') + } + + AppBMainNavigation.prototype.init = function () { + this.module.button.addEventListener('click', this.toggleMenu.bind(this)) + } + + AppBMainNavigation.prototype.toggleMenu = function (e) { + var ariaExpanded = this.module.button.getAttribute('aria-expanded') === 'true' + this.module.nav.classList.toggle('app-b-main-nav__nav--hidden') + this.module.button.setAttribute('aria-expanded', `${!ariaExpanded}`) + } + + Modules.AppBMainNavigation = AppBMainNavigation +})(window.GOVUK.Modules) diff --git a/app/assets/stylesheets/components/_subscribe.scss b/app/assets/stylesheets/components/_subscribe.scss index c5c5ca84bf..480003a75f 100644 --- a/app/assets/stylesheets/components/_subscribe.scss +++ b/app/assets/stylesheets/components/_subscribe.scss @@ -7,12 +7,11 @@ } .app-c-subscribe__link { - @include govuk-font($size: 19, $weight: bold); - display: block; background: url("calendars/icon-calendar.png") no-repeat scroll 0 0; min-height: 2.5em; padding: 0 0 0 3em; + @include govuk-font($size: 19, $weight: bold); @include govuk-device-pixel-ratio { background-image: url("calendars/icon-calendar-2x.png"); diff --git a/app/assets/stylesheets/views/_cookie-settings.scss b/app/assets/stylesheets/views/_cookie-settings.scss index dd8e28eeec..76dc1d600b 100644 --- a/app/assets/stylesheets/views/_cookie-settings.scss +++ b/app/assets/stylesheets/views/_cookie-settings.scss @@ -15,9 +15,9 @@ } .cookie-settings__confirmation { - @include govuk-font(19); display: none; margin-top: govuk-spacing(3); + @include govuk-font(19); } .cookie-settings__gov-services { diff --git a/app/assets/stylesheets/views/_homepage.scss b/app/assets/stylesheets/views/_homepage.scss index a4912a046d..7c2da996a2 100644 --- a/app/assets/stylesheets/views/_homepage.scss +++ b/app/assets/stylesheets/views/_homepage.scss @@ -15,8 +15,8 @@ } .homepage__ready-call-to-action { - @include govuk-font(19, $weight: bold); margin-bottom: 0; + @include govuk-font(19, $weight: bold); } .home-services { @@ -24,29 +24,29 @@ } .home-services__heading { - @include govuk-font(19, $weight: bold); margin: 0 0 govuk-spacing(1); + @include govuk-font(19, $weight: bold); } .home-services__para { - @include govuk-font(16); margin: 0 0 govuk-spacing(3); min-height: 40px; + @include govuk-font(16); } .home-info { - @include govuk-font(24); margin: govuk-spacing(2) 0 govuk-spacing(4); + @include govuk-font(24); } .home-more__title { - @include govuk-font(36, $weight: bold); margin: 0 0 govuk-spacing(4); + @include govuk-font(36, $weight: bold); } .home-more__subtitle { - @include govuk-font(24, $weight: bold); margin: 0 0 govuk-spacing(2); + @include govuk-font(24, $weight: bold); } .home-more__list { @@ -184,6 +184,7 @@ .homepage.global-bar-present .homepage-header { @include govuk-responsive-padding(7, "top"); + @media (min-width: 1281px) { // stylelint-disable-line media-feature-range-notation padding-top: govuk-spacing(8); } diff --git a/app/assets/stylesheets/views/_landing_page.scss b/app/assets/stylesheets/views/_landing_page.scss new file mode 100644 index 0000000000..3da2446f28 --- /dev/null +++ b/app/assets/stylesheets/views/_landing_page.scss @@ -0,0 +1,24 @@ +@import "govuk_publishing_components/individual_component_support"; + +.landing-page-header { + // I've used the hex value for the background colour as it doesn't exist in the colour palette + background-color: #231F20; +} + +.landing-page-header__blue-bar { + background-color: govuk-colour("blue"); + height: govuk-spacing(2); +} + +.landing-page-header__org { + padding-top: govuk-spacing(2); + padding-bottom: govuk-spacing(6); + + // I've added this styling here rather than in the gem because it's application specific + // and it would introduce further work to make this variation work in the gem without + // affecting the other variants. + // TODO add this as a variant in the components gem. + .gem-c-organisation-logo__link:link:not(:hover) { + text-decoration: none; + } +} diff --git a/app/assets/stylesheets/views/_landing_page/card.scss b/app/assets/stylesheets/views/_landing_page/card.scss new file mode 100644 index 0000000000..244e02c52d --- /dev/null +++ b/app/assets/stylesheets/views/_landing_page/card.scss @@ -0,0 +1,41 @@ +@import "govuk_publishing_components/individual_component_support"; + +.app-b-card { + display: flex; + flex-direction: column; + justify-content: space-between; + margin-bottom: govuk-spacing(6); + background-color: govuk-colour("dark-blue"); + color: govuk-colour("white"); +} + +.app-b-card__textbox { + padding: govuk-spacing(6) govuk-spacing(7); + background-color: govuk-colour("dark-blue"); + color: govuk-colour("white"); +} + +.app-b-card__figure { + border-style: solid; + border-width: 0 1px 1px; + border-color: govuk-colour("mid-grey"); + margin: auto 0 0; + background-color: govuk-colour("white"); +} + +.app-b-card__image { + display: block; + width: 100%; + margin: 0; +} + +@include govuk-media-query($media-type: print) { + .app-b-card { + background: none; + padding: 0; + + * { + color: $govuk-print-text-colour !important; // stylelint-disable-line declaration-no-important + } + } +} diff --git a/app/assets/stylesheets/views/_landing_page/grid.scss b/app/assets/stylesheets/views/_landing_page/grid.scss new file mode 100644 index 0000000000..9954c00957 --- /dev/null +++ b/app/assets/stylesheets/views/_landing_page/grid.scss @@ -0,0 +1,9 @@ +@import "govuk_publishing_components/individual_component_support"; + +@include govuk-media-query($from: desktop) { + .grid-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: govuk-spacing(6); + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/views/_landing_page/hero.scss b/app/assets/stylesheets/views/_landing_page/hero.scss index 5c269877fc..a8c613131c 100644 --- a/app/assets/stylesheets/views/_landing_page/hero.scss +++ b/app/assets/stylesheets/views/_landing_page/hero.scss @@ -1,20 +1,26 @@ @import "govuk_publishing_components/individual_component_support"; +$mobile-height: 427px; +$tablet-height: 512px; +$desktop-height: 610px; + .app-b-hero { margin-bottom: govuk-spacing(6); + position: relative; } .app-b-hero__imagewrapper { display: flex; justify-content: center; overflow: hidden; - height: 610px; + min-height: $desktop-height; @include govuk-media-query($until: desktop) { - height: 512px; + min-height: $tablet-height; } + @include govuk-media-query($until: tablet) { - height: 427px; + min-height: $mobile-height; } } @@ -34,3 +40,47 @@ margin-top: -(govuk-spacing(6)); } } + +.app-b-hero--mid-page { + overflow: hidden; + min-height: $desktop-height; + + @include govuk-media-query($until: desktop) { + display: flex; + flex-direction: column-reverse; + min-height: $tablet-height; + } + + @include govuk-media-query($until: tablet) { + min-height: $mobile-height; + } + + .app-b-hero__image { + position: absolute; + left: 50%; + transform: translate(-50%); + } + + .app-b-hero__textbox-wrapper { + @include govuk-media-query($from: desktop) { + box-sizing: border-box; + align-items: center; + display: flex; + min-height: $desktop-height; + margin-top: -$desktop-height; + padding: govuk-spacing(6) 0; + } + } + + .app-b-hero__textbox { + margin-top: 0; + + @include govuk-media-query($until: desktop) { + margin-bottom: -(govuk-spacing(8)); + } + + @include govuk-media-query($until: tablet) { + margin-bottom: -(govuk-spacing(6)); + } + } +} diff --git a/app/assets/stylesheets/views/_landing_page/main-navigation.scss b/app/assets/stylesheets/views/_landing_page/main-navigation.scss new file mode 100644 index 0000000000..82209bf7cf --- /dev/null +++ b/app/assets/stylesheets/views/_landing_page/main-navigation.scss @@ -0,0 +1,162 @@ +@import "govuk_publishing_components/individual_component_support"; + +.app-b-main-nav { + padding-bottom: govuk-spacing(1); + + @include govuk-media-query($from: "desktop") { + display: flex; + flex-wrap: wrap; + align-items: center; + } +} + +.app-b-main-nav__nav--hidden { + @include govuk-media-query($until: "desktop") { + display: none; + } +} + +.app-b-main-nav__ul { + padding-left: 0; + padding-right: 0; + margin: 0; + + .app-b-main-nav__listitem:last-of-type { + margin-right: 0; + } + + @include govuk-media-query($until: "desktop") { + padding-top: 0; + } +} + +.app-b-main-nav__button { + display: none; + background: none; + border: none; + padding: 0; + position: relative; + margin-top: govuk-spacing(3); + cursor: pointer; + color: govuk-colour("blue"); + @include govuk-font(19, $weight: bold); + + @include govuk-media-query($until: "desktop") { + display: block; + + &.js-app-b-main-nav__button { + display: none; + } + } +} + +.app-b-main-nav__icon::after { + position: absolute; + font-size: 15px; + top: 4px; + width: 20px; +} + +.app-b-main-nav__button[aria-expanded="true"] .app-b-main-nav__icon::after { + content: "▲" +} + +.app-b-main-nav__button[aria-expanded="false"] .app-b-main-nav__icon::after { + content: "▼" +} + +.app-b-main-nav__heading-p { + display: inline-block; + margin-bottom: 0; + margin-right: govuk-spacing(9); +} + +.app-b-main-nav__heading-link { + &:link, + &:visited { + color: govuk-colour("black"); + } + @include govuk-media-query($until: "desktop") { + margin-bottom: 0; + } +} + +.app-b-main-nav__childlist { + display: none; + @include govuk-media-query($until: "desktop") { + display: block; + } +} + +.app-b-main-nav__listitem { + position: relative; + list-style: none; + display: inline-block; + margin-right: govuk-spacing(7); + margin-top: govuk-spacing(3); + margin-bottom: govuk-spacing(3); + @include govuk-font(19, $weight: normal); + + @include govuk-media-query($until: "desktop") { + display: block; + margin-top: govuk-spacing(3); + } +} + +.app-b-main-nav__link { + @include govuk-media-query($from: "desktop") { + padding-top: govuk-spacing(3); + padding-bottom: govuk-spacing(3); + } +} + +.app-b-main-nav__link:hover { + text-decoration: none; +} + +.app-b-main-nav__link--active, +.app-b-main-nav__link:hover, +.app-b-main-nav__link:focus { + .app-b-main-nav__mobile-border { + position: absolute; + height: 100%; + width: 15px; + + @include govuk-media-query($until: "desktop") { + border-left: 6px solid govuk-colour("blue"); + left: -30px; + } + + @include govuk-media-query($until: "tablet") { + left: -15px; + } + } +} + +.app-b-main-nav__childlist .app-b-main-nav__link--active, +.app-b-main-nav__childlist .app-b-main-nav__link:hover, +.app-b-main-nav__childlist .app-b-main-nav__link:focus { + .app-b-main-nav__mobile-border { + @include govuk-media-query($until: "desktop") { + left: -70px; + } + @include govuk-media-query($until: "tablet") { + left: -55px; + } + } +} + + +.app-b-main-nav__link--active, +.app-b-main-nav__link:hover { + @include govuk-media-query($from: "desktop") { + border-bottom: 6px solid govuk-colour("blue"); + } +} + +.app-b-main-nav__link--active:hover, +.app-b-main-nav__link:hover { + @include govuk-media-query($from: "desktop") { + border-color: govuk-colour("dark-blue"); + } +} diff --git a/app/assets/stylesheets/views/_landing_page/quote.scss b/app/assets/stylesheets/views/_landing_page/quote.scss new file mode 100644 index 0000000000..887be9e8c5 --- /dev/null +++ b/app/assets/stylesheets/views/_landing_page/quote.scss @@ -0,0 +1,27 @@ +@import "govuk_publishing_components/individual_component_support"; + +.app-b-quote { + color: govuk-colour("white"); +} + +.app-b-quote__svg { + margin-bottom: govuk-spacing(4); +} + +.app-b-quote__blockquote { + margin: 0; +} + +.app-b-quote__text { + margin: 0 0 govuk-spacing(8); + @include govuk-font(19, $weight: "regular", $tabular: false, $line-height: false); + + @include govuk-media-query($from: tablet) { + margin-bottom: 127px; + } +} + +.app-b-quote__cite { + font-style: normal; + @include govuk-font(19, $weight: "regular", $tabular: false, $line-height: false); +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 028003b108..822a0f36c2 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -28,4 +28,14 @@ def wrapper_class(publication = nil) def current_path_without_query_string request.original_fullpath.split("?", 2).first end + + def remove_breadcrumbs(content_item) + remove_breadcrumbs = false + + if content_item.respond_to?(:is_a_landing_page?) && content_item.is_a_landing_page? + remove_breadcrumbs = true + end + + remove_breadcrumbs + end end diff --git a/app/helpers/block_helper.rb b/app/helpers/block_helper.rb index 766a2786fb..7890debc6e 100644 --- a/app/helpers/block_helper.rb +++ b/app/helpers/block_helper.rb @@ -1,4 +1,11 @@ module BlockHelper + def render_block(block) + render("landing_page/blocks/#{block.type}", block:) + rescue ActionView::MissingTemplate + Rails.logger.warn("Missing template for block #{block.type}") + "" + end + def tab_items_to_component_format(tab_items) tab_items.map do |ti| { diff --git a/app/helpers/contents_list_helper.rb b/app/helpers/contents_list_helper.rb new file mode 100644 index 0000000000..06162f5e6b --- /dev/null +++ b/app/helpers/contents_list_helper.rb @@ -0,0 +1,15 @@ +module ContentsListHelper + def contents_list(current_path, links) + links.map do |link| + content = { + href: link["href"], + text: link["text"], + } + + content[:active] = true if current_path == link["href"] + content[:items] = contents_list(current_path, link["items"]) if link["items"].present? + + content + end + end +end diff --git a/app/helpers/location_form_helper.rb b/app/helpers/location_form_helper.rb index 2ff13776c8..ee8cef3304 100644 --- a/app/helpers/location_form_helper.rb +++ b/app/helpers/location_form_helper.rb @@ -1,7 +1,7 @@ module LocationFormHelper def button_text(publication_format = nil) case publication_format - when "local_transaction" + when "local_transaction", "licence" I18n.t("formats.local_transaction.find_council") else I18n.t("find") diff --git a/app/models/block/blocks_container.rb b/app/models/block/blocks_container.rb new file mode 100644 index 0000000000..0e17ca86c3 --- /dev/null +++ b/app/models/block/blocks_container.rb @@ -0,0 +1,5 @@ +module Block + class BlocksContainer < Block::LayoutBase + alias_method :children, :blocks + end +end diff --git a/app/models/block/card.rb b/app/models/block/card.rb new file mode 100644 index 0000000000..820a753ec3 --- /dev/null +++ b/app/models/block/card.rb @@ -0,0 +1,15 @@ +module Block + CardImage = Data.define(:alt, :source) + + class Card < Block::Base + attr_reader :image, :card_content + + def initialize(block_hash) + super(block_hash) + + alt, source = data.fetch("image").values_at("alt", "source") + @image = CardImage.new(alt:, source:) + @card_content = BlockFactory.build_all(data.dig("card_content", "blocks")) + end + end +end diff --git a/app/models/block/grid_container.rb b/app/models/block/grid_container.rb new file mode 100644 index 0000000000..043cb4ba9b --- /dev/null +++ b/app/models/block/grid_container.rb @@ -0,0 +1,5 @@ +module Block + class GridContainer < Block::LayoutBase + alias_method :children, :blocks + end +end diff --git a/app/models/block/share_links.rb b/app/models/block/share_links.rb new file mode 100644 index 0000000000..082babea8a --- /dev/null +++ b/app/models/block/share_links.rb @@ -0,0 +1,11 @@ +module Block + class ShareLinks < Block::Base + attr_reader :links + + def initialize(block_hash) + super(block_hash) + + @links = data.fetch("links").map { |l| { href: l["href"], text: l["text"], icon: l["icon"] } } + end + end +end diff --git a/app/models/block/side_navigation.rb b/app/models/block/side_navigation.rb new file mode 100644 index 0000000000..ba510c9e4f --- /dev/null +++ b/app/models/block/side_navigation.rb @@ -0,0 +1,10 @@ +module Block + class SideNavigation < Block::Base + LINKS_FILE_PATH = "lib/data/landing_page_content_items/links/side_navigation.yaml".freeze + + def links + file_path = Rails.root.join(LINKS_FILE_PATH) + YAML.load(File.read(file_path)) + end + end +end diff --git a/app/models/content_item.rb b/app/models/content_item.rb index e510e4fff6..aa0fd9aaec 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -1,5 +1,6 @@ class ContentItem - attr_reader :content_store_response, :content_store_hash, :body, :image, :description, :document_type, :title, :base_path, :locale + attr_reader :content_store_response, :content_store_hash, :body, :image, :description, + :document_type, :schema, :title, :base_path, :locale # SCAFFOLDING: remove the override_content_store_hash parameter when full landing page # content items including block details are available from content-store @@ -11,6 +12,7 @@ def initialize(content_store_response, override_content_store_hash: nil) @image = content_store_hash.dig("details", "image") @description = content_store_hash["description"] @document_type = content_store_hash["document_type"] + @schema = content_store_hash["schema"] @title = content_store_hash["title"] @base_path = content_store_hash["base_path"] @locale = content_store_hash["locale"] @@ -18,4 +20,18 @@ def initialize(content_store_response, override_content_store_hash: nil) alias_method :to_h, :content_store_hash delegate :cache_control, to: :content_store_response + + REGEX_IS_A = /is_an?_(.*)\?/ + + def respond_to_missing?(method_name, _include_private = false) + method_name.to_s =~ REGEX_IS_A ? true : super + end + + def method_missing(method_name, *_args, &_block) + if method_name.to_s =~ REGEX_IS_A + schema == ::Regexp.last_match(1) + else + super + end + end end diff --git a/app/views/landing_page/blocks/_action_link.html.erb b/app/views/landing_page/blocks/_action_link.html.erb index 9722728eef..7d0fec7aae 100644 --- a/app/views/landing_page/blocks/_action_link.html.erb +++ b/app/views/landing_page/blocks/_action_link.html.erb @@ -1,11 +1,5 @@ -<% - # Note: using inverse rather than light_text to be consistent - # with other components such as govspeak - light_text = inverse || false -%> - <%= render "govuk_publishing_components/components/action_link", { - light_text:, + inverse: block.data["inverse"], text: block.data["text"], href: block.data["href"] } %> diff --git a/app/views/landing_page/blocks/_blocks_container.html.erb b/app/views/landing_page/blocks/_blocks_container.html.erb new file mode 100644 index 0000000000..3c5ea65df3 --- /dev/null +++ b/app/views/landing_page/blocks/_blocks_container.html.erb @@ -0,0 +1,5 @@ +
+ <% block.children.each do |child| %> + <%= render_block(child) %> + <% end %> +
diff --git a/app/views/landing_page/blocks/_card.html.erb b/app/views/landing_page/blocks/_card.html.erb new file mode 100644 index 0000000000..c6a3a9ede1 --- /dev/null +++ b/app/views/landing_page/blocks/_card.html.erb @@ -0,0 +1,16 @@ +<% + add_view_stylesheet("landing_page/card") + + link_classes = %w(app-b-card__link govuk-link gem-print-link) +%> + +
+
+ <% block.card_content.each do |subblock| %> + <%= render_block(subblock) %> + <% end %> +
+
+ <%= image_tag(block.image.source, alt: block.image.alt, class: "app-b-card__image") %> +
+
diff --git a/app/views/landing_page/blocks/_featured.html.erb b/app/views/landing_page/blocks/_featured.html.erb index 0c134dcce8..2226e31c0d 100644 --- a/app/views/landing_page/blocks/_featured.html.erb +++ b/app/views/landing_page/blocks/_featured.html.erb @@ -4,7 +4,7 @@