diff --git a/app.js b/app.js index b7c6767..b8fb7d9 100755 --- a/app.js +++ b/app.js @@ -55,6 +55,7 @@ const appViews = [ path.join(__dirname, 'node_modules/nhsuk-frontend/packages/macros'), path.join(__dirname, 'docs/views/'), path.join(__dirname, 'lib/prototype-admin/'), + path.join(__dirname, 'app/components/'), ]; const nunjucksConfig = { diff --git a/app/assets/sass/main.scss b/app/assets/sass/main.scss index c9f996d..888d86a 100755 --- a/app/assets/sass/main.scss +++ b/app/assets/sass/main.scss @@ -28,6 +28,8 @@ $govuk-brand-colour: $nhsuk-link-color; @import 'components/table'; +@import '../../components/pagination/_pagination'; + .autocomplete__wrapper ul > li { margin-bottom: 0; } diff --git a/app/components/pagination/README.md b/app/components/pagination/README.md new file mode 100644 index 0000000..cddc2b4 --- /dev/null +++ b/app/components/pagination/README.md @@ -0,0 +1,5 @@ +# Pagination + +This is a work-in-progress modification of the Pagination component to support numbered pages. + +See https://github.com/nhsuk/nhsuk-frontend/pull/1026 diff --git a/app/components/pagination/_pagination.scss b/app/components/pagination/_pagination.scss new file mode 100644 index 0000000..5c1677e --- /dev/null +++ b/app/components/pagination/_pagination.scss @@ -0,0 +1,240 @@ +/* ========================================================================== + COMPONENTS / #PAGINATION + ========================================================================== */ + +/** + * 1. Padding to give the icon spacing. + * 2. Append the word 'page' after next and + * previous on print stylesheets to make it easier + * to understand in print context. + */ + +// Previous and next pages variant +.nhsuk-pagination { + @include nhsuk-responsive-margin(7, "top"); + @include nhsuk-responsive-margin(7, "bottom"); +} + +.nhsuk-pagination__list { + @include clearfix(); +} + +.nhsuk-pagination-item--previous { + float: left; + text-align: left; + width: 50%; + + .nhsuk-icon { + left: -6px; + } + + .nhsuk-pagination__title { + padding-left: nhsuk-spacing(5); /* [1] */ + } +} + +.nhsuk-pagination-item--next { + float: right; + text-align: right; + width: 50%; + + .nhsuk-icon { + right: -6px; + } + + .nhsuk-pagination__title { + padding-right: nhsuk-spacing(5); /* [1] */ + } +} + +.nhsuk-pagination__link { + display: block; + position: relative; + text-decoration: none; + width: 100%; + + @include mq($media-type: print) { + color: $color_nhsuk-black; + } + + .nhsuk-icon { + position: absolute; + top: -2px; + + @include mq($media-type: print) { + color: $color_nhsuk-black; + margin-top: 0; + } + } + + &:hover { + color: $nhsuk-link-hover-color; + + .nhsuk-icon { + fill: $nhsuk-link-hover-color; + } + + .nhsuk-pagination__page { + text-decoration: none; + } + } + + &:focus { + @include nhsuk-focused-text; + + .nhsuk-pagination__page { + text-decoration: none; + } + + &:visited, + &:hover, + &:active { + .nhsuk-icon { + fill: $nhsuk-focus-text-color; + } + } + } + + &:visited { + .nhsuk-icon { + fill: $nhsuk-link-visited-color; + } + + &:hover { + .nhsuk-icon { + fill: $nhsuk-link-hover-color; + } + } + + &:focus { + .nhsuk-icon { + fill: $nhsuk-focus-text-color; + } + } + } +} + +.nhsuk-pagination__title { + @include nhsuk-typography-responsive(24); + + display: block; + + @include mq($media-type: print) { + &:after { + content: " page"; /* [2] */ + } + } +} + +.nhsuk-pagination__page { + @include nhsuk-typography-responsive(16); + + display: block; + text-decoration: underline; +} + +// Numbered pages variant +.nhsuk-pagination--numbered { + @include clearfix(); +} + +// In a numbered list, the previous link, numbered page links, +// and next link should all line up +.nhsuk-pagination--numbered__prev, +.nhsuk-pagination--numbered__next, +.nhsuk-pagination--numbered__item { + @include nhsuk-font(19); + box-sizing: border-box; + position: relative; + min-width: 45px; + min-height: 45px; + padding: nhsuk-spacing(2) nhsuk-spacing(2); + text-align: center; + margin: 0; + float: left; +} + +.nhsuk-pagination--numbered__link:visited:hover, +.nhsuk-pagination--numbered__item a:hover { + color: $nhsuk-link-hover-color; +} + +.nhsuk-pagination--numbered__prev:hover, +.nhsuk-pagination--numbered__next:hover, +.nhsuk-pagination--numbered__item:hover { + background-color: $color_nhsuk-grey-4; + color: $color_nhsuk-blue; +} + +// Container for the list of numbered items +.nhsuk-pagination__list--numbered { + margin: 0; + padding: 0; + list-style: none; +} + +// Current number +.nhsuk-pagination--numbered__item--current, +.nhsuk-pagination--numbered__item--current:hover { + background-color: $color_nhsuk-blue; + font-weight: $nhsuk-font-bold; + + .nhsuk-pagination--numbered__link { + color: $color_nhsuk-white; + } + + .nhsuk-pagination--numbered__link:focus { + color: $color_nhsuk-black; + } +} + +.nhsuk-pagination--numbered__item--ellipses { + font-weight: $nhsuk-font-bold; + color: $nhsuk-secondary-text-color; + + &:hover { + background-color: transparent; + } +} + +.nhsuk-pagination--numbered__link { + min-width: nhsuk-spacing(3); + vertical-align: middle; + color: $color_nhsuk-blue; + + // Increase the touch area for the link to the parent element. + @media screen { + &::after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + } +} + +.nhsuk-pagination--numbered .nhsuk-icon { + margin-top: 0; + margin-bottom: -12px; + fill: $color_nhsuk-blue; +} + +.nhsuk-pagination--numbered__link:visited .nhsuk-icon { + fill: $nhsuk-link-visited-color; +} + +.nhsuk-pagination--numbered__link:hover .nhsuk-icon { + fill: $nhsuk-link-hover-color; +} + +.nhsuk-pagination--numbered .nhsuk-icon__arrow-left { + margin-left: -13px; + margin-right: nhsuk-spacing(2); +} + +.nhsuk-pagination--numbered .nhsuk-icon__arrow-right { + margin-left: nhsuk-spacing(2); + margin-right: -13px; +} diff --git a/app/components/pagination/macro.njk b/app/components/pagination/macro.njk new file mode 100644 index 0000000..168fb80 --- /dev/null +++ b/app/components/pagination/macro.njk @@ -0,0 +1,3 @@ +{% macro appPagination(params) %} + {%- include './template.njk' -%} +{% endmacro %} diff --git a/app/components/pagination/template.njk b/app/components/pagination/template.njk new file mode 100644 index 0000000..dc4699b --- /dev/null +++ b/app/components/pagination/template.njk @@ -0,0 +1,106 @@ +{% from "../../../node_modules/nhsuk-frontend/packages/macros/attributes.njk" import nhsukAttributes %} + +{# There are 2 variants of this component, one for content pages which +has only previous and next links including the titles of those pages, +and one for navigating between pages of items, like search results. + +The numbered variable sets which variant is being used, based on the +presence of items (pages). #} +{% set numbered = true if params.items %} + +{# Arrow pointing left - used by both variants #} +{%- macro _arrowPrevious() -%} + +{%- endmacro -%} + +{# Arrow pointing right - used by both variants #} +{%- macro _arrowNext() -%} + +{%- endmacro -%} + +{# Numbered page - included as a link within a list item. #} +{%- macro _pageItem(item) -%} +
  • + {% if item.ellipsis %} + ⋯ + {% else %} + + {{ item.number }} + + {% endif %} +
  • +{%- endmacro -%} + +{# Link for the previous or next or next page, displayed at either end of +the numbered variant only, and including an arrow pointing left or right. #} +{%- macro _arrowLink(link, type = "next") %} + {% set arrowType = arrowPrevious if type == "prev" else arrowNext %} +
    + + {%- if type == "prev" -%} + {{ _arrowPrevious() }} + {%- endif -%} + {{ caller() | safe }} + {%- if type == "next" -%} + {{ _arrowNext() }} + {%- endif -%} + +
    +{% endmacro -%} + + diff --git a/app/data/session-data-defaults.js b/app/data/session-data-defaults.js index 0b11e1b..82a61bd 100644 --- a/app/data/session-data-defaults.js +++ b/app/data/session-data-defaults.js @@ -46,13 +46,208 @@ module.exports = { }, { id: "263474", - batchNumber: "92/6334", + batchNumber: "634/6334", expiryDate: "2024-11-13" }, { id: "1367231", - batchNumber: "9282/4457", + batchNumber: "745/733", expiryDate: "2023-10-13" + }, + { + id: "25325", + batchNumber: "6634/336", + expiryDate: "2024-12-13" + }, + { + id: "1253252", + batchNumber: "13/6334", + expiryDate: "2024-11-13" + }, + { + id: "563463", + batchNumber: "34/324", + expiryDate: "2023-10-13" + }, + { + id: "127845", + batchNumber: "664/336", + expiryDate: "2024-12-23" + }, + { + id: "4025811", + batchNumber: "3525/6334", + expiryDate: "2023-11-13" + }, + { + id: "536325", + batchNumber: "535/242", + expiryDate: "2023-10-13" + }, + { + id: "141424", + batchNumber: "6443/336", + expiryDate: "2024-12-21" + }, + { + id: "64634", + batchNumber: "5233/6334", + expiryDate: "2024-10-21" + }, + { + id: "14235", + batchNumber: "252/134", + expiryDate: "2023-10-23" + }, + { + id: "25325", + batchNumber: "5235/336", + expiryDate: "2024-12-03" + }, + { + id: "73636", + batchNumber: "234/6334", + expiryDate: "2024-12-01" + }, + { + id: "85563", + batchNumber: "2535/7343", + expiryDate: "2024-12-19" + }, + { + id: "935346", + batchNumber: "525/336", + expiryDate: "2025-11-12" + }, + { + id: "527722", + batchNumber: "858/6334", + expiryDate: "2025-05-12" + }, + { + id: "633373", + batchNumber: "1424/131", + expiryDate: "2024-11-12" + }, + { + id: "4623442", + batchNumber: "424/336", + expiryDate: "2024-10-11" + }, + { + id: "745244", + batchNumber: "5235/6334", + expiryDate: "2024-11-27" + }, + { + id: "73343", + batchNumber: "2525/4457", + expiryDate: "2023-10-12" + }, + { + id: "1562", + batchNumber: "745/133", + expiryDate: "2023-10-29" + }, + { + id: "1322", + batchNumber: "6634/7455", + expiryDate: "2024-12-28" + }, + { + id: "62345", + batchNumber: "13/6234", + expiryDate: "2024-11-26" + }, + { + id: "25523", + batchNumber: "34/623", + expiryDate: "2023-10-25" + }, + { + id: "64343", + batchNumber: "664/624", + expiryDate: "2024-12-24" + }, + { + id: "35325", + batchNumber: "3525/413", + expiryDate: "2023-11-22" + }, + { + id: "73434", + batchNumber: "535/2462", + expiryDate: "2023-10-21" + }, + { + id: "53252", + batchNumber: "6443/562", + expiryDate: "2024-12-19" + }, + { + id: "74543", + batchNumber: "5233/5233", + expiryDate: "2024-10-18" + }, + { + id: "2486235", + batchNumber: "252/7434", + expiryDate: "2023-10-16" + }, + { + id: "5235", + batchNumber: "5235/743", + expiryDate: "2024-12-14" + }, + { + id: "523", + batchNumber: "234/244", + expiryDate: "2024-12-12" + }, + { + id: "52335", + batchNumber: "2535/8273", + expiryDate: "2024-12-11" + }, + { + id: "6323", + batchNumber: "525/623", + expiryDate: "2025-11-10" + }, + { + id: "27223", + batchNumber: "858/6233", + expiryDate: "2025-05-09" + }, + { + id: "52352", + batchNumber: "1424/3723", + expiryDate: "2024-11-06" + }, + { + id: "25373", + batchNumber: "424/344", + expiryDate: "2024-10-05" + }, + { + id: "5525235", + batchNumber: "5235/272", + expiryDate: "2024-11-02" + }, + { + id: "6747", + batchNumber: "2525/6346", + expiryDate: "2023-10-14" + }, + { + id: "25235", + batchNumber: "233/255", + expiryDate: "2024-10-02" + }, + { + id: "636346", + batchNumber: "16364/523", + expiryDate: "2025-02-04" } ] }, @@ -174,6 +369,654 @@ module.exports = { status: "Deactivated", deactivatedDate: "2024-03-09", clinician: "no" + }, + { + id: "248691", + email: "lilyana.marshall@nhs.net", + firstName: "Lilyana", + lastName: "Marshall", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "987459", + email: "rhys.mckenzie@nhs.net", + firstName: "Rhys", + lastName: "Mckenzie", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7466454", + email: "joaquin.leblanc@nhs.net", + firstName: "Joaquin", + lastName: "Leblanc", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3363733", + email: "gisselle.stevens@nhs.net", + firstName: "Gisselle", + lastName: "Stevens", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5640871", + email: "kane.mcdaniel@nhs.net", + firstName: "Kane", + lastName: "Mcdaniel", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7076398", + email: "samuel.bray@nhs.net", + firstName: "Samuel", + lastName: "Bray", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "1006456", + email: "thomas.lucero@nhs.net", + firstName: "Thomas", + lastName: "Lucero", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "9335579", + email: "jaden.dennis@nhs.net", + firstName: "Jaden", + lastName: "Dennis", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2510011", + email: "tiana.peck@nhs.net", + firstName: "Tiana", + lastName: "Peck", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3039766", + email: "lorena.fox@nhs.net", + firstName: "Lorena", + lastName: "Fox", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5407821", + email: "conner.osborn@nhs.net", + firstName: "Conner", + lastName: "Osborn", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5941527", + email: "selena.warner@nhs.net", + firstName: "Selena", + lastName: "Warner", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "970879", + email: "aurora.huffman@nhs.net", + firstName: "Aurora", + lastName: "Huffman", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3232663", + email: "deandre.perkins@nhs.net", + firstName: "Deandre", + lastName: "Perkins", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "6665157", + email: "lily.holt@nhs.net", + firstName: "Lily", + lastName: "Holt", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2039091", + email: "angel.alvarado@nhs.net", + firstName: "Angel", + lastName: "Alvarado", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "657695", + email: "crystal.vega@nhs.net", + firstName: "Crystal", + lastName: "Vega", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "8320483", + email: "amiah.alvarado@nhs.net", + firstName: "Amiah", + lastName: "Alvarado", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "6570849", + email: "carlo.norman@nhs.net", + firstName: "Carlo", + lastName: "Norman", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "303510", + email: "jaelynn.chase@nhs.net", + firstName: "Jaelynn", + lastName: "Chase", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7023266", + email: "heaven.mathews@nhs.net", + firstName: "Heaven", + lastName: "Mathews", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2374045", + email: "coleman.matthews@nhs.net", + firstName: "Coleman", + lastName: "Matthews", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "585216", + email: "june.stout@nhs.net", + firstName: "June", + lastName: "Stout", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7124279", + email: "hayley.lee..@nhs.net", + firstName: "Hayley", + lastName: "Lee", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2984740", + email: "stephanie.meyer@nhs.net", + firstName: "Stephanie", + lastName: "Meyer", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2437147", + email: "cynthia.hart@nhs.net", + firstName: "Cynthia", + lastName: "Hart", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "869248", + email: "liliana.jacobson@nhs.net", + firstName: "Liliana", + lastName: "Jacobson", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3158509", + email: "pierce.barr@nhs.net", + firstName: "Pierce", + lastName: "Barr", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7550048", + email: "collin.ewing@nhs.net", + firstName: "Collin", + lastName: "Ewing", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "6205997", + email: "esperanza.lyons@nhs.net", + firstName: "Esperanza", + lastName: "Lyons", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3646893", + email: "giovanni.tanner@nhs.net", + firstName: "Giovanni", + lastName: "Tanner", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5589302", + email: "britney.joyce@nhs.net", + firstName: "Britney", + lastName: "Joyce", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "8404035", + email: "juliana.mathews@nhs.net", + firstName: "Juliana", + lastName: "Mathews", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7814712", + email: "koen.stafford@nhs.net", + firstName: "Koen", + lastName: "Stafford", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5066929", + email: "myles.mcguire@nhs.net", + firstName: "Myles", + lastName: "Mcguire", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2063882", + email: "evie.elliott@nhs.net", + firstName: "Evie", + lastName: "Elliott", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "752342", + email: "zara.pitts@nhs.net", + firstName: "Zara", + lastName: "Pitts", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "824220", + email: "daniel.lamb@nhs.net", + firstName: "Daniel", + lastName: "Lamb", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3057334", + email: "mohammed.burns@nhs.net", + firstName: "Mohammed", + lastName: "Burns", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2844017", + email: "kaylynn.rose@nhs.net", + firstName: "Kaylynn", + lastName: "Rose", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "6261906", + email: "tony.davenport@nhs.net", + firstName: "Tony", + lastName: "Davenport", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "1240005", + email: "darian.mcdonald@nhs.net", + firstName: "Darian", + lastName: "Mcdonald", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3495796", + email: "ryder.nicholson@nhs.net", + firstName: "Ryder", + lastName: "Nicholson", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "9430941", + email: "joyce.glover@nhs.net", + firstName: "Joyce", + lastName: "Glover", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3994171", + email: "uriel.rodgers@nhs.net", + firstName: "Uriel", + lastName: "Rodgers", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "4710304", + email: "liam.thornton@nhs.net", + firstName: "Liam", + lastName: "Thornton", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2699606", + email: "amber.roth@nhs.net", + firstName: "Amber", + lastName: "Roth", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5521116", + email: "harry.garrison@nhs.net", + firstName: "Harry", + lastName: "Garrison", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5903436", + email: "king.yates@nhs.net", + firstName: "King", + lastName: "Yates", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2916343", + email: "clayton.warner@nhs.net", + firstName: "Clayton", + lastName: "Warner", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7737858", + email: "carley.ward@nhs.net", + firstName: "Carley", + lastName: "Ward", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "9166645", + email: "kristen.riley@nhs.net", + firstName: "Kristen", + lastName: "Riley", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "4566130", + email: "dominique.potts@nhs.net", + firstName: "Dominique", + lastName: "Potts", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "4427753", + email: "marisol.hatfield@nhs.net", + firstName: "Marisol", + lastName: "Hatfield", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "4758706", + email: "lesly.nolan@nhs.net", + firstName: "Lesly", + lastName: "Nolan", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "6055459", + email: "ricardo.knight@nhs.net", + firstName: "Ricardo", + lastName: "Knight", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "881056", + email: "alissa.wells@nhs.net", + firstName: "Alissa", + lastName: "Wells", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "1310503", + email: "mara.bryan@nhs.net", + firstName: "Mara", + lastName: "Bryan", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "9890694", + email: "jayleen.robertson@nhs.net", + firstName: "Jayleen", + lastName: "Robertson", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3048215", + email: "aron.delgado@nhs.net", + firstName: "Aron", + lastName: "Delgado", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2029291", + email: "abbigail.kirby@nhs.net", + firstName: "Abbigail", + lastName: "Kirby", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "5657137", + email: "estrella.villa@nhs.net", + firstName: "Estrella", + lastName: "Villa", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "7199138", + email: "aaden.shah@nhs.net", + firstName: "Aaden", + lastName: "Shah", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "1237996", + email: "gaven.davenport@nhs.net", + firstName: "Gaven", + lastName: "Davenport", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2087409", + email: "santos.goodman@nhs.net", + firstName: "Santos", + lastName: "Goodman", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "1069469", + email: "jeffery.page@nhs.net", + firstName: "Jeffery", + lastName: "Page", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "6692769", + email: "nola.watkins@nhs.net", + firstName: "Nola", + lastName: "Watkins", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "2792521", + email: "luciano.lucero@nhs.net", + firstName: "Luciano", + lastName: "Lucero", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "9560869", + email: "payton.howard@nhs.net", + firstName: "Payton", + lastName: "Howard", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "820103", + email: "hayden.horn@nhs.net", + firstName: "Hayden", + lastName: "Horn", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "3490354", + email: "toby.scott@nhs.net", + firstName: "Toby", + lastName: "Scott", + role: "Recorder", + status: "Active", + clinician: "no" + }, + { + id: "8256717", + email: "olive.ferrell@nhs.net", + firstName: "Olive", + lastName: "Ferrell", + role: "Recorder", + status: "Active", + clinician: "no" } ], organisationsAdded: [ diff --git a/app/routes/user-admin.js b/app/routes/user-admin.js index ddb5d7c..d61aa33 100644 --- a/app/routes/user-admin.js +++ b/app/routes/user-admin.js @@ -2,13 +2,40 @@ module.exports = (router) => { router.get('/user-admin', (req, res) => { + const perPage = 20; // Max number of users to show per page + const page = parseInt(req.query.page) || 1 ; // Current page, default to 1 + const data = req.session.data; const statusesToInclude = ['Invited', 'Active']; - const users = data.users.filter((user) => statusesToInclude.includes(user.status)) + const allUsers = data.users + .filter((user) => statusesToInclude.includes(user.status)) + .sort((a, b) => { + const nameA = a.firstName.toUpperCase(); // ignore upper and lowercase + const nameB = b.firstName.toUpperCase(); // ignore upper and lowercase + if (nameA < nameB) { + return -1; + } + if (nameA > nameB) { + return 1; + } + return 0; + }) + + + const totalUsers = allUsers.length + + const indexStartFrom = (page - 1) * perPage + + const users = allUsers.slice(indexStartFrom, indexStartFrom + perPage) + const totalPages = Math.ceil(totalUsers / perPage) + const deactivatedUsers = data.users.filter((user) => user.status === 'Deactivated') res.render('user-admin/index',{ + totalUsers, + totalPages, + page, users, deactivatedUsers }) diff --git a/app/routes/vaccines.js b/app/routes/vaccines.js index 12a3ebf..05a3f56 100644 --- a/app/routes/vaccines.js +++ b/app/routes/vaccines.js @@ -88,16 +88,42 @@ module.exports = (router) => { // Viewing a vaccine product at a site router.get('/vaccines/:id', (req, res) => { const data = req.session.data + const perPage = 20; // Max number of users to show per page + const page = parseInt(req.query.page) || 1 ; // Current page, default to 1 + const vaccine = data.vaccines.find((vaccine) => vaccine.id === req.params.id) if (!vaccine) { res.redirect('/vaccines'); return } const site = data.sites[vaccine.siteCode] const today = new Date().toISOString().substring(0,10) + const allBatches = vaccine.batches.sort((a, b) => { + const expiryA = a.expiryDate + const expiryB = b.expiryDate + if (expiryA > expiryB) { + return -1; + } + if (expiryA < expiryB) { + return 1; + } + return 0; + }) + + const totalBatches = allBatches.length + const indexStartFrom = (page - 1) * perPage + const totalPages = Math.ceil(totalBatches / perPage) + + const batches = allBatches.slice(indexStartFrom, indexStartFrom + perPage) + + res.render('vaccines/product-page', { vaccine, + batches, site, - today + today, + totalPages, + totalBatches, + page }) }) diff --git a/app/views/user-admin/index.html b/app/views/user-admin/index.html index 6c11cf5..2cf0e34 100644 --- a/app/views/user-admin/index.html +++ b/app/views/user-admin/index.html @@ -4,6 +4,9 @@ Manage users and permissions {% endblock %} +{% from '../../components/pagination/macro.njk' import appPagination %} + + {% set currentSection = "manage-users" %} {% block content %} @@ -17,7 +20,7 @@

    Manage users

    }) }} - +
    UsersUsers
    @@ -58,6 +61,26 @@

    Manage users

    + {% set items = [] %} + + {% for i in range(1, totalPages + 1) -%} + {% set items = (items.push({ + number: i, + href: "/user-admin?page=" + i, + current: (i === page) + }), items) %} + {%- endfor %} + + + {% if totalPages > 0 %} + {{ appPagination({ + previousUrl: "/user-admin?page=" + (page - 1) if page != 1, + nextUrl: "/user-admin?page=" + (page + 1) if page != totalPages, + items: items + }) }} + {% endif %} + + {% if deactivatedUsers | length > 0 %}

    View {{ deactivatedUsers | length | plural ("deactivated user") }}

    {% endif %} diff --git a/app/views/vaccines/product-page.html b/app/views/vaccines/product-page.html index 3a8ebcd..567243f 100644 --- a/app/views/vaccines/product-page.html +++ b/app/views/vaccines/product-page.html @@ -6,6 +6,9 @@ {% set currentSection = "vaccines" %} +{% from '../../components/pagination/macro.njk' import appPagination %} + + {% block beforeContent %} {{ backLink({ href: "/vaccines/", @@ -85,7 +88,7 @@

    {{ vaccine.vaccineProduct }}

    - {% for batch in vaccine.batches %} + {% for batch in batches %} {{ batch.batchNumber }} @@ -123,6 +126,25 @@

    {{ vaccine.vaccineProduct }}

    + {% set items = [] %} + + {% for i in range(1, totalPages + 1) -%} + {% set items = (items.push({ + number: i, + href: "/vaccines/" + vaccine.id + "?page=" + i, + current: (i === page) + }), items) %} + {%- endfor %} + + + {% if totalPages > 0 %} + {{ appPagination({ + previousUrl: "/vaccines/" + vaccine.id + "?page=" + (page - 1) if page != 1, + nextUrl: "/vaccines/" + vaccine.id + "?page=" + (page + 1) if page != totalPages, + items: items + }) }} + {% endif %} + {% endblock %} diff --git a/gulpfile.js b/gulpfile.js index edee77c..d4fb860 100755 --- a/gulpfile.js +++ b/gulpfile.js @@ -24,7 +24,7 @@ sass.compiler = require('sass'); // Compile SASS to CSS function compileStyles() { return gulp - .src(['app/assets/sass/**/*.scss', 'docs/assets/sass/**/*.scss']) + .src(['app/assets/sass/**/*.scss', 'docs/assets/sass/**/*.scss', 'app/components/**/*.scss']) .pipe(sass()) .pipe(gulp.dest('public/css')) .on('error', (err) => { @@ -92,7 +92,7 @@ function startBrowserSync(done) { proxy: 'localhost:' + port, port: port + 1000, ui: false, - files: ['app/views/**/*.*', 'docs/views/**/*.*'], + files: ['app/views/**/*.*', 'docs/views/**/*.*', 'app/components/**/*.*'], ghostMode: false, open: false, notify: true,