Skip to content

Commit 4c2f905

Browse files
Add feedback panel (#249)
Exploring ideas for collecting feedback from users after they’ve completed a task. This idea is for a feedback panel which would: * keep users on the same page * start with a closed question with single-click button answers * follow-up with an optional open (free text) question The text for the follow-up question could vary based on the answer to the first question. A checkbox on the open question would allow users to say whether they’d be happy for us to contact them about their feedback or not. ## Screenshots ### After completing 5th vaccination ![localhost_3000_vaccinate_done](https://github.com/user-attachments/assets/eea71f34-e9e9-4b37-9f78-cd5a7b083d48) ### Follow-up open question ![localhost_3000_vaccinate_done (1)](https://github.com/user-attachments/assets/7a20a1c0-2871-489e-b017-4f209bf7a64a)
1 parent 5349c55 commit 4c2f905

File tree

8 files changed

+257
-2
lines changed

8 files changed

+257
-2
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
class FeedbackPanel {
2+
3+
constructor($module) {
4+
this.$module = $module
5+
this.$initialQuestion = $module.querySelector('[data-module="feedback-panel__initial-question"]')
6+
this.$feedbackComments = $module.querySelector('[data-module="feedback-panel__comments"]')
7+
this.$close = $module.querySelector('[data-module="feedback-panel__close"]')
8+
this.$sendCommentsButton = this.$feedbackComments.querySelector('.nhsuk-button')
9+
10+
}
11+
12+
init() {
13+
this.$feedbackComments.hidden = true
14+
this.$initialQuestion.querySelectorAll('.nhsuk-button').forEach((button) => {
15+
button.addEventListener('click', this.hideButtons.bind(this))
16+
})
17+
this.$close.addEventListener('click', this.hidePanel.bind(this))
18+
this.$sendCommentsButton.addEventListener('click', this.hidePanel.bind(this))
19+
20+
}
21+
22+
hidePanel() {
23+
this.$module.hidden = true
24+
}
25+
26+
hidePanelAndSayThanks() {
27+
this.$module.setAttribute('class', 'nhsuk-u-margin-bottom-4')
28+
this.$module.innerHTML = '<p class="nhsuk-body">Feedback sent.</p>'
29+
}
30+
31+
32+
hideButtons(event) {
33+
const thanksMessage = event.target.getAttribute('data-thanks')
34+
35+
const $title = this.$feedbackComments.querySelector('.app-feedback-panel__title')
36+
37+
if (thanksMessage) {
38+
$title.textContent = thanksMessage
39+
} else {
40+
$title.textContent = 'Thanks'
41+
}
42+
43+
this.$initialQuestion.hidden = true
44+
this.$feedbackComments.hidden = false
45+
46+
}
47+
48+
}
49+
50+
function initFeedbackPanels() {
51+
52+
const feedbackPanels = document.querySelectorAll('[data-module="feedback-panel"]')
53+
54+
feedbackPanels.forEach((el) => {
55+
new FeedbackPanel(el).init()
56+
})
57+
58+
}
59+
60+
document.addEventListener('DOMContentLoaded', initFeedbackPanels)

app/assets/javascript/main.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
// ES6 or Vanilla JavaScript
2+
3+
4+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.app-button-group {
2+
@include nhsuk-responsive-margin(6, "bottom");
3+
4+
align-items: center;
5+
display: flex;
6+
flex-direction: column;
7+
flex-wrap: wrap;
8+
gap: nhsuk-spacing(3) nhsuk-spacing(4);
9+
10+
.nhsuk-link {
11+
@include nhsuk-font($size: 19, $line-height: 19px);
12+
display: inline-block;
13+
margin-bottom: nhsuk-spacing(2);
14+
margin-top: nhsuk-spacing(2);
15+
max-width: 100%;
16+
text-align: center;
17+
}
18+
19+
.nhsuk-button {
20+
margin-bottom: 0;
21+
width: 100%;
22+
}
23+
24+
@include mq($from: tablet) {
25+
flex-direction: row;
26+
flex-wrap: wrap;
27+
28+
.nhsuk-button {
29+
width: auto;
30+
}
31+
32+
.nhsuk-link {
33+
text-align: left;
34+
}
35+
}
36+
}

app/assets/sass/components/_button.scss

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,63 @@
7676
font-weight: bold;
7777
color: $nhsuk-error-color;
7878
}
79+
80+
81+
// Proposed outlined button style
82+
// See https://github.com/nhsuk/nhsapp-frontend/issues/12
83+
// See https://github.com/nhsuk/nhs-app-design-styles-components-patterns
84+
@mixin app-button-outlined($button-color) {
85+
background-color: rgba($button-color, 5%);
86+
border-bottom: 0;
87+
border-color: $button-color;
88+
box-shadow: 0 4px 0 $button-color;
89+
color: $button-color;
90+
padding-bottom: nhsuk-spacing(2);
91+
padding-top: nhsuk-spacing(2);
92+
93+
&:link,
94+
&:visited {
95+
color: $button-color;
96+
}
97+
98+
&:hover {
99+
background-color: rgba($button-color, 10%);
100+
color: $button-color;
101+
}
102+
103+
&:focus {
104+
background-color: $nhsuk-focus-color;
105+
border-color: $nhsuk-focus-color;
106+
color: $nhsuk-focus-text-color;
107+
}
108+
109+
&:focus:visited:active {
110+
// Override .nhsuk-button turning colour white
111+
color: $button-color;
112+
}
113+
114+
&:active {
115+
background-color: rgba($button-color, 15%);
116+
border-bottom: $nhsuk-border-width-form-element solid; // Reintroduce 2px bottom border
117+
border-color: $button-color;
118+
color: $button-color;
119+
// Revert padding to account for reintroduction of 2px bottom border
120+
padding-bottom: 8px;
121+
padding-top: 8px;
122+
margin-bottom: -2px;
123+
}
124+
125+
&::before {
126+
bottom: #{$button-shadow-size * -1};
127+
top: #{$nhsuk-border-width-form-element * -1};
128+
}
129+
130+
&:active::before {
131+
bottom: #{($nhsuk-border-width-form-element + $button-shadow-size) * -1};
132+
top: #{($nhsuk-border-width-form-element + $button-shadow-size) * -1};
133+
}
134+
}
135+
136+
.app-button--outlined {
137+
@include app-button-outlined($nhsuk-link-color);
138+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.app-feedback-panel {
2+
background-color: $color_nhsuk-white;
3+
border-color: $color_nhsuk-blue;
4+
border-width: nhsuk-spacing(1);
5+
border-style: solid;
6+
padding: nhsuk-spacing(4);
7+
margin-bottom: nhsuk-spacing(4);
8+
}
9+
10+
.app-feedback-panel__title {
11+
@include nhsuk-typography-responsive(22);
12+
}

app/assets/sass/main.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
@import 'components/list-border';
66
@import 'components/related-nav';
77
@import 'components/indent-list';
8+
@import 'components/feedback-panel';
9+
@import 'components/button-group';
810

911
// Import GOVUK-frontend
1012
//

app/views/_feedback-panel.html

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
2+
{% block head %}
3+
<script src="/js/feedback-panel.js"></script>
4+
{% endblock %}
5+
6+
{% from 'checkboxes/macro.njk' import checkboxes %}
7+
<div class="app-feedback-panel" data-module="feedback-panel">
8+
<div data-module="feedback-panel__initial-question">
9+
<h2 class="app-feedback-panel__title">You’ve just recorded your 5th vaccination.</h2>
10+
11+
<p>How have you found using this service?</p>
12+
13+
<div class="app-button-group nhsuk-u-margin-bottom-0">
14+
{{ button({
15+
text: "Easy",
16+
classes: "app-button--outlined app-button--small",
17+
attributes: {
18+
"data-thanks": "Thank you. Do you want to tell us more?"
19+
}
20+
}) }}
21+
22+
{{ button({
23+
text: "Ok",
24+
classes: "app-button--outlined app-button--small",
25+
attributes: {
26+
"data-thanks": "Thank you. Do you want to tell us more?"
27+
}
28+
}) }}
29+
30+
{{ button({
31+
text: "Hard",
32+
classes: "app-button--outlined app-button--small",
33+
attributes: {
34+
"data-thanks": "Thank you. Do you want to tell us more?"
35+
}
36+
}) }}
37+
</div>
38+
</div>
39+
40+
<div class="app-feedback-panel__comments" data-module="feedback-panel__comments" hidden>
41+
42+
<h2 class="app-feedback-panel__title">Thank you.</h2>
43+
{{ textarea({
44+
name: "example",
45+
id: "example",
46+
rows: 3,
47+
label: {
48+
text: "Feedback (optional)"
49+
}
50+
}) }}
51+
52+
{{ checkboxes({
53+
items: [
54+
{
55+
value: "contactable",
56+
text: "I’m happy to be contacted about my feedback"
57+
}
58+
]
59+
})}}
60+
61+
62+
<div class="app-button-group nhsuk-u-margin-bottom-0">
63+
{{ button({
64+
text: "Send feedback",
65+
classes: "app-button--outlined app-button--small"
66+
}) }}
67+
68+
69+
<a href="#" class="nhsuk-link nhsuk-link--no-visited-state" data-module="feedback-panel__close">Close</a>
70+
</div>
71+
72+
</div>
73+
</div>

app/views/vaccinate/done.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33
{% set pageName = "Vaccination saved" %}
44

5+
{% set patientName = data.patientName if data.patientName else "Jodies Smith" %}
6+
57
{% set currentSection = "vaccinate" %}
68

79
{% block content %}
810
<div class="nhsuk-grid-row">
911
<div class="nhsuk-grid-column-two-thirds">
12+
13+
14+
1015
{% if (errors | length) > 0 %}
1116
{{ errorSummary({
1217
titleText: "There is a problem",
@@ -15,14 +20,16 @@
1520
{% endif %}
1621

1722
{% set panelHtml %}
18-
<a href="#" class="app-link--reverse">{{ data.patientName }}’s {{ data.vaccine }} record</a> will be sent to their GP.
23+
<a href="#" class="app-link--reverse">{{ patientName }}’s {{ data.vaccine }} record</a> will be sent to their GP.
1924
{% endset %}
25+
{% include "_feedback-panel.html" %}
2026

2127
{{ panel({
2228
titleText: "Vaccination saved",
2329
html: panelHtml
2430
}) }}
2531

32+
2633
<form action="/vaccinate/what-next" method="post" novalidate>
2734

2835
{% set lowercaseVaccineName %}
@@ -34,6 +41,8 @@
3441
A flu
3542
{% elseif (data.vaccine == "Pertussis") %}
3643
A pertussis
44+
{% else %}
45+
A COVID-19
3746
{% endif %}
3847
{% endset %}
3948

@@ -52,7 +61,7 @@
5261
items: [
5362
{
5463
value: "same-patient-another-vaccination",
55-
text: data.patientName + "’s next vaccination"
64+
text: patientName + "’s next vaccination"
5665
},
5766
{
5867
value: "same-vaccination-another-patient",

0 commit comments

Comments
 (0)