From 8f40e2a1c64d59f7b9ffded2d6db3493af4104c5 Mon Sep 17 00:00:00 2001 From: Frankie Roberto Date: Fri, 24 Apr 2026 13:19:23 +0100 Subject: [PATCH 1/7] Initial work on pharmacy chain mode --- app/routes.js | 1 + app/routes/pharmacies.js | 55 +++++++++ app/views/home/index.html | 2 +- app/views/includes/header.html | 15 +++ app/views/pharmacies/index.html | 58 +++++++++ app/views/pharmacies/pharmacy.html | 23 ++++ app/views/pharmacies/select.html | 186 +++++++++++++++++++++++++++++ 7 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 app/routes/pharmacies.js create mode 100644 app/views/pharmacies/index.html create mode 100644 app/views/pharmacies/pharmacy.html create mode 100644 app/views/pharmacies/select.html diff --git a/app/routes.js b/app/routes.js index db5607e4..c794b938 100644 --- a/app/routes.js +++ b/app/routes.js @@ -51,6 +51,7 @@ require('./routes/user-profile')(router) require('./routes/vaccines')(router) require('./routes/reports')(router) require('./routes/records')(router) +require('./routes/pharmacies')(router) require('./routes/prototype-admin')(router) require('./routes/lists')(router) require('./routes/support')(router) diff --git a/app/routes/pharmacies.js b/app/routes/pharmacies.js new file mode 100644 index 00000000..e9375d92 --- /dev/null +++ b/app/routes/pharmacies.js @@ -0,0 +1,55 @@ +const { getPharmaciesBelongingToOrganisation, getPharmacyChains, getOrganisation } = require('../lib/ods'); + +const sortByNameThenPostcode = (getPostcode = (item) => item.postcode) => (a, b) => { + if (a.name < b.name) return -1 + if (a.name > b.name) return 1 + const postcodeA = getPostcode(a) + const postcodeB = getPostcode(b) + if (postcodeA < postcodeB) return -1 + return 1 +} + +module.exports = router => { + + router.get('/pharmacies', (req, res) => { + const data = req.session.data + const currentUser = res.locals.currentUser + + const userOrganisationIds = currentUser.organisations.map((organisation) => organisation.id) + + const organisations = data.organisations.filter((organisation) => userOrganisationIds.includes(organisation.id) ) + + + res.render('pharmacies/index', { + organisations + }) + }) + + router.get('/pharmacies/select', async (req, res) => { + const data = req.session.data + const id = req.params.id + + let pharmacies = await getPharmaciesBelongingToOrganisation("P15J") + + pharmacies = pharmacies.sort(sortByNameThenPostcode((item) => item.address.postcode)) + + + res.render('pharmacies/select', { + pharmacies + }) + }) + + + router.get('/pharmacies/:id', (req, res) => { + const data = req.session.data + const id = req.params.id + + const organisation = data.organisations.find((organisation) => organisation.id === id) + + res.render('pharmacies/pharmacy', { + organisation + }) + }) + + +} diff --git a/app/views/home/index.html b/app/views/home/index.html index fad8e48b..662883cd 100644 --- a/app/views/home/index.html +++ b/app/views/home/index.html @@ -13,7 +13,7 @@ {% include "includes/notification.html" %} -

{% if currentOrganisation %}{{ currentOrganisation.name }}{% else %}Overview{% endif %}

+

{% if currentOrganisation %}{{ currentOrganisation.name }}{% else %}Peak pharmacies{% endif %}

{% if currentOrganisation and totalVaccinationsRecorded == 0 %} diff --git a/app/views/includes/header.html b/app/views/includes/header.html index 7b92876d..8881592f 100644 --- a/app/views/includes/header.html +++ b/app/views/includes/header.html @@ -11,6 +11,21 @@ active: (currentSection == "home") }), navigationItems) %} + + {% if data.currentMode == "reports" %} + {% set navigationItems = (navigationItems.push({ + href: "/pharmacies", + text: "Pharmacies", + active: (currentSection == "pharmacies") + }), navigationItems) %} + + {% set navigationItems = (navigationItems.push({ + href: "/users", + text: "Manage users", + active: (currentSection == "user-admin") + }), navigationItems) %} + {% endif %} + {% if currentOrganisation %} {% set navigationItems = (navigationItems.push({ href: "/record-vaccinations", diff --git a/app/views/pharmacies/index.html b/app/views/pharmacies/index.html new file mode 100644 index 00000000..1fe6d32d --- /dev/null +++ b/app/views/pharmacies/index.html @@ -0,0 +1,58 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies" %} + +{% block content %} +
+
+ +

Pharmacies

+ +

Add a new pharmacy or manage an existing pharmacy.

+ + {{ button({ + text: "Add pharmacy", + href: "/pharmacies/select" + }) }} + + + + + + + + + + + + + + {% for organisation in organisations %} + + + + + + + {% endfor %} + + +
Current pharmacies
+ Name + + Vaccines + + Users +
+ {{ organisation.name }} ({{ organisation.id}}) + + COVID-19 + + 1 + + Deactivate +
+
+
+ +{% endblock %} diff --git a/app/views/pharmacies/pharmacy.html b/app/views/pharmacies/pharmacy.html new file mode 100644 index 00000000..a50639f2 --- /dev/null +++ b/app/views/pharmacies/pharmacy.html @@ -0,0 +1,23 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies" %} + +{% set pageName = organisation.name %} + +{% block beforeContent %} + {{ backLink({ + href: "/pharmacies" + }) }} +{% endblock %} + +{% block content %} +
+
+ +

{{ pageName }}

+ + +
+
+ +{% endblock %} diff --git a/app/views/pharmacies/select.html b/app/views/pharmacies/select.html new file mode 100644 index 00000000..0ff4eb6d --- /dev/null +++ b/app/views/pharmacies/select.html @@ -0,0 +1,186 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies" %} + +{% block beforeContent %} + {{ backLink({ + href: "/pharmacies" + }) }} +{% endblock %} + +{% block content %} +
+
+
+ + {% set items = [] %} + + {% for pharmacy in pharmacies %} + {% set items = (items.push({ + text: pharmacy.name + ", " + pharmacy.address.postcode + " (" + pharmacy.id + ")", + value: pharmacy.id + }), items) %} + {% endfor %} + + + {% call fieldset({ + legend: { + text: "Select pharmacies", + size: "l", + classes: "nhsuk-u-margin-bottom-5" + } + }) %} + + {% if (pharmacies | length) > 1 %} + {{ checkboxes({ + idPrefix: "pharmacy-select-all", + name: "pharmacyIds", + values: data.pharmacyIds, + formGroup: { + classes: "nhsuk-u-margin-bottom-2" + }, + items: [ + { + text: "Select all " + (pharmacies | length), + value: "", + attributes: { + "data-select-all": "true" + } + }, + { + divider: "or" + } + ] + }) }} + {% endif %} + + {% if (pharmacies | length) > 20 %} + {{ input({ + id: "pharmacy-search", + name: "pharmacySearch", + type: "search", + label: { + text: "Search" + }, + classes: "nhsuk-input--width-20", + attributes: { + "data-module": "app-filter-checkboxes" + }, + formGroup: { + classes: "nhsuk-u-margin-bottom-4" + } + }) }} + {% endif %} + + +
+ {{ checkboxes({ + id: "pharmacy-ids", + name: "pharmacyIds", + values: data.pharmacyIds, + items: items + }) }} +
+ + {% endcall %} + + + {{ button({ + text: "Continue" + }) }} + +
+
+
+ + + + +{% endblock %} From 41a628b6992d688ed36b570d9ddb4bbb3dd658d9 Mon Sep 17 00:00:00 2001 From: Frankie Roberto Date: Fri, 24 Apr 2026 14:01:28 +0100 Subject: [PATCH 2/7] More work in progress --- app/data/session-data-defaults.js | 5 +- app/routes/pharmacies.js | 24 ++++++ app/views/includes/header.html | 4 +- app/views/pharmacies/check-selection.html | 58 ++++++++++++++ app/views/pharmacies/pharmacy.html | 65 +++++++++++++++ app/views/pharmacies/users/index.html | 52 ++++++++++++ app/views/pharmacies/users/new.html | 98 +++++++++++++++++++++++ 7 files changed, 302 insertions(+), 4 deletions(-) create mode 100644 app/views/pharmacies/check-selection.html create mode 100644 app/views/pharmacies/users/index.html create mode 100644 app/views/pharmacies/users/new.html diff --git a/app/data/session-data-defaults.js b/app/data/session-data-defaults.js index c0027bf0..e06dba75 100644 --- a/app/data/session-data-defaults.js +++ b/app/data/session-data-defaults.js @@ -15,8 +15,9 @@ module.exports = { vaccineStock: vaccineStock, lists: [], nhsNumberKnown: "yes", - currentUserId: "2387441662601", - currentOrganisationId: "RW3", + currentUserId: "6424325235325", + currentOrganisationId: null, + currentMode: "reports", vaccinationsRecorded: vaccinationsRecorded, // These are the options for extracting CSV reports diff --git a/app/routes/pharmacies.js b/app/routes/pharmacies.js index e9375d92..f71ba910 100644 --- a/app/routes/pharmacies.js +++ b/app/routes/pharmacies.js @@ -39,6 +39,30 @@ module.exports = router => { }) }) + router.get('/pharmacies/check-selection', async (req, res) => { + const data = req.session.data + + let pharmacies = await getPharmaciesBelongingToOrganisation("P15J") + + pharmacies = pharmacies.filter((pharmacy) => { + return data.pharmacyIds.includes(pharmacy.id) + }).sort(sortByNameThenPostcode()) + + + res.render('pharmacies/check-selection', { + pharmacies + }) + }) + + router.get('/pharmacies/users',(req, res) => { + const data = req.session.data + const users = data.users.slice(10, 20) + + res.render('pharmacies/users/index', { + users + }) + }) + router.get('/pharmacies/:id', (req, res) => { const data = req.session.data diff --git a/app/views/includes/header.html b/app/views/includes/header.html index 8881592f..58e9a25a 100644 --- a/app/views/includes/header.html +++ b/app/views/includes/header.html @@ -20,9 +20,9 @@ }), navigationItems) %} {% set navigationItems = (navigationItems.push({ - href: "/users", + href: "/pharmacies/users", text: "Manage users", - active: (currentSection == "user-admin") + active: (currentSection == "pharmacies-users") }), navigationItems) %} {% endif %} diff --git a/app/views/pharmacies/check-selection.html b/app/views/pharmacies/check-selection.html new file mode 100644 index 00000000..e1596c75 --- /dev/null +++ b/app/views/pharmacies/check-selection.html @@ -0,0 +1,58 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies" %} +{% set pageName = "Check your list of pharmacies" %} + +{% block beforeContent %} + {{ backLink({ + href: "/pharmacies/select" + }) }} +{% endblock %} + +{% block content %} +
+
+ +

{{ pageName }}

+ +

You have selected {{ pharmacies | length | plural("pharmacy") }}.

+ + + + + + + + + + + {% for pharmacy in pharmacies %} + + + + + {% endfor %} + + +
Pharmacy
{{ pharmacy.name }}, {{ pharmacy.address.postcode }} ({{ pharmacy.id }}) + {% if pharmacies | length > 1 %} +
+ + {{ button({ + text: "Remove", + classes: "nhsuk-button--small nhsuk-button--secondary nhsuk-u-margin-bottom-0" + }) }} +
+ {% endif %} +
+ +
+ {{ button({ + text: "Continue" + }) }} +
+ +
+
+ +{% endblock %} diff --git a/app/views/pharmacies/pharmacy.html b/app/views/pharmacies/pharmacy.html index a50639f2..7ce47a11 100644 --- a/app/views/pharmacies/pharmacy.html +++ b/app/views/pharmacies/pharmacy.html @@ -16,6 +16,71 @@

{{ pageName }}

+ {{ summaryList({ + rows: [ + { + key: { + text: "ODS code" + }, + value: { + text: organisation.id + } + }, + { + key: { + text: "Address" + }, + value: { + text: organisation.address.line1 + ", " + organisation.address.town + ", " + organisation.address.postcode + } + } + ] + }) }} + +

Users

+ + {{ button({ + text: "Add user" + }) }} + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Permission level + + Vaccinator + + Status +
+ Jane Smith + + Lead administrator + + Yes + + Active + +
diff --git a/app/views/pharmacies/users/index.html b/app/views/pharmacies/users/index.html new file mode 100644 index 00000000..bd940b52 --- /dev/null +++ b/app/views/pharmacies/users/index.html @@ -0,0 +1,52 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies-users" %} + +{% block content %} +
+
+ +

Users

+ +

Add a new user or manage an existing pharmacy.

+ + {{ button({ + text: "Add user", + href: "/pharmacies/users/new" + }) }} + + + + + + + + + + + + + {% for user in users %} + + + + + + {% endfor %} + + +
Current users
+ Name + + Email +
+ {{ user.firstName }} {{ user.lastName }} + + {{ user.email }} + + Deactivate +
+
+
+ +{% endblock %} diff --git a/app/views/pharmacies/users/new.html b/app/views/pharmacies/users/new.html new file mode 100644 index 00000000..c6ebdf50 --- /dev/null +++ b/app/views/pharmacies/users/new.html @@ -0,0 +1,98 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies-users" %} + +{% block beforeContent %} + {{ backLink({ + href: "/pharmacies/users" + }) }} +{% endblock %} + +{% block content %} +
+
+ +

Add user

+ +
+ + {{ input({ + "label": { + "text": "First name" + }, + "id": "first-name", + "name": "firstName", + classes: "nhsuk-input--width-20", + value: data.firstName, + "errorMessage": { + "text": firstNameError + } if firstNameError + }) }} + + {{ input({ + "label": { + "text": "Last name" + }, + "id": "last-name", + "name": "lastName", + classes: "nhsuk-input--width-20", + value: data.lastName, + "errorMessage": { + "text": lastNameError + } if lastNameError + }) }} + + {{ input({ + "label": { + "text": "Email address", + size: "s" + }, + "id": "email", + "name": "email", + type: "email", + value: data.email + }) }} + + {{ checkboxes({ + idPrefix: "example", + name: "example", + fieldset: { + legend: { + text: "Which pharmacy do you want to add them to?", + size: "s", + isPageHeading: true + } + }, + items: [ + { + value: "all", + text: "All – add them as a super admin for Peak Pharmacy" + }, + { + divider: "or" + }, + { + text: "Peak Pharmacy (P141)" + }, + { + text: "Peak Pharmacy (P931)" + }, + { + text: "Peak Pharmacy (P291)" + }, + { + text: "etc" + } + ] + }) }} + + + {{ button({ + "text": "Continue" + }) }} +
+ +
+
+ +{% endblock %} From d319388ce83a1c4301e3c4ea05c9b0d3daf276ee Mon Sep 17 00:00:00 2001 From: Frankie Roberto Date: Fri, 24 Apr 2026 14:13:12 +0100 Subject: [PATCH 3/7] More work in progress --- app/routes/pharmacies.js | 10 +++ app/views/pharmacies/pharmacy.html | 2 +- app/views/pharmacies/users/index.html | 2 +- app/views/pharmacies/users/user.html | 100 ++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 app/views/pharmacies/users/user.html diff --git a/app/routes/pharmacies.js b/app/routes/pharmacies.js index f71ba910..bd6d3173 100644 --- a/app/routes/pharmacies.js +++ b/app/routes/pharmacies.js @@ -63,6 +63,16 @@ module.exports = router => { }) }) + router.get('/pharmacies/users/:id',(req, res) => { + const data = req.session.data + const id = req.params.id + const user = data.users.find((user) => user.id === id) + + res.render('pharmacies/users/user', { + user + }) + }) + router.get('/pharmacies/:id', (req, res) => { const data = req.session.data diff --git a/app/views/pharmacies/pharmacy.html b/app/views/pharmacies/pharmacy.html index 7ce47a11..4769b4a0 100644 --- a/app/views/pharmacies/pharmacy.html +++ b/app/views/pharmacies/pharmacy.html @@ -65,7 +65,7 @@

Users

- Jane Smith + Jane Smith Lead administrator diff --git a/app/views/pharmacies/users/index.html b/app/views/pharmacies/users/index.html index bd940b52..0c530fb2 100644 --- a/app/views/pharmacies/users/index.html +++ b/app/views/pharmacies/users/index.html @@ -33,7 +33,7 @@

Users

{% for user in users %} - {{ user.firstName }} {{ user.lastName }} + {{ user.firstName }} {{ user.lastName }} {{ user.email }} diff --git a/app/views/pharmacies/users/user.html b/app/views/pharmacies/users/user.html new file mode 100644 index 00000000..6c008800 --- /dev/null +++ b/app/views/pharmacies/users/user.html @@ -0,0 +1,100 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies-users" %} + +{% set pageName = user.firstName + " " + user.lastName %} + +{% block beforeContent %} + {{ backLink({ + href: "/pharmacies/users" + }) }} +{% endblock %} + +{% block content %} +
+
+ +

{{ pageName }}

+ + {{ summaryList({ + rows: [ + { + key: { + text: "Email" + }, + value: { + text: user.email + } + } + ] + }) }} + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pharmacies
+ Name + + Permission level + + Vaccinator + + Status +
+ Peak Pharmacy (P112) + + Lead administrator + + Yes + + Active + + Remove +
+ Peak Pharmacy (P9241) + + Recorder + + Yes + + Active + + Remove +
+ +

Deactivate user from all pharmacies

+ +
+
+ +{% endblock %} From 2c13df8d800a65f9f828d1e67e194a0fb0ae137a Mon Sep 17 00:00:00 2001 From: Frankie Roberto Date: Fri, 24 Apr 2026 14:28:55 +0100 Subject: [PATCH 4/7] Add lead administrators page --- app/routes/pharmacies.js | 9 ++++ app/views/pharmacies/add-lead-admins.html | 60 +++++++++++++++++++++++ app/views/pharmacies/check-selection.html | 1 + 3 files changed, 70 insertions(+) create mode 100644 app/views/pharmacies/add-lead-admins.html diff --git a/app/routes/pharmacies.js b/app/routes/pharmacies.js index bd6d3173..408bb722 100644 --- a/app/routes/pharmacies.js +++ b/app/routes/pharmacies.js @@ -63,6 +63,15 @@ module.exports = router => { }) }) + router.get('/pharmacies/add-lead-admins',(req, res) => { + const data = req.session.data + const users = data.users.slice(10, 20) + + res.render('pharmacies/add-lead-admins', { + users + }) + }) + router.get('/pharmacies/users/:id',(req, res) => { const data = req.session.data const id = req.params.id diff --git a/app/views/pharmacies/add-lead-admins.html b/app/views/pharmacies/add-lead-admins.html new file mode 100644 index 00000000..269a35b0 --- /dev/null +++ b/app/views/pharmacies/add-lead-admins.html @@ -0,0 +1,60 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies" %} +{% set pageName = "Add lead administrators" %} + +{% block beforeContent %} + {{ backLink({ + href: "/pharmacies/check-selection" + }) }} +{% endblock %} + +{% block content %} +
+
+

{{ pageName }}

+ +

Who do you want to get be a lead administrator on RAVS for all {{ data.pharmacyIds | length }} pharmacies?

+ + {% set items = [] %} + + {% set items = (items.push({ + text: "Me (" + currentUser.firstName + " " + currentUser.lastName + ")", + value: user.id + }), items) %} + + {% for user in (users | sort(false, false, "firstName")) %} + {% set items = (items.push({ + text: user.firstName + " " + user.lastName, + value: user.id + }), items) %} + {% endfor %} + + {% set items = (items.push({ + divider: "or" + }), items) %} + + {% set items = (items.push({ + text: "No one, I’ll add lead administrators later", + value: "", + exclusive: true + }), items) %} + + {{ checkboxes({ + fieldset: { + legend: { + text: "Users", + size: "m" + } + }, + items: items + }) }} + + {{ button({ + text: "Continue" + }) }} + + +
+
+{% endblock %} diff --git a/app/views/pharmacies/check-selection.html b/app/views/pharmacies/check-selection.html index e1596c75..9d99d841 100644 --- a/app/views/pharmacies/check-selection.html +++ b/app/views/pharmacies/check-selection.html @@ -48,6 +48,7 @@

{{ pageName }}

{{ button({ + href: "/pharmacies/add-lead-admins", text: "Continue" }) }}
From 93e50b2632e332fa933ca7219ae8d502f2b1a710 Mon Sep 17 00:00:00 2001 From: Frankie Roberto Date: Fri, 24 Apr 2026 15:25:19 +0100 Subject: [PATCH 5/7] Some more progress --- app/views/home/index.html | 2 +- app/views/pharmacies/add-lead-admins.html | 153 ++++++++++++++++++++-- app/views/pharmacies/index.html | 14 +- app/views/pharmacies/pharmacy.html | 1 + app/views/pharmacies/select.html | 10 +- app/views/pharmacies/users/index.html | 4 - app/views/pharmacies/users/user.html | 13 +- 7 files changed, 167 insertions(+), 30 deletions(-) diff --git a/app/views/home/index.html b/app/views/home/index.html index 662883cd..a5a5e58f 100644 --- a/app/views/home/index.html +++ b/app/views/home/index.html @@ -13,7 +13,7 @@ {% include "includes/notification.html" %} -

{% if currentOrganisation %}{{ currentOrganisation.name }}{% else %}Peak pharmacies{% endif %}

+

{% if currentOrganisation %}{{ currentOrganisation.name }}{% else %}PCT Healthcare{% endif %}

{% if currentOrganisation and totalVaccinationsRecorded == 0 %} diff --git a/app/views/pharmacies/add-lead-admins.html b/app/views/pharmacies/add-lead-admins.html index 269a35b0..e555f8d6 100644 --- a/app/views/pharmacies/add-lead-admins.html +++ b/app/views/pharmacies/add-lead-admins.html @@ -14,13 +14,69 @@

{{ pageName }}

-

Who do you want to get be a lead administrator on RAVS for all {{ data.pharmacyIds | length }} pharmacies?

+
+ +

Who do you want to assign as lead administrators for all {{ data.pharmacyIds | length }} pharmacies?

+ + {% call details({ + summaryText: "What is a lead administrator?", + classes: "nhsuk-expander" + }) %} +

Lead administrators are responsible for setting up the pharmacy's users and vaccines.

+ +

They will get a Welcome email telling them how to log into RAVS. Once logged in at ABC pharmacy, they will be able to:

+ +
    +
  • add more users, with different permission levels
  • +
  • add vaccines
  • +
  • create reports
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Permission levelRecord and edit vaccinationsAdd and manage vaccinesCreate reportsAdd and manage users
Lead administratorYesYesYesYes
AdministratorYesYesYesNo
RecorderYesNoNoNo
+ {% endcall %} {% set items = [] %} {% set items = (items.push({ text: "Me (" + currentUser.firstName + " " + currentUser.lastName + ")", - value: user.id + value: user.id, + hint: { + text: "Do not add yourself if you do not need to record vaccinations at these pharmacies" + } }), items) %} {% for user in (users | sort(false, false, "firstName")) %} @@ -30,30 +86,101 @@

{{ pageName }}

}), items) %} {% endfor %} - {% set items = (items.push({ - divider: "or" - }), items) %} - - {% set items = (items.push({ - text: "No one, I’ll add lead administrators later", - value: "", - exclusive: true - }), items) %} - {{ checkboxes({ fieldset: { legend: { - text: "Users", + text: "Existing lead administrators", size: "m" } }, items: items }) }} +
+ {{ button({ + id: "add-lead-admin", + text: "Add a new lead administrator", + type: "button", + classes: "nhsuk-button--secondary", + attributes: { + "data-add-another-add": "true" + } + }) }} +
+ + + {{ button({ text: "Continue" }) }} +
+
diff --git a/app/views/pharmacies/index.html b/app/views/pharmacies/index.html index 1fe6d32d..ecf76961 100644 --- a/app/views/pharmacies/index.html +++ b/app/views/pharmacies/index.html @@ -8,15 +8,15 @@

Pharmacies

-

Add a new pharmacy or manage an existing pharmacy.

+

Add new pharmacies or manage an existing pharmacy.

{{ button({ - text: "Add pharmacy", + text: "Add pharmacies", href: "/pharmacies/select" }) }} - + - + @@ -39,14 +39,14 @@

Pharmacies

{{ organisation.name }} ({{ organisation.id}}) - {% endfor %} diff --git a/app/views/pharmacies/pharmacy.html b/app/views/pharmacies/pharmacy.html index 4769b4a0..23811652 100644 --- a/app/views/pharmacies/pharmacy.html +++ b/app/views/pharmacies/pharmacy.html @@ -82,6 +82,7 @@

Users

Current pharmaciesCurrent pharmacies ({{ organisations | length }})
@@ -28,7 +28,7 @@

Pharmacies

Users
- COVID-19 + COVID-19, flu 1 +
+

Deactivate this pharmacy

diff --git a/app/views/pharmacies/select.html b/app/views/pharmacies/select.html index 0ff4eb6d..11aa9abe 100644 --- a/app/views/pharmacies/select.html +++ b/app/views/pharmacies/select.html @@ -1,6 +1,7 @@ {% extends 'layout.html' %} {% set currentSection = "pharmacies" %} +{% set pageName = "Add pharmacies" %} {% block beforeContent %} {{ backLink({ @@ -13,6 +14,13 @@
+

{{ pageName }}

+ +

There are {{ (pharmacies | length) + 7 }} active pharmacies in your company according to the NHS Organisation Data Service (ODS).

+ +

{{ (pharmacies | length) }} of them are not yet using RAVS and can be added below.

+ + {% set items = [] %} {% for pharmacy in pharmacies %} @@ -26,7 +34,7 @@ {% call fieldset({ legend: { text: "Select pharmacies", - size: "l", + size: "m", classes: "nhsuk-u-margin-bottom-5" } }) %} diff --git a/app/views/pharmacies/users/index.html b/app/views/pharmacies/users/index.html index 0c530fb2..c7c66a3c 100644 --- a/app/views/pharmacies/users/index.html +++ b/app/views/pharmacies/users/index.html @@ -25,7 +25,6 @@

Users

Email - @@ -38,9 +37,6 @@

Users

{{ user.email }} - - Deactivate - {% endfor %} diff --git a/app/views/pharmacies/users/user.html b/app/views/pharmacies/users/user.html index 6c008800..50bfb9a3 100644 --- a/app/views/pharmacies/users/user.html +++ b/app/views/pharmacies/users/user.html @@ -35,11 +35,11 @@

{{ pageName }}

- + @@ -86,12 +86,17 @@

{{ pageName }}

Active
PharmaciesAccess and permission levels
- Name + Pharmacy Permission level @@ -69,7 +69,7 @@

{{ pageName }}

Active
- Remove + Deactivate
- Remove + Deactivate
+ {{ button({ + text: "Add to another pharmacy", + classes: "nhsuk-button--secondary" + }) }} +

Deactivate user from all pharmacies

From e4a8c67d65b2868541b35f04c0be197cf6e8842d Mon Sep 17 00:00:00 2001 From: Frankie Roberto Date: Fri, 24 Apr 2026 18:07:37 +0100 Subject: [PATCH 6/7] Update add another so that none are shown by default --- app/assets/javascript/add-another.js | 37 ++++++++++++++++++----- app/views/pharmacies/add-lead-admins.html | 24 +++++---------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/app/assets/javascript/add-another.js b/app/assets/javascript/add-another.js index cfb86296..23844906 100644 --- a/app/assets/javascript/add-another.js +++ b/app/assets/javascript/add-another.js @@ -14,6 +14,7 @@ import { Component } from 'nhsuk-frontend' * - Add `data-add-another-item="N"` to each item section (where N is the item index: 1, 2, 3, etc.) * - Add `data-add-another-add` to the "Add another" button (hidden by default) * - Add `data-add-another-remove="N"` to the "Remove" button within each section (hidden by default) + * - Optionally add `data-add-another-min="0"` to allow starting with no items visible (default is 1) * * @augments Component */ @@ -29,11 +30,13 @@ export class AddAnother extends Component { this.$items = Array.from(this.$root.querySelectorAll('[data-add-another-item]')) this.$addButton = this.$root.querySelector('[data-add-another-add]') this.$addButtonWrapper = this.$addButton?.closest('.nhsuk-button-group') + this.minItems = parseInt(this.$root.dataset.addAnotherMin ?? '1', 10) this.initializeItemVisibility() this.setupAddButton() this.setupRemoveButtons() this.updateAddButtonVisibility() + this.updateAddButtonText() this.updateRemoveButtonVisibility() } @@ -71,17 +74,18 @@ export class AddAnother extends Component { */ initializeItemVisibility() { // Find the last item with values - let lastFilledIndex = 0 + let lastFilledIndex = -1 this.$items.forEach(($item, index) => { if (this.hasInputValues($item)) { lastFilledIndex = index } }) - // Show items up to and including the last filled one (minimum 1) + // Show items up to and including the last filled one (respecting minItems) // Hide all items after that + const minVisibleIndex = this.minItems - 1 this.$items.forEach(($item, index) => { - if (index <= lastFilledIndex) { + if (index <= lastFilledIndex || index <= minVisibleIndex) { $item.hidden = false } else { $item.hidden = true @@ -152,6 +156,7 @@ export class AddAnother extends Component { } this.updateAddButtonVisibility() + this.updateAddButtonText() this.updateRemoveButtonVisibility() } @@ -163,8 +168,8 @@ export class AddAnother extends Component { removeItem(index) { const visibleItems = this.getVisibleItems() - // Don't remove if only one item is visible - if (visibleItems.length <= 1) { + // Don't remove if at minimum items + if (visibleItems.length <= this.minItems) { return } @@ -187,16 +192,34 @@ export class AddAnother extends Component { } this.updateAddButtonVisibility() + this.updateAddButtonText() this.updateRemoveButtonVisibility() } + /** + * Update the add button text based on number of visible items + * Uses data-add-another-text-first for the first item, + * data-add-another-text-another for subsequent items + */ + updateAddButtonText() { + if (!this.$addButton) return + + const firstText = this.$addButton.dataset.addAnotherTextFirst + const anotherText = this.$addButton.dataset.addAnotherTextAnother + + if (!firstText || !anotherText) return + + const visibleItems = this.getVisibleItems() + this.$addButton.textContent = visibleItems.length === 0 ? firstText : anotherText + } + /** * Update visibility of remove buttons based on number of visible items - * Remove buttons should only be visible when there are 2+ items + * Remove buttons should only be visible when there are more than minItems */ updateRemoveButtonVisibility() { const visibleItems = this.getVisibleItems() - const showRemoveButtons = visibleItems.length >= 2 + const showRemoveButtons = visibleItems.length > this.minItems this.$items.forEach($item => { const $removeButton = $item.querySelector('[data-add-another-remove]') diff --git a/app/views/pharmacies/add-lead-admins.html b/app/views/pharmacies/add-lead-admins.html index e555f8d6..c8e7da2c 100644 --- a/app/views/pharmacies/add-lead-admins.html +++ b/app/views/pharmacies/add-lead-admins.html @@ -14,7 +14,7 @@

{{ pageName }}

- +

Who do you want to assign as lead administrators for all {{ data.pharmacyIds | length }} pharmacies?

@@ -97,23 +97,13 @@

{{ pageName }}

}) }}
- {{ button({ - id: "add-lead-admin", - text: "Add a new lead administrator", - type: "button", - classes: "nhsuk-button--secondary", - attributes: { - "data-add-another-add": "true" - } - }) }} -
- +
{{ button({ From e08d33392a66fd0a0647d7f8885c596b6c70ec79 Mon Sep 17 00:00:00 2001 From: Frankie Roberto Date: Fri, 24 Apr 2026 18:15:07 +0100 Subject: [PATCH 7/7] Add a user to a pharmacy --- app/routes/pharmacies.js | 12 +++ app/views/pharmacies/add-users.html | 119 ++++++++++++++++++++++++++++ app/views/pharmacies/pharmacy.html | 3 +- 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 app/views/pharmacies/add-users.html diff --git a/app/routes/pharmacies.js b/app/routes/pharmacies.js index 408bb722..8e0ecfc6 100644 --- a/app/routes/pharmacies.js +++ b/app/routes/pharmacies.js @@ -83,6 +83,18 @@ module.exports = router => { }) + router.get('/pharmacies/:id/add-users',(req, res) => { + const data = req.session.data + const users = data.users.slice(10, 20) + const id = req.params.id + const organisation = data.organisations.find((organisation) => organisation.id === id) + + res.render('pharmacies/add-users', { + users, + organisation + }) + }) + router.get('/pharmacies/:id', (req, res) => { const data = req.session.data const id = req.params.id diff --git a/app/views/pharmacies/add-users.html b/app/views/pharmacies/add-users.html new file mode 100644 index 00000000..09ae6b96 --- /dev/null +++ b/app/views/pharmacies/add-users.html @@ -0,0 +1,119 @@ +{% extends 'layout.html' %} + +{% set currentSection = "pharmacies" %} +{% set pageName = "Add user to " + organisation.name %} + +{% block beforeContent %} + {{ backLink({ + href: "/pharmacies/" + organisation.id + }) }} +{% endblock %} + +{% block content %} +
+
+

{{ pageName }}

+ +

You can add an existing user to the pharmacy, or invite a new user.

+ + + + {% set items = [] %} + + {% for user in (users | sort(false, false, "firstName")) %} + {% set items = (items.push({ + text: user.firstName + " " + user.lastName, + value: user.id + }), items) %} + {% endfor %} + + {{ checkboxes({ + fieldset: { + legend: { + text: "Existing users", + size: "m" + } + }, + items: items + }) }} + +
+ + {# Ordinal suffixes for numbers 1-10 #} + + {% for index in range(0, 1) %} +
+

New user details

+ + + + {{ input({ + label: { + text: "First name" + }, + id: "first-name-" + (index + 1), + name: "firstName", + classes: "nhsuk-input--width-20", + value: data.firstName[index] + }) }} + + {{ input({ + label: { + text: "Last name" + }, + id: "last-name-" + (index + 1), + name: "lastName", + classes: "nhsuk-input--width-20", + value: data.lastName[index] + }) }} + + {{ input({ + label: { + text: "Email address" + }, + hint: { + html: "Use a personal nhs.net email, not a pharmacy email.
For example, joe.bloggs1@nhs.net" + }, + id: "email-" + (index + 1), + name: "email", + type: "email", + value: data.email[index] + }) }} +
+ {% endfor %} + + + + + {{ button({ + text: "Continue" + }) }} + + + + +
+
+{% endblock %} diff --git a/app/views/pharmacies/pharmacy.html b/app/views/pharmacies/pharmacy.html index 23811652..1610e168 100644 --- a/app/views/pharmacies/pharmacy.html +++ b/app/views/pharmacies/pharmacy.html @@ -40,7 +40,8 @@

{{ pageName }}

Users

{{ button({ - text: "Add user" + href: "/pharmacies/" + organisation.id + "/add-users", + text: "Add users" }) }}