diff --git a/app/components/admin/performance/validation_error_component.html.erb b/app/components/admin/performance/validation_error_component.html.erb
new file mode 100644
index 0000000000..f10c763167
--- /dev/null
+++ b/app/components/admin/performance/validation_error_component.html.erb
@@ -0,0 +1,23 @@
+
+
+
+ <%= header_label %>
+
+
+
+
+ <% error.details.each do |field, info| %>
+
+
-
+ <%= field %>
+
+
-
+
<%= info['messages'].join(", ") %>
+ <%= info['value'] %>
+
+
+
+ <% end %>
+
+
+
diff --git a/app/components/admin/performance/validation_error_component.rb b/app/components/admin/performance/validation_error_component.rb
new file mode 100644
index 0000000000..36b601ed43
--- /dev/null
+++ b/app/components/admin/performance/validation_error_component.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Admin
+ module Performance
+ class ValidationErrorComponent < BaseComponent
+ attr_reader :error
+
+ def initialize(error:)
+ @error = error
+ end
+
+ def header_label
+ "#{validation_error_label}#{created_at_label}#{user_label}"
+ end
+
+ private
+
+ def validation_error_label
+ "Validation error ##{error.id.slice(0, 8)} – "
+ end
+
+ def created_at_label
+ error.created_at.strftime("%d %B %Y at %H:%M")
+ end
+
+ def user_label
+ if error.user
+ " by user #{error.user.full_name}"
+ end
+ end
+ end
+ end
+end
diff --git a/app/views/admin/performance/validation_errors/show.html.erb b/app/views/admin/performance/validation_errors/show.html.erb
index f8e4bc69f8..35f01c393e 100644
--- a/app/views/admin/performance/validation_errors/show.html.erb
+++ b/app/views/admin/performance/validation_errors/show.html.erb
@@ -6,31 +6,7 @@
Validation errors
<% @validation_errors.each do |error| %>
-
-
-
- Validation error #<%= error.id.slice(0, 8) %> –
- <%= error.created_at.strftime("%d %B %Y at %H:%M") %>
- by user <%= error.user.full_name %>
-
-
-
-
- <% error.details.each do |field, info| %>
-
-
-
- <%= field %>
-
-
-
-
<%= info['messages'].join(", ") %>
- <%= info['value'] %>
-
-
-
- <% end %>
-
-
-
+ <%= render Admin::Performance::ValidationErrorComponent.new(error: error)%>
<% end %>
<%= govuk_pagination(pagy: @pagy) %>
diff --git a/spec/components/performance/validation_error_component_spec.rb b/spec/components/performance/validation_error_component_spec.rb
new file mode 100644
index 0000000000..2a261d9ecf
--- /dev/null
+++ b/spec/components/performance/validation_error_component_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+RSpec.describe Admin::Performance::ValidationErrorComponent, type: :component do
+ subject { described_class.new(error: validation_error) }
+
+ let(:user) { create(:user, full_name: "Performance User") }
+ let(:validation_error) do
+ build(
+ :validation_error,
+ id: "0d8f4556-1c3d-4e3e-8e3e-3e3e3e3e3e3e",
+ created_at: "2023-06-16 03:27:00",
+ user:,
+ )
+ end
+
+ describe "validation error with a user" do
+ it "produces header_label with user info" do
+ expect(subject.header_label).to eq(
+ "Validation error #0d8f4556 – 16 June 2023 at 03:27 by user Performance User",
+ )
+ end
+ end
+
+ describe "validation error without a user" do
+ let(:user) { nil }
+
+ it "produces header_label without user info" do
+ expect(subject.header_label).to eq(
+ "Validation error #0d8f4556 – 16 June 2023 at 03:27",
+ )
+ end
+ end
+end