From 5db78ac61832984784846b0aaacf0f97ee3c84ef Mon Sep 17 00:00:00 2001 From: Chris Zetter <253059100+zetter-rpf@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:10:04 +0100 Subject: [PATCH 01/18] Serve Code Editor pages from editor-api on the editor host The Code Editor web app currently lives in the editor-standalone repo, where it shares a React codebase with Code Classroom and cannot be changed independently of it. Moving it here lets the editor evolve on its own, and lets its pages be rendered on the server rather than in the browser. This change adds an EditorApp Rails engine and mounts it at the root of any host listed in EDITOR_APP_HOSTS, so editor.raspberrypi.org can serve the editor while editor-api.raspberrypi.org carries on serving the API and admin. Existing routes are declared before the mount so they keep working on both hosts, and the bare root is restricted to non-editor hosts so that "/" reaches the engine and redirects to a locale-prefixed path. Locale resolution follows what the React app did: the path segment first, then the i18next cookie, then Accept-Language, then English. The engine declares the locales it supports rather than inferring them from whichever translation files happen to be present. OriginParser gains a .parse that takes a value directly, so the engine can reuse its literal-or-regex host parsing without duplicating it. Co-Authored-By: Claude Opus 5 (1M context) --- .env.example | 4 ++ Gemfile | 6 +++ Gemfile.lock | 43 +++++++++++++++++++ config/environments/production.rb | 3 +- config/routes.rb | 10 ++++- .../editor_app/application_controller.rb | 29 +++++++++++++ .../editor_app/locales_controller.rb | 11 +++++ editor_app/app/models/editor_app/locale.rb | 29 +++++++++++++ editor_app/config/importmap.rb | 5 +++ editor_app/config/routes.rb | 12 ++++++ editor_app/editor_app.gemspec | 23 ++++++++++ editor_app/lib/editor_app.rb | 16 +++++++ editor_app/lib/editor_app/engine.rb | 28 ++++++++++++ editor_app/lib/editor_app/version.rb | 5 +++ lib/origin_parser.rb | 6 ++- spec/lib/editor_app_spec.rb | 27 ++++++++++++ spec/lib/origin_parser_spec.rb | 8 ++++ spec/models/editor_app/locale_spec.rb | 23 ++++++++++ spec/requests/editor_app/mounting_spec.rb | 29 +++++++++++++ 19 files changed, 313 insertions(+), 4 deletions(-) create mode 100644 editor_app/app/controllers/editor_app/application_controller.rb create mode 100644 editor_app/app/controllers/editor_app/locales_controller.rb create mode 100644 editor_app/app/models/editor_app/locale.rb create mode 100644 editor_app/config/importmap.rb create mode 100644 editor_app/config/routes.rb create mode 100644 editor_app/editor_app.gemspec create mode 100644 editor_app/lib/editor_app.rb create mode 100644 editor_app/lib/editor_app/engine.rb create mode 100644 editor_app/lib/editor_app/version.rb create mode 100644 spec/lib/editor_app_spec.rb create mode 100644 spec/models/editor_app/locale_spec.rb create mode 100644 spec/requests/editor_app/mounting_spec.rb diff --git a/.env.example b/.env.example index a079cf34d..67ffb4778 100644 --- a/.env.example +++ b/.env.example @@ -36,6 +36,10 @@ SMEE_TUNNEL=https://smee.io/MLq0n9kvAes2vydX HOST_URL=http://localhost:3009 EDITOR_PUBLIC_URL=http://classroom.localhost:3013 +# Hosts served by the EditorApp engine. Comma separated, literal strings or +# regexes wrapped in forward slashes (see lib/origin_parser.rb). +EDITOR_APP_HOSTS=editor.localhost + PROFILE_API_KEY=test # This has to match the value set in Profile (https://github.com/RaspberryPiFoundation/profile/blob/ca10a4f360b6fe2b04be76264e03283054126b0f/.env.example#L45). # The application is configured to log sent emails in development. If diff --git a/Gemfile b/Gemfile index 68fd5d6d0..a67ad4175 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,10 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby file: '.tool-versions' +source 'https://rubygems.pkg.github.com/raspberrypifoundation' do + gem 'design_system_rails', '~> 0.19' +end + gem 'administrate', '~> 1.0.0' gem 'administrate-field-active_storage' gem 'aws-sdk-s3', require: false @@ -13,6 +17,7 @@ gem 'bootsnap', require: false gem 'cancancan', '~> 3.3' gem 'countries' gem 'csv', '~> 3.3' +gem 'editor_app', path: 'editor_app' gem 'email_validator' gem 'faker' gem 'faraday' @@ -50,6 +55,7 @@ gem 'ruby-vips' gem 'rubyzip' gem 'sentry-rails' gem 'statesman' +gem 'view_component' group :development, :test do gem 'awesome_print' diff --git a/Gemfile.lock b/Gemfile.lock index ec6a75fc8..e00752c38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,13 @@ GIT omniauth (~> 2.0) omniauth-oauth2 (~> 1.4) +PATH + remote: editor_app + specs: + editor_app (0.1.0) + rails (>= 8.1) + view_component + GEM remote: https://rubygems.org/ specs: @@ -150,6 +157,8 @@ GEM bigdecimal rexml crass (1.0.7) + cssbundling-rails (1.4.3) + railties (>= 6.0.0) csv (3.3.6) database_cleaner-active_record (2.2.2) activerecord (>= 5.a) @@ -525,7 +534,17 @@ GEM snaky_hash (2.0.7) hashie (>= 0.1.0, < 6) version_gem (~> 1.1, >= 1.1.14) + sprockets (4.4.1) + concurrent-ruby (~> 1.1) + logger + rack (>= 2.2.4, < 4) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + sprockets (>= 3.0.0) statesman (13.3.0) + stimulus-rails (1.3.4) + railties (>= 6.0.0) stringio (3.2.0) thor (1.5.0) time (0.4.1) @@ -542,6 +561,15 @@ GEM uri (1.1.1) useragent (0.16.11) version_gem (1.1.14) + view_component (4.15.0) + actionview (>= 7.1.0) + activesupport (>= 7.1.0) + concurrent-ruby (~> 1) + view_component-form (0.3.1) + actionview (>= 7.2.0) + activesupport (>= 7.2.0) + view_component (>= 2.34.0, < 5.0) + zeitwerk (~> 2.5) webdrivers (5.3.1) nokogiri (~> 1.6) rubyzip (>= 1.3.0) @@ -558,6 +586,18 @@ GEM nokogiri (~> 1.8) zeitwerk (2.8.3) +GEM + remote: https://rubygems.pkg.github.com/raspberrypifoundation/ + specs: + design_system_rails (0.19.0) + cssbundling-rails (~> 1.2) + importmap-rails + rails (>= 7.0, < 9.0) + sprockets-rails (~> 3.4) + stimulus-rails (~> 1.2) + view_component (>= 2.0, < 5.0) + view_component-form (>= 0.2.5, < 1.0) + PLATFORMS aarch64-linux arm64-darwin-24 @@ -579,7 +619,9 @@ DEPENDENCIES csv (~> 3.3) database_cleaner-active_record debug + design_system_rails (~> 0.19)! dotenv-rails + editor_app! email_validator factory_bot_rails faker @@ -634,6 +676,7 @@ DEPENDENCIES shoulda-matchers (~> 8.0) simplecov statesman + view_component webdrivers webmock diff --git a/config/environments/production.rb b/config/environments/production.rb index 4f668a926..f43a512b9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -82,7 +82,8 @@ # Enable DNS rebinding protection and other `Host` header attacks. config.hosts = [ - URI.parse(ENV.fetch('HOST_URL')).host + URI.parse(ENV.fetch('HOST_URL')).host, + *EditorApp.hosts ] # Skip DNS rebinding protection for the default health check endpoint. diff --git a/config/routes.rb b/config/routes.rb index 4da976888..9cd6097bd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -126,9 +126,15 @@ resource :github_webhooks, only: :create, defaults: { formats: :json } - root to: 'auth#index' - post '/auth/rpi', as: 'login' get '/auth/callback', to: 'auth#callback', as: 'callback' get '/logout', to: 'auth#destroy', as: 'logout' + + constraints(->(request) { !EditorApp.serves_host?(request.host) }) do + root to: 'auth#index' + end + + constraints(->(request) { EditorApp.serves_host?(request.host) }) do + mount EditorApp::Engine => '/' + end end diff --git a/editor_app/app/controllers/editor_app/application_controller.rb b/editor_app/app/controllers/editor_app/application_controller.rb new file mode 100644 index 000000000..805313faf --- /dev/null +++ b/editor_app/app/controllers/editor_app/application_controller.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module EditorApp + class ApplicationController < ::ApplicationController + layout 'editor_app/application' + + check_authorization + + around_action :switch_locale + + private + + def switch_locale(&) + I18n.with_locale(requested_locale, &) + end + + def requested_locale + Locale.resolve( + path: params[:locale], + cookie: cookies[:i18next], + accept_language: request.headers['Accept-Language'] + ) + end + + def default_url_options + { locale: I18n.locale } + end + end +end diff --git a/editor_app/app/controllers/editor_app/locales_controller.rb b/editor_app/app/controllers/editor_app/locales_controller.rb new file mode 100644 index 000000000..e496885bd --- /dev/null +++ b/editor_app/app/controllers/editor_app/locales_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module EditorApp + class LocalesController < ApplicationController + skip_authorization_check + + def show + redirect_to home_path + end + end +end diff --git a/editor_app/app/models/editor_app/locale.rb b/editor_app/app/models/editor_app/locale.rb new file mode 100644 index 000000000..48e1543e4 --- /dev/null +++ b/editor_app/app/models/editor_app/locale.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module EditorApp + module Locale + DEFAULT = 'en' + SUPPORTED = %w[en en-US es-LA fr-FR ga-IE].freeze + SELECTABLE = { + 'en' => 'English (Global)', + 'en-US' => 'English (US)', + 'es-LA' => 'Español (Latinoamericano)', + 'fr-FR' => 'Français' + }.freeze + + def self.resolve(path: nil, cookie: nil, accept_language: nil) + supported(path) || supported(cookie) || from_accept_language(accept_language) || DEFAULT + end + + def self.supported(locale) + locale if SUPPORTED.include?(locale) + end + + def self.from_accept_language(header) + return if header.blank? + + preferences = header.split(',').map { |entry| entry.split(';').first.to_s.strip } + preferences.find { |preference| SUPPORTED.include?(preference) } + end + end +end diff --git a/editor_app/config/importmap.rb b/editor_app/config/importmap.rb new file mode 100644 index 000000000..1c3af19c7 --- /dev/null +++ b/editor_app/config/importmap.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +pin_all_from EditorApp::Engine.root.join('app/javascript/editor_app/controllers'), + under: 'editor_app/controllers', + to: 'editor_app/controllers' diff --git a/editor_app/config/routes.rb b/editor_app/config/routes.rb new file mode 100644 index 000000000..0bd1654ea --- /dev/null +++ b/editor_app/config/routes.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +EditorApp::Engine.routes.draw do + get '/session/token', to: 'session_tokens#show' + + scope '/:locale', locale: /[a-z]{2}(-[A-Z]{2})?/ do + root to: 'home#show', as: :home + resources :projects, only: %i[index show new create edit update destroy], param: :identifier + end + + root to: 'locales#show' +end diff --git a/editor_app/editor_app.gemspec b/editor_app/editor_app.gemspec new file mode 100644 index 000000000..43e4a00f0 --- /dev/null +++ b/editor_app/editor_app.gemspec @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative 'lib/editor_app/version' + +Gem::Specification.new do |spec| + spec.name = 'editor_app' + spec.version = EditorApp::VERSION + spec.authors = ['Raspberry Pi Foundation'] + spec.summary = 'Code Editor web app' + spec.description = 'Server-rendered pages for the Raspberry Pi Code Editor' + spec.homepage = 'https://github.com/RaspberryPiFoundation/editor-api' + spec.license = 'MIT' + spec.required_ruby_version = '>= 4.0' + + spec.metadata['allowed_push_host'] = 'https://rubygems.pkg.github.com/raspberrypifoundation' + spec.metadata['homepage_uri'] = spec.homepage + spec.metadata['rubygems_mfa_required'] = 'true' + + spec.files = Dir['{app,config,lib}/**/*', 'README.md'] + + spec.add_dependency 'rails', '>= 8.1' + spec.add_dependency 'view_component' +end diff --git a/editor_app/lib/editor_app.rb b/editor_app/lib/editor_app.rb new file mode 100644 index 000000000..c9fc0b2ec --- /dev/null +++ b/editor_app/lib/editor_app.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'editor_app/version' +require 'editor_app/engine' + +module EditorApp + def self.hosts + OriginParser.parse(ENV.fetch('EDITOR_APP_HOSTS', nil)) + end + + def self.serves_host?(host) + hosts.any? do |pattern| + pattern.is_a?(Regexp) ? pattern.match?(host) : pattern == host + end + end +end diff --git a/editor_app/lib/editor_app/engine.rb b/editor_app/lib/editor_app/engine.rb new file mode 100644 index 000000000..382528605 --- /dev/null +++ b/editor_app/lib/editor_app/engine.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'view_component' + +module EditorApp + class Engine < ::Rails::Engine + isolate_namespace EditorApp + + config.autoload_paths << root.join('app/components').to_s + + initializer 'editor_app.assets' do |app| + app.config.assets.paths << root.join('app/javascript') + end + + initializer 'editor_app.importmap', before: 'importmap' do |app| + app.config.importmap.paths << root.join('config/importmap.rb') + app.config.importmap.cache_sweepers << root.join('app/javascript') + end + + config.after_initialize do + I18n.available_locales |= EditorApp::Locale::SUPPORTED.map(&:to_sym) + end + + config.generators do |g| + g.test_framework :rspec + end + end +end diff --git a/editor_app/lib/editor_app/version.rb b/editor_app/lib/editor_app/version.rb new file mode 100644 index 000000000..b6287cfec --- /dev/null +++ b/editor_app/lib/editor_app/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module EditorApp + VERSION = '0.1.0' +end diff --git a/lib/origin_parser.rb b/lib/origin_parser.rb index 1e6472643..c1cabc956 100644 --- a/lib/origin_parser.rb +++ b/lib/origin_parser.rb @@ -5,7 +5,11 @@ # regexes must be wrapped in forward slashes eg. /https?:\/\/localhost(:[0-9]*)?$/ module OriginParser def self.parse_origins - ENV['ALLOWED_ORIGINS']&.split(',')&.map do |origin| + parse(ENV.fetch('ALLOWED_ORIGINS', nil)) + end + + def self.parse(value) + value&.split(',')&.map do |origin| stripped_origin = origin.strip if stripped_origin.start_with?('/') && stripped_origin.end_with?('/') Regexp.new(stripped_origin[1..-2]) diff --git a/spec/lib/editor_app_spec.rb b/spec/lib/editor_app_spec.rb new file mode 100644 index 000000000..615ecf906 --- /dev/null +++ b/spec/lib/editor_app_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe EditorApp do + describe '.serves_host?' do + it 'matches a literal host' do + ClimateControl.modify(EDITOR_APP_HOSTS: 'editor.localhost') do + expect(described_class.serves_host?('editor.localhost')).to be(true) + expect(described_class.serves_host?('editor-api.localhost')).to be(false) + end + end + + it 'matches a host given as a regex' do + ClimateControl.modify(EDITOR_APP_HOSTS: '/^editor(-staging)?\.example\.com$/') do + expect(described_class.serves_host?('editor-staging.example.com')).to be(true) + expect(described_class.serves_host?('other.example.com')).to be(false) + end + end + + it 'serves no hosts when unconfigured' do + ClimateControl.modify(EDITOR_APP_HOSTS: nil) do + expect(described_class.serves_host?('editor.localhost')).to be(false) + end + end + end +end diff --git a/spec/lib/origin_parser_spec.rb b/spec/lib/origin_parser_spec.rb index 7c76563a7..44697a2a2 100644 --- a/spec/lib/origin_parser_spec.rb +++ b/spec/lib/origin_parser_spec.rb @@ -36,4 +36,12 @@ expect(described_class.parse_origins).to eq([]) end end + + describe '.parse' do + it 'parses a value given directly rather than from the environment' do + expect(described_class.parse('editor.localhost, /^editor\\.example\\.com$/')).to eq( + ['editor.localhost', Regexp.new('^editor\\.example\\.com$')] + ) + end + end end diff --git a/spec/models/editor_app/locale_spec.rb b/spec/models/editor_app/locale_spec.rb new file mode 100644 index 000000000..2f24c572d --- /dev/null +++ b/spec/models/editor_app/locale_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe EditorApp::Locale do + describe '.resolve' do + it 'prefers a supported locale from the path' do + expect(described_class.resolve(path: 'fr-FR', cookie: 'es-LA')).to eq('fr-FR') + end + + it 'falls back to the cookie when the path has no locale' do + expect(described_class.resolve(path: nil, cookie: 'es-LA')).to eq('es-LA') + end + + it 'falls back to the Accept-Language header when there is no path or cookie' do + expect(described_class.resolve(accept_language: 'de-DE,fr-FR;q=0.9')).to eq('fr-FR') + end + + it 'defaults to English when nothing is supported' do + expect(described_class.resolve(path: 'de-DE', cookie: 'zz', accept_language: 'de-DE')).to eq('en') + end + end +end diff --git a/spec/requests/editor_app/mounting_spec.rb b/spec/requests/editor_app/mounting_spec.rb new file mode 100644 index 000000000..3e9e53da0 --- /dev/null +++ b/spec/requests/editor_app/mounting_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'EditorApp engine mounting' do + around do |example| + ClimateControl.modify(EDITOR_APP_HOSTS: 'editor.example.com') { example.run } + end + + it 'redirects the root of an editor host to the default locale' do + get 'http://editor.example.com/' + expect(response).to redirect_to('http://editor.example.com/en') + end + + it 'honours the i18next cookie when choosing the locale to redirect to' do + get 'http://editor.example.com/', headers: { 'HTTP_COOKIE' => 'i18next=fr-FR' } + expect(response).to redirect_to('http://editor.example.com/fr-FR') + end + + it 'leaves the root of a non-editor host to the host application' do + get 'http://editor-api.example.com/' + expect(response.body).to include('Log in') + end + + it 'keeps serving the API on an editor host' do + get 'http://editor.example.com/info/release' + expect(response).to have_http_status(:ok) + end +end From e8dd58046f33a912ae9dc2027c0d990d132a789b Mon Sep 17 00:00:00 2001 From: Chris Zetter <253059100+zetter-rpf@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:19:34 +0100 Subject: [PATCH 02/18] Stop CORP header depending on how origins are read from ENV The previous commit made OriginParser.parse_origins read ALLOWED_ORIGINS with ENV.fetch. CorpMiddleware specs stubbed ENV#[] instead, so they silently saw no allowed origins and the Cross-Origin-Resource-Policy header stopped being asserted. This change sets the variable with ClimateControl, as the school and school class specs already do, so the specs exercise the middleware through the environment rather than through a stub of the exact reader the implementation happens to call. Co-Authored-By: Claude Opus 5 (1M context) --- spec/lib/corp_middleware_spec.rb | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/spec/lib/corp_middleware_spec.rb b/spec/lib/corp_middleware_spec.rb index aa94a2512..a182615bd 100644 --- a/spec/lib/corp_middleware_spec.rb +++ b/spec/lib/corp_middleware_spec.rb @@ -3,14 +3,16 @@ require 'rails_helper' describe CorpMiddleware do + around do |example| + ClimateControl.modify(ALLOWED_ORIGINS: allowed_origins) { example.run } + end + + before { allow(app).to receive(:call).and_return([200, {}, ['OK']]) } + let(:app) { instance_double(App::Application) } let(:middleware) { described_class.new(app) } let(:env) { { 'HTTP_HOST' => 'test.com', 'PATH_INFO' => '/rails/active_storage' } } - - before do - allow(app).to receive(:call).and_return([200, {}, ['OK']]) - allow(ENV).to receive(:[]).with('ALLOWED_ORIGINS').and_return('test.com') - end + let(:allowed_origins) { 'test.com' } it 'sets the Cross-Origin-Resource-Policy header for a literal origin' do _status, headers, _response = middleware.call(env) @@ -24,19 +26,23 @@ expect(headers['Cross-Origin-Resource-Policy']).to eq('cross-origin') end - it 'sets the Cross-Origin-Resource-Policy header for regex origin' do - allow(ENV).to receive(:[]).with('ALLOWED_ORIGINS').and_return('/test\.com/') + context 'when the origin is allowed by a regex' do + let(:allowed_origins) { '/test\.com/' } - _status, headers, _response = middleware.call(env) + it 'sets the Cross-Origin-Resource-Policy header' do + _status, headers, _response = middleware.call(env) - expect(headers['Cross-Origin-Resource-Policy']).to eq('cross-origin') + expect(headers['Cross-Origin-Resource-Policy']).to eq('cross-origin') + end end - it 'does not set the Cross-Origin-Resource-Policy header for disallowed origins' do - allow(ENV).to receive(:[]).with('ALLOWED_ORIGINS').and_return('other.com') + context 'when the origin is not allowed' do + let(:allowed_origins) { 'other.com' } - _status, headers, _response = middleware.call(env) + it 'does not set the Cross-Origin-Resource-Policy header' do + _status, headers, _response = middleware.call(env) - expect(headers).not_to have_key('Cross-Origin-Resource-Policy') + expect(headers).not_to have_key('Cross-Origin-Resource-Policy') + end end end From 0327b477a5151bbacd433ffcefe70dffb230d16c Mon Sep 17 00:00:00 2001 From: Chris Zetter <253059100+zetter-rpf@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:19:47 +0100 Subject: [PATCH 03/18] Render the Code Editor home page on the server The Code Editor landing page was a React component that needed the whole SPA, its Redux store and a round trip to the school API before it could show a heading and two "start coding" buttons. Rendering it on the server means the page is useful in its first response. This change ports the landing page to an ERB template in the EditorApp engine, using the design system Button component and the light theme tokens the React app applied. Whether a visitor sees the login options or the school student view is now decided from the session rather than from client-side state. Translations are ported from editor-standalone into the engine, keyed for Rails lazy lookup. The React student view referenced two keys that are absent from every translation file and so rendered raw key names; it now uses the existing translated "Go to Code Classroom" string. The cross-origin localStorage writes that the student and teacher login links performed are dropped, as localStorage cannot be read by Code Classroom on its own origin. I18n fallbacks to English are enabled to match the fallbackLng the React app configured, so a page in a partially translated locale is not left with missing-translation markup. Co-Authored-By: Claude Opus 5 (1M context) --- config/application.rb | 2 + .../assets/images/editor_app/html_file.svg | 10 ++ .../images/editor_app/ide_instructions.png | Bin 0 -> 162459 bytes .../assets/images/editor_app/python_file.svg | 11 ++ .../stylesheets/editor_app/application.css | 30 ++++ .../stylesheets/editor_app/landing_page.css | 166 ++++++++++++++++++ .../editor_app/landing_page_decoration.svg | 31 ++++ .../controllers/editor_app/home_controller.rb | 11 ++ .../helpers/editor_app/application_helper.rb | 23 +++ editor_app/app/models/editor_app/locale.rb | 5 + .../app/views/editor_app/home/show.html.erb | 74 ++++++++ .../layouts/editor_app/application.html.erb | 20 +++ .../config/locales/editor_app.en-US.yml | 22 +++ editor_app/config/locales/editor_app.en.yml | 26 +++ .../config/locales/editor_app.es-LA.yml | 22 +++ .../config/locales/editor_app.fr-FR.yml | 22 +++ .../config/locales/editor_app.ga-IE.yml | 22 +++ spec/requests/editor_app/home_spec.rb | 76 ++++++++ spec/support/negated_matchers.rb | 1 + 19 files changed, 574 insertions(+) create mode 100644 editor_app/app/assets/images/editor_app/html_file.svg create mode 100644 editor_app/app/assets/images/editor_app/ide_instructions.png create mode 100644 editor_app/app/assets/images/editor_app/python_file.svg create mode 100644 editor_app/app/assets/stylesheets/editor_app/application.css create mode 100644 editor_app/app/assets/stylesheets/editor_app/landing_page.css create mode 100644 editor_app/app/assets/stylesheets/editor_app/landing_page_decoration.svg create mode 100644 editor_app/app/controllers/editor_app/home_controller.rb create mode 100644 editor_app/app/helpers/editor_app/application_helper.rb create mode 100644 editor_app/app/views/editor_app/home/show.html.erb create mode 100644 editor_app/app/views/layouts/editor_app/application.html.erb create mode 100644 editor_app/config/locales/editor_app.en-US.yml create mode 100644 editor_app/config/locales/editor_app.en.yml create mode 100644 editor_app/config/locales/editor_app.es-LA.yml create mode 100644 editor_app/config/locales/editor_app.fr-FR.yml create mode 100644 editor_app/config/locales/editor_app.ga-IE.yml create mode 100644 spec/requests/editor_app/home_spec.rb diff --git a/config/application.rb b/config/application.rb index 838921ca0..bcd6ed57e 100644 --- a/config/application.rb +++ b/config/application.rb @@ -55,6 +55,8 @@ class Application < Rails::Application config.api_only = false + config.i18n.fallbacks = [:en] + config.middleware.insert_before 0, CorpMiddleware require 'rack/content_type_default' diff --git a/editor_app/app/assets/images/editor_app/html_file.svg b/editor_app/app/assets/images/editor_app/html_file.svg new file mode 100644 index 000000000..2448ae178 --- /dev/null +++ b/editor_app/app/assets/images/editor_app/html_file.svg @@ -0,0 +1,10 @@ + + + diff --git a/editor_app/app/assets/images/editor_app/ide_instructions.png b/editor_app/app/assets/images/editor_app/ide_instructions.png new file mode 100644 index 0000000000000000000000000000000000000000..30a07cce4bf0ce85f300079d94065cd8769028e0 GIT binary patch literal 162459 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 + + diff --git a/editor_app/app/assets/stylesheets/editor_app/application.css b/editor_app/app/assets/stylesheets/editor_app/application.css new file mode 100644 index 000000000..d09dcf033 --- /dev/null +++ b/editor_app/app/assets/stylesheets/editor_app/application.css @@ -0,0 +1,30 @@ +.editor-app { + --editor-color-layer-1: var(--rpf-off-white); + --editor-color-layer-2: var(--rpf-white); + --editor-color-layer-3: var(--rpf-white); + --editor-color-outline: var(--rpf-grey-150); + --editor-color-theme: var(--rpf-raspberry-800); + --editor-color-theme-secondary: var(--rpf-raspberry-900); + --editor-color-theme-tertiary: var(--rpf-raspberry-100); + --editor-color-text: var(--rpf-text-primary); + --editor-color-text-secondary: var(--rpf-text-secondary); + --editor-color-action: var(--rpf-navy-800); + --editor-color-layer-accent: var(--rpf-off-white-warm); + + display: flex; + flex-direction: column; + min-block-size: 100vh; + color: var(--editor-color-text); +} + +html { + font-size: 16px; +} + +body { + margin: 0; + font-family: Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", Oxygen, + Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/editor_app/app/assets/stylesheets/editor_app/landing_page.css b/editor_app/app/assets/stylesheets/editor_app/landing_page.css new file mode 100644 index 000000000..d9295f0fb --- /dev/null +++ b/editor_app/app/assets/stylesheets/editor_app/landing_page.css @@ -0,0 +1,166 @@ +.landing-page { + flex: 1; + display: flex; + flex-direction: column; + gap: var(--space-8); + align-items: center; + justify-content: center; + padding: var(--space-8) var(--space-3); + background-color: var(--editor-color-layer-accent); +} + +.landing-page__projects { + text-align: center; + inline-size: 100%; + display: flex; + flex-direction: column; + gap: var(--space-3); +} + +.landing-page__title-wrapper { + display: flex; + flex-direction: column; + gap: var(--space-1); +} + +.landing-page__action-wrapper { + display: flex; + flex-direction: column; + gap: var(--space-2); +} + +.landing-page__title { + font-size: var(--font-size-4); + font-weight: var(--font-weight-bold); + line-height: var(--line-height-3-5); + margin: 0; +} + +.landing-page__subtitle { + font-size: var(--font-size-3); + font-weight: var(--font-weight-regular); + line-height: var(--line-height-2-5); + margin: 0; +} + +.landing-page__choose-text { + font-size: var(--font-size-1-5); + font-weight: var(--font-weight-regular); + line-height: var(--line-height-1-5); + margin: var(--space-1); +} + +.landing-page__buttons { + display: flex; + flex-direction: column; + align-items: center; + inline-size: 100%; + gap: var(--space-1); +} + +@media screen and (min-width: 588px) { + .landing-page__title { + font-size: var(--font-size-5); + line-height: var(--line-height-4); + } + + .landing-page__choose-text { + font-size: var(--font-size-2); + line-height: var(--line-height-2); + } + + .landing-page__buttons { + justify-content: center; + flex-direction: row; + } +} + +.information-cards { + display: flex; + flex-direction: column; + gap: var(--space-3); + border-radius: var(--space-3); +} + +.information-card { + border: 1px solid var(--rpf-grey-150); + border-radius: var(--space-3); + padding-inline: var(--space-4) var(--space-3); + padding-block-end: var(--space-3); + background-color: var(--rpf-white); +} + +.information-card--decorative { + background-image: url("landing_page_decoration.svg"); + background-repeat: no-repeat; + background-position: bottom left; + padding-block-end: 100px; +} + +@media screen and (max-width: 587px) { + .information-card { + box-shadow: 0 12px 24px 0 rgba(0, 0, 0, 0.04); + } +} + +@media screen and (min-width: 588px) { + .information-cards { + flex-direction: row; + gap: 0; + box-shadow: 0 12px 24px 0 rgba(0, 0, 0, 0.04); + } + + .information-card--left { + border-start-end-radius: 0; + border-end-end-radius: 0; + } + + .information-card--right { + border-start-start-radius: 0; + border-end-start-radius: 0; + border-inline-start: none; + } +} + +.information-card__title { + font-size: var(--font-size-2); + font-weight: var(--font-weight-bold); + line-height: var(--line-height-2); +} + +.information-card__subtitle { + font-size: var(--font-size-1); + font-weight: var(--font-weight-bold); + line-height: var(--line-height-1-5); + margin-block-end: 0; +} + +.information-card__copy { + font-size: var(--font-size-1); + font-weight: var(--font-weight-regular); + line-height: var(--line-height-1-5); + max-inline-size: 50ch; +} + +.information-card__copy a { + font-weight: var(--font-weight-bold); + color: var(--editor-color-action); +} + +.information-card__buttons { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--space-1); +} + +.landing-page__link { + color: var(--editor-color-action); +} + +.landing-page__text-link { + font-size: var(--font-size-1); + font-weight: var(--font-weight-bold); + line-height: var(--line-height-1-5); + color: var(--editor-color-action); +} diff --git a/editor_app/app/assets/stylesheets/editor_app/landing_page_decoration.svg b/editor_app/app/assets/stylesheets/editor_app/landing_page_decoration.svg new file mode 100644 index 000000000..d63f89efb --- /dev/null +++ b/editor_app/app/assets/stylesheets/editor_app/landing_page_decoration.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/editor_app/app/controllers/editor_app/home_controller.rb b/editor_app/app/controllers/editor_app/home_controller.rb new file mode 100644 index 000000000..1baf0ea73 --- /dev/null +++ b/editor_app/app/controllers/editor_app/home_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module EditorApp + class HomeController < ApplicationController + skip_authorization_check + + def show + @school_student = current_user&.student? + end + end +end diff --git a/editor_app/app/helpers/editor_app/application_helper.rb b/editor_app/app/helpers/editor_app/application_helper.rb new file mode 100644 index 000000000..5e591bd24 --- /dev/null +++ b/editor_app/app/helpers/editor_app/application_helper.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module EditorApp + module ApplicationHelper + def code_classroom_url(path = '') + "#{ENV.fetch('EDITOR_PUBLIC_URL', nil)}#{path}" + end + + def projects_site_url(path) + "https://projects.raspberrypi.org/#{Locale.projects_site(I18n.locale)}#{path}" + end + + # The engine adds :locale to default_url_options for its own routes, so it + # has to be cleared when generating host application routes. + def login_path(return_to:) + main_app.login_path(returnTo: return_to, locale: nil) + end + + def logout_path + main_app.logout_path(locale: nil) + end + end +end diff --git a/editor_app/app/models/editor_app/locale.rb b/editor_app/app/models/editor_app/locale.rb index 48e1543e4..5a1f62825 100644 --- a/editor_app/app/models/editor_app/locale.rb +++ b/editor_app/app/models/editor_app/locale.rb @@ -10,6 +10,7 @@ module Locale 'es-LA' => 'Español (Latinoamericano)', 'fr-FR' => 'Français' }.freeze + PROJECTS_SITE_OVERRIDES = { 'en-US' => 'en' }.freeze def self.resolve(path: nil, cookie: nil, accept_language: nil) supported(path) || supported(cookie) || from_accept_language(accept_language) || DEFAULT @@ -19,6 +20,10 @@ def self.supported(locale) locale if SUPPORTED.include?(locale) end + def self.projects_site(locale) + PROJECTS_SITE_OVERRIDES.fetch(locale.to_s, locale.to_s) + end + def self.from_accept_language(header) return if header.blank? diff --git a/editor_app/app/views/editor_app/home/show.html.erb b/editor_app/app/views/editor_app/home/show.html.erb new file mode 100644 index 000000000..710f89b5b --- /dev/null +++ b/editor_app/app/views/editor_app/home/show.html.erb @@ -0,0 +1,74 @@ +<% content_for :head do %> + <%= stylesheet_link_tag 'editor_app/landing_page' %> +<% end %> + +

+ <% if @school_student %> +

<%= t('.title') %>

+ <%= render DesignSystem::ButtonComponent.new( + href: code_classroom_url("/#{I18n.locale}/school"), + text: t('.go_to_classroom') + ) %> + <%= image_tag 'editor_app/ide_instructions.png', alt: t('.ide_image_alt') %> + <% else %> +
+
+

<%= t('.title') %>

+

<%= t('.subtitle') %>

+
+
+

<%= t('.choose_language') %>

+
+ <%= render DesignSystem::ButtonComponent.new( + href: project_path('blank-python-starter'), + data: { plausible_event: 'Start coding Python' } + ) do %> + <%= image_tag 'editor_app/python_file.svg', alt: '', aria: { hidden: true } %> + <%= t('.python') %> + <% end %> + <%= render DesignSystem::ButtonComponent.new( + href: project_path('blank-html-starter'), + data: { plausible_event: 'Start coding HTML/CSS' } + ) do %> + <%= image_tag 'editor_app/html_file.svg', alt: '', aria: { hidden: true } %> + <%= t('.html') %> + <% end %> +
+
+
+ +
+
+
+

<%= t('.where_to_start') %>

+

+ <%= t('.follow_a_path_html', + python_link: link_to(t('.project_python'), projects_site_url('/pathways/python-intro'), class: 'landing-page__link'), + html_link: link_to(t('.project_html'), projects_site_url('/pathways/web-intro'), class: 'landing-page__link')) %> +

+

+ <%= t('.also_discover_html', + experience_cs_link: link_to(t('.experience_cs'), 'https://experience-cs.org', class: 'landing-page__link')) %> +

+
+
+ + <% unless current_user %> +
+
+

<%= t('.ready_to_continue') %>

+

<%= t('.continue_your_projects') %>

+ <%= button_to t('.login_to_code_editor'), + login_path(return_to: projects_path), + class: 'landing-page__text-link' %> +

<%= t('.using_code_classroom') %>

+
+ <%= link_to t('.login_as_a_student'), code_classroom_url('/auth/user_login/student'), class: 'landing-page__text-link' %> + <%= link_to t('.login_as_a_teacher'), code_classroom_url('/auth/user_login/full'), class: 'landing-page__text-link' %> +
+
+
+ <% end %> +
+ <% end %> +
diff --git a/editor_app/app/views/layouts/editor_app/application.html.erb b/editor_app/app/views/layouts/editor_app/application.html.erb new file mode 100644 index 000000000..9c1dbd2aa --- /dev/null +++ b/editor_app/app/views/layouts/editor_app/application.html.erb @@ -0,0 +1,20 @@ + + + + <%= content_for(:title).presence || t('editor_app.meta.title') %> + + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + <%= render DesignSystem::Meta::GoogleFontsComponent.new(fonts: :default) %> + <%= stylesheet_link_tag DesignSystem::STYLESHEET_URL %> + <%= stylesheet_link_tag 'editor_app/application' %> + <%= content_for :head %> + <%= javascript_importmap_tags %> + + +
+ <%= yield %> +
+ + diff --git a/editor_app/config/locales/editor_app.en-US.yml b/editor_app/config/locales/editor_app.en-US.yml new file mode 100644 index 000000000..991b33706 --- /dev/null +++ b/editor_app/config/locales/editor_app.en-US.yml @@ -0,0 +1,22 @@ +en-US: + editor_app: + home: + show: + title: "Code Editor" + subtitle: "Start coding, no setup required!" + choose_language: "What do you want to code with?" + python: "Python" + html: "HTML/CSS" + where_to_start: "Not sure where to start?" + project_python: "Python path" + project_html: "Web path" + follow_a_path_html: "Explore %{python_link} or %{html_link} on our Projects site for guided learning." + also_discover_html: "Teachers can also discover %{experience_cs_link}, a Scratch-based curriculum with step-by-step projects for the classroom." + experience_cs: "Experience CS" + ready_to_continue: "Ready to continue?" + continue_your_projects: "Continue your projects" + using_code_classroom: "Using Code Classroom?" + login_to_code_editor: "Log in to Code Editor" + login_as_a_student: "Log in as a student" + login_as_a_teacher: "Log in as a teacher" + go_to_classroom: "Go to Code Classroom" diff --git a/editor_app/config/locales/editor_app.en.yml b/editor_app/config/locales/editor_app.en.yml new file mode 100644 index 000000000..7f7a8535f --- /dev/null +++ b/editor_app/config/locales/editor_app.en.yml @@ -0,0 +1,26 @@ +en: + editor_app: + meta: + title: Code Editor | Raspberry Pi + description: Code Editor, created by the Raspberry Pi Foundation + home: + show: + title: Code Editor + subtitle: Start coding, no setup required! + choose_language: What do you want to code with? + python: Python + html: HTML/CSS + where_to_start: Not sure where to start? + project_python: Python path + project_html: Web path + follow_a_path_html: Explore the %{python_link} or %{html_link} on our Projects site for guided learning. + also_discover_html: Teachers can also discover %{experience_cs_link}, a Scratch-based curriculum with step-by-step projects for the classroom. + experience_cs: Experience CS + ready_to_continue: Ready to continue? + continue_your_projects: Continue your projects + using_code_classroom: Using Code Classroom? + login_to_code_editor: Log in to Code Editor + login_as_a_student: Log in as a student + login_as_a_teacher: Log in as a teacher + go_to_classroom: Go to Code Classroom + ide_image_alt: A Code Editor project with instructions alongside the code diff --git a/editor_app/config/locales/editor_app.es-LA.yml b/editor_app/config/locales/editor_app.es-LA.yml new file mode 100644 index 000000000..069e2a4b5 --- /dev/null +++ b/editor_app/config/locales/editor_app.es-LA.yml @@ -0,0 +1,22 @@ +es-LA: + editor_app: + home: + show: + title: "Code Editor" + subtitle: "¡Empieza a programar! No hace falta configurar nada" + choose_language: "¿En qué lenguaje quieres programar?" + python: "Python" + html: "HTML/CSS" + where_to_start: "¿No sabes por dónde empezar?" + project_python: "Ruta de Python" + project_html: "Ruta web" + follow_a_path_html: "Explora la %{python_link} o la %{html_link} en nuestro sitio de proyectos para acceder a un aprendizaje guiado." + also_discover_html: "Si eres docente, también puedes explorar %{experience_cs_link}, un plan de estudios basado en Scratch con proyectos paso a paso para el aula." + experience_cs: "Experience CS" + ready_to_continue: "¿Quieres continuar?" + continue_your_projects: "Ir a tus proyectos" + using_code_classroom: "¿Usas Code Classroom?" + login_to_code_editor: "Inicia sesión en el Code Editor" + login_as_a_student: "Inicia sesión como estudiante" + login_as_a_teacher: "Inicia sesión como docente" + go_to_classroom: "Ir a Code Classroom" diff --git a/editor_app/config/locales/editor_app.fr-FR.yml b/editor_app/config/locales/editor_app.fr-FR.yml new file mode 100644 index 000000000..e7149a859 --- /dev/null +++ b/editor_app/config/locales/editor_app.fr-FR.yml @@ -0,0 +1,22 @@ +fr-FR: + editor_app: + home: + show: + title: "Code Editor" + subtitle: "Commencer à coder, aucune configuration requise!" + choose_language: "Dans quel langage voulez-vous coder?" + python: "Python" + html: "HTML/CSS" + where_to_start: "Vous ne savez pas par où commencer?" + project_python: "Chemin Python" + project_html: "Chemin Web" + follow_a_path_html: "Explorez le %{python_link} ou %{html_link} sur notre site de projets pour un apprentissage guidé." + also_discover_html: "Les enseignants et enseignantes peuvent aussi découvrir %{experience_cs_link}, un programme utilisant Scratch qui propose des projets détaillés à faire en classe." + experience_cs: "Experience CS" + ready_to_continue: "Vous souhaitez poursuivre?" + continue_your_projects: "Continuer vos projets" + using_code_classroom: "Vous utilisez Code Classroom?" + login_to_code_editor: "Se connecter au Code Editor" + login_as_a_student: "Se connecter en tant qu’élève" + login_as_a_teacher: "Se connecter en tant qu’enseignant ou enseignante" + go_to_classroom: "Aller à Code Classroom" diff --git a/editor_app/config/locales/editor_app.ga-IE.yml b/editor_app/config/locales/editor_app.ga-IE.yml new file mode 100644 index 000000000..11ac4c294 --- /dev/null +++ b/editor_app/config/locales/editor_app.ga-IE.yml @@ -0,0 +1,22 @@ +ga-IE: + editor_app: + home: + show: + title: "Code Editor" + subtitle: "Tosaigh ag códú, ní gá aon rud a shocrú!" + choose_language: "Céard is mian leat códú leis?" + python: "Python" + html: "HTML/CSS" + where_to_start: "Níl tú cinnte cá háit le tosú?" + project_python: "Cosán Python" + project_html: "Cosán gréasáin" + follow_a_path_html: "Fiosraigh an %{python_link} nó %{html_link} ar ár suíomh Tionscadail chun foghlaim threoraithe a fháil." + also_discover_html: "Is féidir le múinteoirí %{experience_cs_link} a fhoghlaim freisin, curaclam bunaithe ar Scratch le tionscadail céim ar chéim don seomra ranga." + experience_cs: "Experience CS" + ready_to_continue: "Réidh le dul ar aghaidh?" + continue_your_projects: "Lean le do thionscadail" + using_code_classroom: "Ag úsáid Code Classroom?" + login_to_code_editor: "Logáil isteach sa Code Editor" + login_as_a_student: "Logáil isteach mar dhalta" + login_as_a_teacher: "Logáil isteach mar mhúinteoir" + go_to_classroom: "Téigh go Code Classroom" diff --git a/spec/requests/editor_app/home_spec.rb b/spec/requests/editor_app/home_spec.rb new file mode 100644 index 000000000..0f51de579 --- /dev/null +++ b/spec/requests/editor_app/home_spec.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Code Editor home page' do + around do |example| + ClimateControl.modify( + EDITOR_APP_HOSTS: 'editor.example.com', + EDITOR_PUBLIC_URL: 'https://classroom.example.com' + ) { example.run } + end + + it 'responds 200 OK' do + get 'http://editor.example.com/en' + expect(response).to have_http_status(:ok) + end + + it 'offers a starter project for each language' do + get 'http://editor.example.com/en' + expect(response.body).to include('/en/projects/blank-python-starter') + .and include('/en/projects/blank-html-starter') + end + + it 'renders the page in the locale from the path' do + get 'http://editor.example.com/fr-FR' + expect(response.body).to include('Commencer à coder, aucune configuration requise!') + .and include('') + end + + it 'links to the Projects site in the equivalent locale' do + get 'http://editor.example.com/en-US' + expect(response.body).to include('https://projects.raspberrypi.org/en/pathways/python-intro') + end + + context 'when nobody is signed in' do + it 'offers a way to log in to the Code Editor' do + get 'http://editor.example.com/en' + expect(response.body).to include('Log in to Code Editor') + end + + it 'sends the Code Editor login to the project index after authenticating' do + get 'http://editor.example.com/en' + expect(response.body).to include(CGI.escapeHTML('/auth/rpi?returnTo=%2Fen%2Fprojects')) + end + + it 'offers the Code Classroom logins' do + get 'http://editor.example.com/en' + expect(response.body).to include('https://classroom.example.com/auth/user_login/student') + .and include('https://classroom.example.com/auth/user_login/full') + end + end + + context 'when a user is signed in' do + before { stub_sign_in(create(:user)) } + + it 'does not offer the login options' do + get 'http://editor.example.com/en' + expect(response.body).not_to include('Log in to Code Editor') + end + + it 'still offers the starter projects' do + get 'http://editor.example.com/en' + expect(response.body).to include('/en/projects/blank-python-starter') + end + end + + context 'when a school student is signed in' do + before { stub_sign_in(create(:student)) } + + it 'sends them to Code Classroom rather than offering starter projects' do + get 'http://editor.example.com/en' + expect(response.body).to include('https://classroom.example.com/en/school') + .and not_include('/en/projects/blank-python-starter') + end + end +end diff --git a/spec/support/negated_matchers.rb b/spec/support/negated_matchers.rb index 575ecfc7a..f83a5bd34 100644 --- a/spec/support/negated_matchers.rb +++ b/spec/support/negated_matchers.rb @@ -3,3 +3,4 @@ # Negated forms of common matchers, for use inside compound expectations like # `.to have_enqueued_job(A).and not_have_enqueued_job(B)`. RSpec::Matchers.define_negated_matcher :not_have_enqueued_job, :have_enqueued_job +RSpec::Matchers.define_negated_matcher :not_include, :include From de5bc0228852cf339d4e7d0c06975a5442a8f44d Mon Sep 17 00:00:00 2001 From: Chris Zetter <253059100+zetter-rpf@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:25:17 +0100 Subject: [PATCH 04/18] Show the global navigation on Code Editor pages The Code Editor pages had no navigation, so there was no way to log in, log out or change language from them. This change renders the global navigation from its Stencil web component build, which exists specifically for server-rendered apps: it posts to paths the host application already provides at /auth/rpi and /logout, and takes the per-form CSRF tokens those posts need. In the React app the language links were placeholders that JavaScript intercepted; here they are real links to the current page in the chosen language, so changing language works without JavaScript. The account dropdown is hidden for school students, matching the React app, which decided this from the user type held in its Redux store. Co-Authored-By: Claude Opus 5 (1M context) --- .../stylesheets/editor_app/application.css | 4 ++ .../editor_app/global_nav_component.html.erb | 12 ++++ .../editor_app/global_nav_component.rb | 50 +++++++++++++++ .../helpers/editor_app/application_helper.rb | 14 ++-- .../app/views/editor_app/home/show.html.erb | 2 +- .../layouts/editor_app/application.html.erb | 5 ++ editor_app/lib/editor_app/engine.rb | 2 - .../editor_app/global_nav_component_spec.rb | 64 +++++++++++++++++++ spec/rails_helper.rb | 2 + spec/requests/editor_app/home_spec.rb | 5 ++ 10 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 editor_app/app/components/editor_app/global_nav_component.html.erb create mode 100644 editor_app/app/components/editor_app/global_nav_component.rb create mode 100644 spec/components/editor_app/global_nav_component_spec.rb diff --git a/editor_app/app/assets/stylesheets/editor_app/application.css b/editor_app/app/assets/stylesheets/editor_app/application.css index d09dcf033..f53bdefe8 100644 --- a/editor_app/app/assets/stylesheets/editor_app/application.css +++ b/editor_app/app/assets/stylesheets/editor_app/application.css @@ -28,3 +28,7 @@ body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + +rpf-global-nav { + min-block-size: 2.875rem; +} diff --git a/editor_app/app/components/editor_app/global_nav_component.html.erb b/editor_app/app/components/editor_app/global_nav_component.html.erb new file mode 100644 index 000000000..03f29edcb --- /dev/null +++ b/editor_app/app/components/editor_app/global_nav_component.html.erb @@ -0,0 +1,12 @@ + + +> diff --git a/editor_app/app/components/editor_app/global_nav_component.rb b/editor_app/app/components/editor_app/global_nav_component.rb new file mode 100644 index 000000000..81d6daa76 --- /dev/null +++ b/editor_app/app/components/editor_app/global_nav_component.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module EditorApp + class GlobalNavComponent < ViewComponent::Base + VERSION = 'v1.8.9' + SCRIPT_URL = "https://static.raspberrypi.org/js/global-nav-web-component/releases/#{VERSION}/rpf-global-nav.esm.js".freeze + FORCE_SIGNUP = 'force_signup' + LOCALE_PREFIX = %r{\A/[a-z]{2}(-[A-Z]{2})?(?=/|\z)} + + attr_reader :current_path, :signed_in, :student + + def initialize(current_path:, signed_in:, student: false) + super() + @current_path = current_path + @signed_in = signed_in + @student = student + end + + def script_url + SCRIPT_URL + end + + def locales + Locale::SELECTABLE.to_h { |locale, text| [locale, { url: path_in_locale(locale), text: }] }.to_json + end + + def log_in_path + helpers.editor_login_path(return_to: current_path) + end + + def sign_up_path + helpers.editor_login_path(return_to: current_path, login_options: FORCE_SIGNUP) + end + + def log_out_path + helpers.editor_logout_path + end + + def authenticity_token + helpers.editor_login_authenticity_token + end + + private + + def path_in_locale(locale) + remainder = current_path.sub(LOCALE_PREFIX, '') + "/#{locale}#{remainder unless remainder == '/'}" + end + end +end diff --git a/editor_app/app/helpers/editor_app/application_helper.rb b/editor_app/app/helpers/editor_app/application_helper.rb index 5e591bd24..bbe55b2d5 100644 --- a/editor_app/app/helpers/editor_app/application_helper.rb +++ b/editor_app/app/helpers/editor_app/application_helper.rb @@ -10,14 +10,18 @@ def projects_site_url(path) "https://projects.raspberrypi.org/#{Locale.projects_site(I18n.locale)}#{path}" end - # The engine adds :locale to default_url_options for its own routes, so it - # has to be cleared when generating host application routes. - def login_path(return_to:) - main_app.login_path(returnTo: return_to, locale: nil) + # Login happens in the host application, so :locale is cleared from the + # engine's default_url_options to keep it out of host application paths. + def editor_login_path(return_to:, login_options: nil) + main_app.login_path({ returnTo: return_to, login_options: }.compact.merge(locale: nil)) end - def logout_path + def editor_logout_path main_app.logout_path(locale: nil) end + + def editor_login_authenticity_token + form_authenticity_token(form_options: { action: main_app.login_path(locale: nil), method: 'post' }) + end end end diff --git a/editor_app/app/views/editor_app/home/show.html.erb b/editor_app/app/views/editor_app/home/show.html.erb index 710f89b5b..b9c89c19c 100644 --- a/editor_app/app/views/editor_app/home/show.html.erb +++ b/editor_app/app/views/editor_app/home/show.html.erb @@ -59,7 +59,7 @@

<%= t('.ready_to_continue') %>

<%= t('.continue_your_projects') %>

<%= button_to t('.login_to_code_editor'), - login_path(return_to: projects_path), + editor_login_path(return_to: projects_path), class: 'landing-page__text-link' %>

<%= t('.using_code_classroom') %>

diff --git a/editor_app/app/views/layouts/editor_app/application.html.erb b/editor_app/app/views/layouts/editor_app/application.html.erb index 9c1dbd2aa..34ad98573 100644 --- a/editor_app/app/views/layouts/editor_app/application.html.erb +++ b/editor_app/app/views/layouts/editor_app/application.html.erb @@ -14,6 +14,11 @@
+ <%= render EditorApp::GlobalNavComponent.new( + current_path: request.path, + signed_in: current_user.present?, + student: current_user&.student? || false + ) %> <%= yield %>
diff --git a/editor_app/lib/editor_app/engine.rb b/editor_app/lib/editor_app/engine.rb index 382528605..0789cc582 100644 --- a/editor_app/lib/editor_app/engine.rb +++ b/editor_app/lib/editor_app/engine.rb @@ -6,8 +6,6 @@ module EditorApp class Engine < ::Rails::Engine isolate_namespace EditorApp - config.autoload_paths << root.join('app/components').to_s - initializer 'editor_app.assets' do |app| app.config.assets.paths << root.join('app/javascript') end diff --git a/spec/components/editor_app/global_nav_component_spec.rb b/spec/components/editor_app/global_nav_component_spec.rb new file mode 100644 index 000000000..5fe95abe2 --- /dev/null +++ b/spec/components/editor_app/global_nav_component_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe EditorApp::GlobalNavComponent, type: :component do + subject(:rendered) do + with_controller_class(EditorApp::HomeController) { render_inline(component) } + end + + let(:component) { described_class.new(current_path: '/en/projects', signed_in: false) } + + it 'tells the nav which locale the page is in' do + expect(rendered.css('rpf-global-nav').attr('locale').value).to eq('en') + end + + it 'offers each selectable language at the equivalent path in that language' do + locales = JSON.parse(rendered.css('rpf-global-nav').attr('locales').value) + + expect(locales).to include( + 'fr-FR' => { 'url' => '/fr-FR/projects', 'text' => 'Français' }, + 'en-US' => { 'url' => '/en-US/projects', 'text' => 'English (US)' } + ) + end + + it 'keeps the return path so logging in comes back to the current page' do + expect(rendered.css('rpf-global-nav').attr('log-in-path').value) + .to eq('/auth/rpi?returnTo=%2Fen%2Fprojects') + end + + it 'asks for a fresh account when signing up' do + expect(rendered.css('rpf-global-nav').attr('sign-up-path').value) + .to include('login_options=force_signup') + end + + it 'gives the nav a token its forms can post with' do + expect(rendered.css('rpf-global-nav').attr('log-in-token').value).to be_present + end + + context 'when the path has no locale prefix' do + let(:component) { described_class.new(current_path: '/', signed_in: false) } + + it 'points each language at its own root' do + locales = JSON.parse(rendered.css('rpf-global-nav').attr('locales').value) + + expect(locales['es-LA']['url']).to eq('/es-LA') + end + end + + context 'when a school student is signed in' do + let(:component) { described_class.new(current_path: '/en', signed_in: true, student: true) } + + it 'hides the account dropdown, which students cannot use' do + expect(rendered.css('rpf-global-nav').attr('hide-account-dropdown')).to be_present + end + end + + context 'when a full account is signed in' do + let(:component) { described_class.new(current_path: '/en', signed_in: true) } + + it 'leaves the account dropdown in place' do + expect(rendered.css('rpf-global-nav').attr('hide-account-dropdown')).to be_nil + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 528fd668d..5a8712555 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -94,6 +94,8 @@ config.include SignInStubs, type: :request config.include SignInStubs, type: :system + config.include ViewComponent::TestHelpers, type: :component + if Bullet.enable? config.before { Bullet.start_request } config.after { Bullet.end_request } diff --git a/spec/requests/editor_app/home_spec.rb b/spec/requests/editor_app/home_spec.rb index 0f51de579..379d11ba9 100644 --- a/spec/requests/editor_app/home_spec.rb +++ b/spec/requests/editor_app/home_spec.rb @@ -15,6 +15,11 @@ expect(response).to have_http_status(:ok) end + it 'renders the global navigation' do + get 'http://editor.example.com/en' + expect(response.body).to include(' Date: Wed, 30 Sep 2026 14:28:24 +0100 Subject: [PATCH 05/18] Give the Code Editor home page its secondary navigation The home page had no way to reach your projects, your school, or the For Education page. This change ports the editor secondary nav as a view component. Which links appear is decided from the session and the user's school roles, rather than from Redux state populated by a school API request, so the nav is complete in the first response. The React nav collapsed into a JavaScript overlay with a focus trap below 600px. With at most four short links, the nav now wraps instead, which needs no JavaScript and keeps every link reachable. For Education pointed at a page whose entire content was a notice that Code Editor for Education is now Code Classroom. That URL now redirects to Code Classroom, so the page is not worth porting and existing links to it keep working. Route helpers and engine helpers reach components through the view context, so a base component delegates them to keep templates readable. Co-Authored-By: Claude Opus 5 (1M context) --- .../stylesheets/editor_app/secondary_nav.css | 80 +++++++++++++++++++ .../components/editor_app/base_component.rb | 13 +++ .../editor_app/global_nav_component.rb | 10 +-- .../secondary_nav_component.html.erb | 24 ++++++ .../editor_app/secondary_nav_component.rb | 38 +++++++++ .../editor_app/education_controller.rb | 13 +++ .../layouts/editor_app/application.html.erb | 2 + .../config/locales/editor_app.en-US.yml | 6 ++ editor_app/config/locales/editor_app.en.yml | 6 ++ .../config/locales/editor_app.es-LA.yml | 6 ++ .../config/locales/editor_app.fr-FR.yml | 6 ++ .../config/locales/editor_app.ga-IE.yml | 6 ++ editor_app/config/routes.rb | 1 + .../secondary_nav_component_spec.rb | 59 ++++++++++++++ spec/requests/editor_app/education_spec.rb | 22 +++++ spec/requests/editor_app/home_spec.rb | 5 ++ 16 files changed, 292 insertions(+), 5 deletions(-) create mode 100644 editor_app/app/assets/stylesheets/editor_app/secondary_nav.css create mode 100644 editor_app/app/components/editor_app/base_component.rb create mode 100644 editor_app/app/components/editor_app/secondary_nav_component.html.erb create mode 100644 editor_app/app/components/editor_app/secondary_nav_component.rb create mode 100644 editor_app/app/controllers/editor_app/education_controller.rb create mode 100644 spec/components/editor_app/secondary_nav_component_spec.rb create mode 100644 spec/requests/editor_app/education_spec.rb diff --git a/editor_app/app/assets/stylesheets/editor_app/secondary_nav.css b/editor_app/app/assets/stylesheets/editor_app/secondary_nav.css new file mode 100644 index 000000000..9648ea853 --- /dev/null +++ b/editor_app/app/assets/stylesheets/editor_app/secondary_nav.css @@ -0,0 +1,80 @@ +.secondary-nav { + display: flex; + align-items: center; + flex-wrap: wrap; + background-color: var(--rpf-white); + border-block: 1px solid var(--rpf-grey-150); + box-sizing: border-box; + gap: var(--space-1) var(--space-4); + inline-size: 100%; + padding-inline: var(--space-2); + padding-block: var(--space-2); + position: relative; +} + +@media (max-width: 600px) { + .secondary-nav { + padding-inline-start: var(--space-2); + padding-inline-end: var(--space-1-5); + } +} + +.secondary-nav__title { + font-size: var(--font-size-2); + line-height: var(--line-height-2); + font-weight: var(--font-weight-bold); + margin-inline-end: var(--space-4); +} + +.secondary-nav__links { + --secondary-nav-gap: var(--space-4); + + font-size: var(--font-size-1-5); + line-height: var(--line-height-1-5); + display: flex; + align-items: center; + flex-wrap: wrap; + block-size: 100%; + gap: var(--space-1) var(--secondary-nav-gap); +} + +.secondary-nav__link { + display: flex; + align-items: center; + min-block-size: var(--min-target-size); + color: var(--rpf-text-primary); + font-weight: var(--font-weight-bold); + text-decoration: none; +} + +.secondary-nav__link:hover .secondary-nav__link-text { + border-block-end: 3px solid var(--rpf-grey-150); + border-block-start: 3px solid transparent; +} + +.secondary-nav__link:focus-visible { + border: none; + outline: none; +} + +.secondary-nav__link:focus-visible .secondary-nav__link-text { + outline-offset: 4px; + outline: 3px solid var(--editor-color-action); +} + +.secondary-nav__link-text { + border-block: 3px solid transparent; +} + +.secondary-nav__link--active .secondary-nav__link-text { + border-block-end: 3px solid var(--editor-color-theme); + border-block-start: 3px solid transparent; +} + +.secondary-nav__separator { + border: none; + margin: 0; + block-size: var(--space-3); + inline-size: var(--space-0-25); + background-color: var(--rpf-grey-150); +} diff --git a/editor_app/app/components/editor_app/base_component.rb b/editor_app/app/components/editor_app/base_component.rb new file mode 100644 index 000000000..6d0cf2b9d --- /dev/null +++ b/editor_app/app/components/editor_app/base_component.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module EditorApp + # Engine route helpers and the engine's own helpers are reached through the + # view context, so they are delegated here to keep component templates + # readable. + class BaseComponent < ViewComponent::Base + delegate :home_path, :education_path, :projects_path, :project_path, + :code_classroom_url, :projects_site_url, + :editor_login_path, :editor_logout_path, :editor_login_authenticity_token, + to: :helpers + end +end diff --git a/editor_app/app/components/editor_app/global_nav_component.rb b/editor_app/app/components/editor_app/global_nav_component.rb index 81d6daa76..592d2412a 100644 --- a/editor_app/app/components/editor_app/global_nav_component.rb +++ b/editor_app/app/components/editor_app/global_nav_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module EditorApp - class GlobalNavComponent < ViewComponent::Base + class GlobalNavComponent < BaseComponent VERSION = 'v1.8.9' SCRIPT_URL = "https://static.raspberrypi.org/js/global-nav-web-component/releases/#{VERSION}/rpf-global-nav.esm.js".freeze FORCE_SIGNUP = 'force_signup' @@ -25,19 +25,19 @@ def locales end def log_in_path - helpers.editor_login_path(return_to: current_path) + editor_login_path(return_to: current_path) end def sign_up_path - helpers.editor_login_path(return_to: current_path, login_options: FORCE_SIGNUP) + editor_login_path(return_to: current_path, login_options: FORCE_SIGNUP) end def log_out_path - helpers.editor_logout_path + editor_logout_path end def authenticity_token - helpers.editor_login_authenticity_token + editor_login_authenticity_token end private diff --git a/editor_app/app/components/editor_app/secondary_nav_component.html.erb b/editor_app/app/components/editor_app/secondary_nav_component.html.erb new file mode 100644 index 000000000..ef568f2db --- /dev/null +++ b/editor_app/app/components/editor_app/secondary_nav_component.html.erb @@ -0,0 +1,24 @@ + diff --git a/editor_app/app/components/editor_app/secondary_nav_component.rb b/editor_app/app/components/editor_app/secondary_nav_component.rb new file mode 100644 index 000000000..126bfb3e7 --- /dev/null +++ b/editor_app/app/components/editor_app/secondary_nav_component.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module EditorApp + class SecondaryNavComponent < BaseComponent + HOME_PATH = %r{\A/[a-z]{2}(-[A-Z]{2})?/?\z} + + attr_reader :current_path, :user + + def initialize(current_path:, user: nil) + super() + @current_path = current_path + @user = user + end + + # The React nav showed itself only on the home and education pages. + def render? + HOME_PATH.match?(current_path) + end + + def show_projects? + user.present? && !user.student? + end + + def show_school? + user.present? && user.schools.active.any? + end + + def show_separator? + show_projects? || show_school? + end + + def link_classes(path) + classes = ['secondary-nav__link'] + classes << 'secondary-nav__link--active' if current_path.chomp('/') == path.chomp('/') + classes.join(' ') + end + end +end diff --git a/editor_app/app/controllers/editor_app/education_controller.rb b/editor_app/app/controllers/editor_app/education_controller.rb new file mode 100644 index 000000000..9a86a6818 --- /dev/null +++ b/editor_app/app/controllers/editor_app/education_controller.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module EditorApp + class EducationController < ApplicationController + skip_authorization_check + + # The page this replaced existed only to tell teachers that Code Editor + # for Education is now Code Classroom. + def show + redirect_to helpers.code_classroom_url("/#{I18n.locale}/school"), allow_other_host: true + end + end +end diff --git a/editor_app/app/views/layouts/editor_app/application.html.erb b/editor_app/app/views/layouts/editor_app/application.html.erb index 34ad98573..623bbc816 100644 --- a/editor_app/app/views/layouts/editor_app/application.html.erb +++ b/editor_app/app/views/layouts/editor_app/application.html.erb @@ -9,6 +9,7 @@ <%= render DesignSystem::Meta::GoogleFontsComponent.new(fonts: :default) %> <%= stylesheet_link_tag DesignSystem::STYLESHEET_URL %> <%= stylesheet_link_tag 'editor_app/application' %> + <%= stylesheet_link_tag 'editor_app/secondary_nav' %> <%= content_for :head %> <%= javascript_importmap_tags %> @@ -19,6 +20,7 @@ signed_in: current_user.present?, student: current_user&.student? || false ) %> + <%= render EditorApp::SecondaryNavComponent.new(current_path: request.path, user: current_user) %> <%= yield %>
diff --git a/editor_app/config/locales/editor_app.en-US.yml b/editor_app/config/locales/editor_app.en-US.yml index 991b33706..40cb97083 100644 --- a/editor_app/config/locales/editor_app.en-US.yml +++ b/editor_app/config/locales/editor_app.en-US.yml @@ -20,3 +20,9 @@ en-US: login_as_a_student: "Log in as a student" login_as_a_teacher: "Log in as a teacher" go_to_classroom: "Go to Code Classroom" + secondary_nav: + code_editor: "Code Editor" + home: "Home" + education: "For Education" + projects: "Your Projects" + school: "Your School" diff --git a/editor_app/config/locales/editor_app.en.yml b/editor_app/config/locales/editor_app.en.yml index 7f7a8535f..86a92b159 100644 --- a/editor_app/config/locales/editor_app.en.yml +++ b/editor_app/config/locales/editor_app.en.yml @@ -24,3 +24,9 @@ en: login_as_a_teacher: Log in as a teacher go_to_classroom: Go to Code Classroom ide_image_alt: A Code Editor project with instructions alongside the code + secondary_nav: + code_editor: "Code Editor" + home: "Home" + education: "For Education" + projects: "Your Projects" + school: "Your School" diff --git a/editor_app/config/locales/editor_app.es-LA.yml b/editor_app/config/locales/editor_app.es-LA.yml index 069e2a4b5..b43294521 100644 --- a/editor_app/config/locales/editor_app.es-LA.yml +++ b/editor_app/config/locales/editor_app.es-LA.yml @@ -20,3 +20,9 @@ es-LA: login_as_a_student: "Inicia sesión como estudiante" login_as_a_teacher: "Inicia sesión como docente" go_to_classroom: "Ir a Code Classroom" + secondary_nav: + code_editor: "Code Editor" + home: "Inicio" + education: "For Education" + projects: "Tus proyectos" + school: "Tu escuela" diff --git a/editor_app/config/locales/editor_app.fr-FR.yml b/editor_app/config/locales/editor_app.fr-FR.yml index e7149a859..418188b02 100644 --- a/editor_app/config/locales/editor_app.fr-FR.yml +++ b/editor_app/config/locales/editor_app.fr-FR.yml @@ -20,3 +20,9 @@ fr-FR: login_as_a_student: "Se connecter en tant qu’élève" login_as_a_teacher: "Se connecter en tant qu’enseignant ou enseignante" go_to_classroom: "Aller à Code Classroom" + secondary_nav: + code_editor: "Code Editor" + home: "Accueil" + education: "For Education" + projects: "Tes projets" + school: "Votre école" diff --git a/editor_app/config/locales/editor_app.ga-IE.yml b/editor_app/config/locales/editor_app.ga-IE.yml index 11ac4c294..aa118877b 100644 --- a/editor_app/config/locales/editor_app.ga-IE.yml +++ b/editor_app/config/locales/editor_app.ga-IE.yml @@ -20,3 +20,9 @@ ga-IE: login_as_a_student: "Logáil isteach mar dhalta" login_as_a_teacher: "Logáil isteach mar mhúinteoir" go_to_classroom: "Téigh go Code Classroom" + secondary_nav: + code_editor: "Code Editor" + home: "Baile" + education: "For Education" + projects: "Do Thionscadail" + school: "Do Scoil" diff --git a/editor_app/config/routes.rb b/editor_app/config/routes.rb index 0bd1654ea..482e772ed 100644 --- a/editor_app/config/routes.rb +++ b/editor_app/config/routes.rb @@ -5,6 +5,7 @@ scope '/:locale', locale: /[a-z]{2}(-[A-Z]{2})?/ do root to: 'home#show', as: :home + get '/education', to: 'education#show', as: :education resources :projects, only: %i[index show new create edit update destroy], param: :identifier end diff --git a/spec/components/editor_app/secondary_nav_component_spec.rb b/spec/components/editor_app/secondary_nav_component_spec.rb new file mode 100644 index 000000000..ee67aab3e --- /dev/null +++ b/spec/components/editor_app/secondary_nav_component_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe EditorApp::SecondaryNavComponent, type: :component do + subject(:rendered) do + with_controller_class(EditorApp::HomeController) { render_inline(component) } + end + + around do |example| + ClimateControl.modify(EDITOR_PUBLIC_URL: 'https://classroom.example.com') { example.run } + end + + let(:component) { described_class.new(current_path: '/en', user: nil) } + + it 'links to the home page and the education page' do + expect(rendered.css('a').pluck(:href)).to eq(['/en', '/en/education']) + end + + it 'marks the current page as active' do + expect(rendered.css('.secondary-nav__link--active').attr('href').value).to eq('/en') + end + + context 'when the page is not the home page' do + let(:component) { described_class.new(current_path: '/en/projects', user: nil) } + + it 'does not render, as the nav belongs to the home page' do + expect(rendered.to_html).to be_blank + end + end + + context 'when a user with no school is signed in' do + let(:component) { described_class.new(current_path: '/en', user: create(:user)) } + + it 'offers their projects' do + expect(rendered.css('a').pluck(:href)).to include('/en/projects') + end + + it 'does not offer a school they are not part of' do + expect(rendered.to_html).not_to include('/en/school') + end + end + + context 'when a school teacher is signed in' do + let(:component) { described_class.new(current_path: '/en', user: create(:teacher, school: create(:school))) } + + it 'offers their school in Code Classroom' do + expect(rendered.css('a').pluck(:href)).to include('https://classroom.example.com/en/school') + end + end + + context 'when a school student is signed in' do + let(:component) { described_class.new(current_path: '/en', user: create(:student, school: create(:school))) } + + it 'does not offer the project index, which students cannot use' do + expect(rendered.to_html).not_to include('/en/projects') + end + end +end diff --git a/spec/requests/editor_app/education_spec.rb b/spec/requests/editor_app/education_spec.rb new file mode 100644 index 000000000..3af81fff3 --- /dev/null +++ b/spec/requests/editor_app/education_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Code Editor education page' do + around do |example| + ClimateControl.modify( + EDITOR_APP_HOSTS: 'editor.example.com', + EDITOR_PUBLIC_URL: 'https://classroom.example.com' + ) { example.run } + end + + it 'sends teachers to their school in Code Classroom' do + get 'http://editor.example.com/en/education' + expect(response).to redirect_to('https://classroom.example.com/en/school') + end + + it 'keeps the reader in their own language' do + get 'http://editor.example.com/fr-FR/education' + expect(response).to redirect_to('https://classroom.example.com/fr-FR/school') + end +end diff --git a/spec/requests/editor_app/home_spec.rb b/spec/requests/editor_app/home_spec.rb index 379d11ba9..277f64e2a 100644 --- a/spec/requests/editor_app/home_spec.rb +++ b/spec/requests/editor_app/home_spec.rb @@ -20,6 +20,11 @@ expect(response.body).to include(' Date: Wed, 30 Sep 2026 14:30:12 +0100 Subject: [PATCH 06/18] Add the footer to Code Editor pages Code Editor pages had no footer, so the terms, privacy, cookies, accessibility and safeguarding links the site is expected to carry were missing, as was the route for reporting a safeguarding concern. This change ports the footer as a view component. The React footer decided whether to show the safeguarding report from a Redux value that was an object whenever a user was signed in, so it showed the report to every signed-in user and put an undefined school id into the form. It now shows only to users who belong to an active school, and passes that school. Pages that fill the viewport suppress the footer by overriding show_footer?, rather than matching the request path against a list of page URLs as the React footer did. Co-Authored-By: Claude Opus 5 (1M context) --- .../assets/stylesheets/editor_app/footer.css | 57 +++++++++++++++++ .../editor_app/footer_component.html.erb | 26 ++++++++ .../components/editor_app/footer_component.rb | 42 +++++++++++++ .../editor_app/application_controller.rb | 7 +++ .../layouts/editor_app/application.html.erb | 4 ++ .../config/locales/editor_app.en-US.yml | 11 ++++ editor_app/config/locales/editor_app.en.yml | 11 ++++ .../config/locales/editor_app.es-LA.yml | 11 ++++ .../config/locales/editor_app.fr-FR.yml | 11 ++++ .../config/locales/editor_app.ga-IE.yml | 11 ++++ .../editor_app/footer_component_spec.rb | 63 +++++++++++++++++++ spec/requests/editor_app/home_spec.rb | 6 ++ 12 files changed, 260 insertions(+) create mode 100644 editor_app/app/assets/stylesheets/editor_app/footer.css create mode 100644 editor_app/app/components/editor_app/footer_component.html.erb create mode 100644 editor_app/app/components/editor_app/footer_component.rb create mode 100644 spec/components/editor_app/footer_component_spec.rb diff --git a/editor_app/app/assets/stylesheets/editor_app/footer.css b/editor_app/app/assets/stylesheets/editor_app/footer.css new file mode 100644 index 000000000..3644e2698 --- /dev/null +++ b/editor_app/app/assets/stylesheets/editor_app/footer.css @@ -0,0 +1,57 @@ +.footer { + align-items: center; + gap: var(--space-2); + margin-block-start: auto; + padding-inline: var(--space-4); + padding-block: var(--space-2); + border-block-start: 1px solid var(--rpf-grey-150); + background-color: transparent; +} + +.footer__links-wrapper { + display: flex; + gap: var(--space-2); + flex-direction: column; +} + +.footer__top { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-between; + gap: var(--space-2); + inline-size: 100%; +} + +.footer__top--reverse { + flex-wrap: wrap-reverse; +} + +.footer__links { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-1) var(--space-2); +} + +.footer__link { + font-weight: var(--font-weight-bold); + align-items: center; + color: var(--rpf-black); +} + +.footer__report { + display: inline-flex; + align-items: center; + gap: var(--space-1); + flex-wrap: wrap; + margin: 0; + padding: 0; +} + +.footer__text { + margin: 0; +} diff --git a/editor_app/app/components/editor_app/footer_component.html.erb b/editor_app/app/components/editor_app/footer_component.html.erb new file mode 100644 index 000000000..21b5fab2c --- /dev/null +++ b/editor_app/app/components/editor_app/footer_component.html.erb @@ -0,0 +1,26 @@ +
+ +
diff --git a/editor_app/app/components/editor_app/footer_component.rb b/editor_app/app/components/editor_app/footer_component.rb new file mode 100644 index 000000000..b411ca420 --- /dev/null +++ b/editor_app/app/components/editor_app/footer_component.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module EditorApp + class FooterComponent < BaseComponent + HELP_URL = 'https://help.editor.raspberrypi.org/hc/en-us' + FEEDBACK_URL = 'https://form.raspberrypi.org/f/code-editor-feedback' + TERMS_URL = 'https://my.raspberrypi.org/code-classroom-terms' + SAFEGUARDING_URL = 'https://www.raspberrypi.org/safeguarding/' + ACCESSIBILITY_URL = 'https://www.raspberrypi.org/accessibility/' + PRIVACY_URL = 'https://www.raspberrypi.org/privacy/' + COOKIES_URL = 'https://www.raspberrypi.org/cookies/' + REPORT_CONCERN_URL = 'https://form.raspberrypi.org/f/report-concern-code-editor-for-education' + + attr_reader :user, :show_feedback_link + + def initialize(user: nil, show_feedback_link: false) + super() + @user = user + @show_feedback_link = show_feedback_link + end + + def school + @school ||= user&.schools&.active&.first + end + + def report_concern_url + "#{REPORT_CONCERN_URL}?tfa_2019=#{user.id}&tfa_2021=#{school.id}" + end + + def links + [ + [t('editor_app.footer.help'), HELP_URL], + ([t('editor_app.footer.feedback'), FEEDBACK_URL] if show_feedback_link), + [t('editor_app.footer.terms_and_conditions'), TERMS_URL], + [t('editor_app.footer.safeguarding'), SAFEGUARDING_URL], + [t('editor_app.footer.accessibility'), ACCESSIBILITY_URL], + [t('editor_app.footer.privacy'), PRIVACY_URL], + [t('editor_app.footer.cookies'), COOKIES_URL] + ].compact + end + end +end diff --git a/editor_app/app/controllers/editor_app/application_controller.rb b/editor_app/app/controllers/editor_app/application_controller.rb index 805313faf..c307b9396 100644 --- a/editor_app/app/controllers/editor_app/application_controller.rb +++ b/editor_app/app/controllers/editor_app/application_controller.rb @@ -8,8 +8,15 @@ class ApplicationController < ::ApplicationController around_action :switch_locale + helper_method :show_footer? + private + # The editor takes over the whole viewport, so its pages opt out. + def show_footer? + true + end + def switch_locale(&) I18n.with_locale(requested_locale, &) end diff --git a/editor_app/app/views/layouts/editor_app/application.html.erb b/editor_app/app/views/layouts/editor_app/application.html.erb index 623bbc816..58173a943 100644 --- a/editor_app/app/views/layouts/editor_app/application.html.erb +++ b/editor_app/app/views/layouts/editor_app/application.html.erb @@ -10,6 +10,7 @@ <%= stylesheet_link_tag DesignSystem::STYLESHEET_URL %> <%= stylesheet_link_tag 'editor_app/application' %> <%= stylesheet_link_tag 'editor_app/secondary_nav' %> + <%= stylesheet_link_tag 'editor_app/footer' %> <%= content_for :head %> <%= javascript_importmap_tags %> @@ -22,6 +23,9 @@ ) %> <%= render EditorApp::SecondaryNavComponent.new(current_path: request.path, user: current_user) %> <%= yield %> + <% if show_footer? %> + <%= render EditorApp::FooterComponent.new(user: current_user, show_feedback_link: true) %> + <% end %> diff --git a/editor_app/config/locales/editor_app.en-US.yml b/editor_app/config/locales/editor_app.en-US.yml index 40cb97083..79f87298e 100644 --- a/editor_app/config/locales/editor_app.en-US.yml +++ b/editor_app/config/locales/editor_app.en-US.yml @@ -26,3 +26,14 @@ en-US: education: "For Education" projects: "Your Projects" school: "Your School" + footer: + charity_name_and_number: "Raspberry Pi Foundation UK registered charity 1129409" + safeguarding_concern: "Do you have a safeguarding concern?" + contact_us: "Report a concern" + help: "Help" + feedback: "Feedback" + terms_and_conditions: "Terms & Conditions" + safeguarding: "Safeguarding" + accessibility: "Accessibility" + privacy: "Privacy" + cookies: "Cookies" diff --git a/editor_app/config/locales/editor_app.en.yml b/editor_app/config/locales/editor_app.en.yml index 86a92b159..9ab9657e5 100644 --- a/editor_app/config/locales/editor_app.en.yml +++ b/editor_app/config/locales/editor_app.en.yml @@ -30,3 +30,14 @@ en: education: "For Education" projects: "Your Projects" school: "Your School" + footer: + charity_name_and_number: "Raspberry Pi Foundation UK registered charity 1129409" + safeguarding_concern: "Do you have a safeguarding concern?" + contact_us: "Report a concern" + help: "Help" + feedback: "Feedback" + terms_and_conditions: "Terms & Conditions" + safeguarding: "Safeguarding" + accessibility: "Accessibility" + privacy: "Privacy" + cookies: "Cookies" diff --git a/editor_app/config/locales/editor_app.es-LA.yml b/editor_app/config/locales/editor_app.es-LA.yml index b43294521..6f0a94bf9 100644 --- a/editor_app/config/locales/editor_app.es-LA.yml +++ b/editor_app/config/locales/editor_app.es-LA.yml @@ -26,3 +26,14 @@ es-LA: education: "For Education" projects: "Tus proyectos" school: "Tu escuela" + footer: + charity_name_and_number: "Fundación Raspberry Pi, organización benéfica registrada en el Reino Unido 1129409" + safeguarding_concern: "¿Tienes alguna inquietud en relación con la seguridad?" + contact_us: "Informar una inquietud" + help: "Ayuda" + feedback: "Comentarios" + terms_and_conditions: "Términos y condiciones" + safeguarding: "Protección" + accessibility: "Accesibilidad" + privacy: "Privacidad" + cookies: "Cookies" diff --git a/editor_app/config/locales/editor_app.fr-FR.yml b/editor_app/config/locales/editor_app.fr-FR.yml index 418188b02..1d071b538 100644 --- a/editor_app/config/locales/editor_app.fr-FR.yml +++ b/editor_app/config/locales/editor_app.fr-FR.yml @@ -26,3 +26,14 @@ fr-FR: education: "For Education" projects: "Tes projets" school: "Votre école" + footer: + charity_name_and_number: "Raspberry Pi Foundation, organisme de charité enregistré au Royaume-Uni sous le numéro 1129409" + safeguarding_concern: "Avez-vous une préoccupation en matière de sécurité?" + contact_us: "Signaler une préoccupation" + help: "Aide" + feedback: "Avis" + terms_and_conditions: "Conditions d’utilisation" + safeguarding: "Protection" + accessibility: "Accessibilité" + privacy: "Protection de la vie privée" + cookies: "Témoins" diff --git a/editor_app/config/locales/editor_app.ga-IE.yml b/editor_app/config/locales/editor_app.ga-IE.yml index aa118877b..3a8d1250e 100644 --- a/editor_app/config/locales/editor_app.ga-IE.yml +++ b/editor_app/config/locales/editor_app.ga-IE.yml @@ -26,3 +26,14 @@ ga-IE: education: "For Education" projects: "Do Thionscadail" school: "Do Scoil" + footer: + charity_name_and_number: "Raspberry Pi Foundation UK Carthanas Cláraithe 1129409" + safeguarding_concern: "An bhfuil imní ort faoi chosaint?" + contact_us: "Tuairiscigh imní" + help: "Cabhair" + feedback: "Aiseolas" + terms_and_conditions: "Téarmaí agus Coinníollacha" + safeguarding: "Cosaint" + accessibility: "Inrochtaineacht" + privacy: "Príobháideachas" + cookies: "Fianáin" diff --git a/spec/components/editor_app/footer_component_spec.rb b/spec/components/editor_app/footer_component_spec.rb new file mode 100644 index 000000000..830ee6118 --- /dev/null +++ b/spec/components/editor_app/footer_component_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe EditorApp::FooterComponent, type: :component do + subject(:rendered) do + with_controller_class(EditorApp::HomeController) { render_inline(component) } + end + + let(:component) { described_class.new } + + it 'names the charity behind the editor' do + expect(rendered.to_html).to include('registered charity 1129409') + end + + it 'links to help, terms, safeguarding, accessibility, privacy and cookies' do + expect(rendered.css('.footer__link').pluck(:href)).to eq( + [ + described_class::HELP_URL, + described_class::TERMS_URL, + described_class::SAFEGUARDING_URL, + described_class::ACCESSIBILITY_URL, + described_class::PRIVACY_URL, + described_class::COOKIES_URL + ] + ) + end + + it 'omits the feedback link unless it is asked for' do + expect(rendered.to_html).not_to include(described_class::FEEDBACK_URL) + end + + context 'when the feedback link is asked for' do + let(:component) { described_class.new(show_feedback_link: true) } + + it 'offers it' do + expect(rendered.css('.footer__link').pluck(:href)).to include(described_class::FEEDBACK_URL) + end + end + + context 'when a user with no school is signed in' do + let(:component) { described_class.new(user: create(:user)) } + + it 'does not offer to report a safeguarding concern, which needs a school' do + expect(rendered.to_html).not_to include('report-concern') + end + end + + context 'when a school teacher is signed in' do + let(:school) { create(:school) } + let(:teacher) { create(:teacher, school:) } + let(:component) { described_class.new(user: teacher) } + + it 'offers to report a safeguarding concern' do + expect(rendered.to_html).to include('Do you have a safeguarding concern?') + end + + it 'identifies the user and their school to the concern form' do + expect(rendered.css('.footer__link').pluck(:href)) + .to include("#{described_class::REPORT_CONCERN_URL}?tfa_2019=#{teacher.id}&tfa_2021=#{school.id}") + end + end +end diff --git a/spec/requests/editor_app/home_spec.rb b/spec/requests/editor_app/home_spec.rb index 277f64e2a..8c0f03a4b 100644 --- a/spec/requests/editor_app/home_spec.rb +++ b/spec/requests/editor_app/home_spec.rb @@ -25,6 +25,12 @@ expect(response.body).to include('secondary-nav__title') end + it 'renders the footer with the feedback link' do + get 'http://editor.example.com/en' + expect(response.body).to include('