Skip to content

Commit

Permalink
feat: add usability survey
Browse files Browse the repository at this point in the history
Jira: PWNN-1800
  • Loading branch information
EdwinKruglov committed Feb 8, 2024
1 parent aa3a48c commit 0f2843b
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 2 deletions.
3 changes: 2 additions & 1 deletion app/dbTree/dbTreeFramework.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const dbTreeFramework = app => (framework, summary = '') => {
body: marked(body),
title: framework.title,
url: framework.url,
pageTitle: framework.title
pageTitle: framework.title,
feedbackUrl: `/feedback/${framework.ref}`
})
return renderedResult
}
Expand Down
3 changes: 3 additions & 0 deletions app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ routeIntroPages.route(app)
const frameworkRoutes = require('./routeFrameworks')
frameworkRoutes.route(app)

const feedbackRoutes = require('./routeFeedback')
feedbackRoutes.route(app)

app.locals.db = require('./dbTree/db')({
connectionString: process.env.MONGO_READONLY,
docStatus: process.env.DOC_STATUS || 'LIVE'
Expand Down
1 change: 1 addition & 0 deletions app/nunjucksConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const nunjucksConfig = app => {
env.addGlobal("docStatus", app.locals.db.docStatus)
env.addGlobal("sessionId", userJourney.readOrCreateSessionId(req, res))
env.addGlobal("cookieAccepted", req.cookies["cookie_consent"] == "yes")
env.addGlobal("skipSurvey", req.cookies.skipSurvey == "true")
next()
})

Expand Down
142 changes: 142 additions & 0 deletions app/routeFeedback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
const utils = require("./dbTree/utils");
const nunjucks = require("nunjucks");
const feedback = require("./services/feedback");

const easyToUseRatingRadioOptions = {
name: "easy_to_use_rating",
fieldset: {
legend: {
text: "The form was easy to use",
isPageHeading: false,
classes: "govuk-fieldset__legend--s"
}
},
items: [
{
value: "strongly_agree",
text: "Strongly agree"
},
{
value: "agree",
text: "Agree"
},
{
value: "neutral",
text: "Neutral"
},
{
value: "disagree",
text: "Disagree"
},
{
value: "strongly_disagree",
text: "Strongly disagree"
}
]
};

const route = (app) => {
app.get("/feedback/:frameworkRef", (req, res, next) => {
const db = app.locals.db;
return db.getRecord().then(doc => {
const framework = doc.framework.find(f => f.ref === req.params.frameworkRef);

if (!framework) {
return next();
}

const populatedFramework = utils.populateFramework(doc, framework);

return res.send(nunjucks.render("feedback/survey.njk", {
locals: app.locals,
pageTitle: "Feedback survey",
providerName: utils.getProviderShort(populatedFramework.provider),
frameworkUrl: populatedFramework.url,
skipUrl: `/feedback/skip/${framework.ref}`,
easyToUseRatingRadioOptions: easyToUseRatingRadioOptions
}));
});
});

app.post("/feedback/:frameworkRef", (req, res, next) => {
const db = app.locals.db;
return db.getRecord().then(doc => {
const framework = doc.framework.find(f => f.ref === req.params.frameworkRef);

if (!framework) {
return next();
}

const populatedFramework = utils.populateFramework(doc, framework);

let err = null;
if (!req.body.easy_to_use_rating) {
const errMsg = "Select how strongly you agree that this form was easy to use";
easyToUseRatingRadioOptions.errorMessage = { text: errMsg };
err = {
titleText: "There is a problem",
errorList: [
{
text: errMsg,
href: `#${easyToUseRatingRadioOptions.name}`
}
]
};
}

if (!err) {
res.cookie("skipSurvey", true);
feedback.sendFeedback(req.body, app.locals.db.docStatus);
return res.redirect(`/feedback/thank-you/${framework.ref}`);
}

return res.send(nunjucks.render("feedback/survey.njk", {
locals: app.locals,
pageTitle: "Feedback survey",
providerName: utils.getProviderShort(populatedFramework.provider),
frameworkUrl: populatedFramework.url,
skipUrl: `/feedback/skip/${framework.ref}`,
easyToUseRatingRadioOptions: easyToUseRatingRadioOptions,
err: err
}));
});
});

app.get("/feedback/thank-you/:frameworkRef", (req, res, next) => {
const db = app.locals.db;
return db.getRecord().then(doc => {
const framework = doc.framework.find(f => f.ref === req.params.frameworkRef);

if (!framework) {
return next();
}

const populatedFramework = utils.populateFramework(doc, framework);

return res.send(nunjucks.render("feedback/thank-you.njk", {
locals: app.locals,
pageTitle: "Feedback survey",
providerName: utils.getProviderShort(populatedFramework.provider),
frameworkUrl: populatedFramework.url
}));
});
});

app.get("/feedback/skip/:frameworkRef", (req, res, next) => {
const db = app.locals.db;
return db.getRecord().then(doc => {
const framework = doc.framework.find(f => f.ref === req.params.frameworkRef);

if (!framework) {
return next();
}

res.cookie("skipSurvey", true);
return res.redirect(framework.url);
});
});
};

module.exports = {
route
};
39 changes: 39 additions & 0 deletions app/services/feedback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const https = require("https");

const service = {
sendFeedback: sendFeedback
};

module.exports = service;

function sendFeedback(feedback, docStatus) {
let endpoint = docStatus === "LIVE" ? "https://www.get-help-buying-for-schools.service.gov.uk" : "https://staging.get-help-buying-for-schools.service.gov.uk";
endpoint = `${endpoint}/end_of_journey_surveys`;

const data = JSON.stringify({
easy_to_use_rating: feedback.easy_to_use_rating,
improvements: feedback.improvements,
service: "find_a_framework"
});

const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"Content-Length": Buffer.byteLength(data),
"Authorization": `Token ${process.env.GHBS_WEBHOOK_SECRET}`
}
};

const req = https.request(endpoint, options, res => {
console.log(`Send feedback statusCode: ${res.statusCode}`);
});

req.on("error", error => {
console.error(error);
});

req.write(data);
req.end();
}
2 changes: 1 addition & 1 deletion app/templates/dbTreeFramework.njk
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<li>pre-agreed terms and conditions</li>
</ul>

{{ results.button(providerShort, url) }}
{{ results.button(providerShort, url if skipSurvey else feedbackUrl) }}

{% include "summary.njk" %}

Expand Down
37 changes: 37 additions & 0 deletions app/templates/feedback/survey.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{% extends "buying-for-schools.njk" %}
{% from "radios/macro.njk" import govukRadios %}
{% from "textarea/macro.njk" import govukTextarea %}
{% import "macros/results.njk" as results %}

{% block content %}
{% if err %}
{{ govukErrorSummary(err) }}
{% endif %}

<h1 class="govuk-heading-l">Before you go</h1>
<p class="govuk-body">Please could you let us know how easy it was to use this form? Your feedback helps us make our service better.</p>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<form action="{{ currentUrl }}" method="post">
{{ govukRadios(easyToUseRatingRadioOptions) }}

{{ govukTextarea({
name: "improvements",
id: "improvements",
rows: "5",
label: {
text: "How could we improve this form?",
classes: "govuk-label--s",
isPageHeading: false
}
}) }}

<div class="govuk-button-group">
{{ govukButton({ text: "Send feedback", type: "submit"}) }}
<a href="{{skipUrl}}" class="govuk-link govuk-link--no-visited-state">Skip survey</a>
</div>
</form>
</div>
</div>
{% endblock %}
8 changes: 8 additions & 0 deletions app/templates/feedback/thank-you.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends "buying-for-schools.njk" %}
{% import "macros/results.njk" as results %}

{% block content %}
<h1 class="govuk-heading-l">Thank you for your feedback</h1>
<p class="govuk-body">We will use your feedback to make our services better.</p>
{{ results.button(providerName, frameworkUrl) }}
{% endblock %}

0 comments on commit 0f2843b

Please sign in to comment.