From e0cdb9398a07f08bdca1658bb7a781b215677cf2 Mon Sep 17 00:00:00 2001 From: John Livingstone Date: Thu, 23 Jan 2025 11:54:31 +0000 Subject: [PATCH 01/16] Created UI and sytling for users.ejs --- views/users.ejs | 64 +++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/views/users.ejs b/views/users.ejs index f323c63..5538bba 100644 --- a/views/users.ejs +++ b/views/users.ejs @@ -5,42 +5,44 @@ User List - + -

User List

+
+

User List

- <% if (users && users.length > 0) { %> - - - - - - - - - - - - - <% users.forEach(user => { %> + <% if (users && users.length > 0) { %> +
NameEmailRole
+ - - - - - - + + + + - <% }); %> - -
<%= user.name %><%= user.email %><%= user.role %>ViewEditDeleteNameEmailRoleActions
- <% } else { %> -

No users found.

- <% } %> + + + <% users.forEach(user => { %> + + <%= user.name %> + <%= user.email %> + <%= user.role %> + + View + Edit + Delete + + + <% }); %> + + + <% } else { %> +

No users found.

+ <% } %> -
- -
+
+ +
+
From 19956f54e9fe137a198ad9ec6eb23ebaa050b7ba Mon Sep 17 00:00:00 2001 From: Noblenog Date: Thu, 23 Jan 2025 13:11:35 +0000 Subject: [PATCH 02/16] user list button added from index, addition of content to the user.json, and GET request added --- package-lock.json | 501 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- routes/index.js | 6 + users.json | 35 +++- views/index.ejs | 6 +- 5 files changed, 546 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index db4e50a..8d36f05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "express": "^4.18.2", "fs": "^0.0.1-security", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "morgan": "~1.9.1", + "nodemon": "^3.1.9" } }, "node_modules/accepts": { @@ -44,6 +45,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -70,6 +84,18 @@ "node": ">= 0.8" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -154,6 +180,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -190,6 +228,30 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -510,6 +572,18 @@ "node": ">=10" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -567,6 +641,20 @@ "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -589,6 +677,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -677,6 +777,12 @@ "node": ">=0.10.0" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "license": "ISC" + }, "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -690,6 +796,48 @@ "node": ">= 0.10" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/jake": { "version": "10.8.7", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", @@ -797,6 +945,87 @@ "node": ">= 0.6" } }, + "node_modules/nodemon": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -837,6 +1066,18 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -849,6 +1090,12 @@ "node": ">= 0.10" } }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "license": "MIT" + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -926,6 +1173,18 @@ "node": ">= 0.8" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -936,6 +1195,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1063,6 +1334,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -1082,6 +1365,18 @@ "node": ">=8" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1090,6 +1385,15 @@ "node": ">=0.6" } }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1102,6 +1406,12 @@ "node": ">= 0.6" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "license": "MIT" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1145,6 +1455,15 @@ "color-convert": "^2.0.1" } }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -1168,6 +1487,11 @@ "safe-buffer": "5.1.2" } }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" + }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -1238,6 +1562,14 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "requires": { + "fill-range": "^7.1.1" + } + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1262,6 +1594,21 @@ "supports-color": "^7.1.0" } }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1496,6 +1843,14 @@ } } }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -1540,6 +1895,12 @@ "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "optional": true + }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1556,6 +1917,14 @@ "hasown": "^2.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -1614,6 +1983,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -1624,6 +1998,32 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, "jake": { "version": "10.8.7", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", @@ -1698,6 +2098,56 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "nodemon": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", + "requires": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "requires": { + "ms": "^2.1.3" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, "object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1726,6 +2176,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1735,6 +2190,11 @@ "ipaddr.js": "1.9.1" } }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, "qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1793,6 +2253,14 @@ } } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1803,6 +2271,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1908,6 +2381,14 @@ "object-inspect": "^1.9.0" } }, + "simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "requires": { + "semver": "^7.5.3" + } + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -1921,11 +2402,24 @@ "has-flag": "^4.0.0" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1935,6 +2429,11 @@ "mime-types": "~2.1.24" } }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index ad2820c..ad3f765 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "express": "^4.18.2", "fs": "^0.0.1-security", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "morgan": "~1.9.1", + "nodemon": "^3.1.9" } } diff --git a/routes/index.js b/routes/index.js index ecca96a..6125c62 100644 --- a/routes/index.js +++ b/routes/index.js @@ -6,4 +6,10 @@ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); + +router.get('users', (req, res) => { + res.render('users', { users }); +}); +; + module.exports = router; diff --git a/users.json b/users.json index c3b48ae..cec7e65 100644 --- a/users.json +++ b/users.json @@ -3,6 +3,39 @@ "id": 1, "name": "Shaun", "email": "shaun@test.com", - "role": "Software Engineer" + "role": "Software Engineer", + "address": "1234 Main St" + } + + ,{ + "id": 2, + "name": "Noble", + "email": "Noble@test.com", + "role": "Super Senior Software Engineer", + "address": "256 Main St" + } + + ,{ + "id": 3, + "name": "Abbey", + "email": "abbey@test.com", + "role": "Software Engineer", + "address": "742 Main St" + } + + ,{ + "id": 3, + "name": "John", + "email": "john@test.com", + "role": "Software Engineer", + "address": "111 Main St" + } + + ,{ + "id": 4, + "name": "Jennifer", + "email": "Abbey@test.com", + "role": "Software Engineer", + "address": "0 Main St" } ] \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index 7b7a1d6..4a7241c 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -5,7 +5,9 @@ -

<%= title %>

-

Welcome to <%= title %>

+
+

Welcome to the Home Page

+

View User List

+
From b2e2a9d36858f618d841cbd49880cf825f718594 Mon Sep 17 00:00:00 2001 From: Noblenog Date: Thu, 23 Jan 2025 13:21:20 +0000 Subject: [PATCH 03/16] added return button for the users page to redirect back to the home page --- views/users.ejs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/views/users.ejs b/views/users.ejs index 5538bba..08221c1 100644 --- a/views/users.ejs +++ b/views/users.ejs @@ -43,6 +43,8 @@
+ + Return to Home From 9fd214b95ead00c7d048fcc26db5cbf2c0c18dff Mon Sep 17 00:00:00 2001 From: Noblenog Date: Thu, 23 Jan 2025 13:46:05 +0000 Subject: [PATCH 04/16] fleshed out JSON data, added salary, and employee number --- users.json | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/users.json b/users.json index cec7e65..6c3b502 100644 --- a/users.json +++ b/users.json @@ -4,38 +4,39 @@ "name": "Shaun", "email": "shaun@test.com", "role": "Software Engineer", - "address": "1234 Main St" - } - - ,{ + "address": "1234 Main St", + "salary": "£50,000" + }, + { "id": 2, "name": "Noble", "email": "Noble@test.com", "role": "Super Senior Software Engineer", - "address": "256 Main St" - } - - ,{ + "address": "256 Main St", + "salary": "£80,000" + }, + { "id": 3, "name": "Abbey", "email": "abbey@test.com", "role": "Software Engineer", - "address": "742 Main St" - } - - ,{ + "address": "742 Main St", + "salary": "£55,000" + }, + { "id": 3, "name": "John", "email": "john@test.com", "role": "Software Engineer", - "address": "111 Main St" - } - - ,{ + "address": "111 Main St", + "salary": "£60,000" + }, + { "id": 4, "name": "Jennifer", "email": "Abbey@test.com", "role": "Software Engineer", - "address": "0 Main St" + "address": "0 Main St", + "salary": "£58,000" } ] \ No newline at end of file From 62b1fd61eb12eb52d4328297173f3a6cdb55fc53 Mon Sep 17 00:00:00 2001 From: Noblenog Date: Thu, 23 Jan 2025 13:54:23 +0000 Subject: [PATCH 05/16] updated json entries --- users.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/users.json b/users.json index 6c3b502..d7d44fb 100644 --- a/users.json +++ b/users.json @@ -1,6 +1,7 @@ [ { "id": 1, + "employee number": "12345678", "name": "Shaun", "email": "shaun@test.com", "role": "Software Engineer", @@ -9,6 +10,7 @@ }, { "id": 2, + "employee number": "23456789", "name": "Noble", "email": "Noble@test.com", "role": "Super Senior Software Engineer", @@ -17,6 +19,7 @@ }, { "id": 3, + "employee number": "34567890", "name": "Abbey", "email": "abbey@test.com", "role": "Software Engineer", @@ -25,6 +28,7 @@ }, { "id": 3, + "employee number": "45678901", "name": "John", "email": "john@test.com", "role": "Software Engineer", @@ -33,6 +37,7 @@ }, { "id": 4, + "employee number": "56789012", "name": "Jennifer", "email": "Abbey@test.com", "role": "Software Engineer", From 02a4e8a9f89b80c4c9cf0eefc4f6cda67028189c Mon Sep 17 00:00:00 2001 From: Jennifer Date: Thu, 23 Jan 2025 14:18:56 +0000 Subject: [PATCH 06/16] index and user --- package-lock.json | 501 +++++++++++++++++- package.json | 3 +- .../Kainos 800x250 Logo (Transparent BG).png | Bin 0 -> 21738 bytes public/images/Kainos-alt-transparent.png | Bin 0 -> 20061 bytes public/images/favicon.png | Bin 0 -> 11102 bytes public/stylesheets/style.css | 38 ++ views/addUser.ejs | 8 + views/deleteUser.ejs | 2 + views/error.ejs | 1 + views/index.ejs | 21 +- views/updateUser.ejs | 2 + views/user.ejs | 7 +- views/users.ejs | 9 + 13 files changed, 586 insertions(+), 6 deletions(-) create mode 100644 public/images/Kainos 800x250 Logo (Transparent BG).png create mode 100644 public/images/Kainos-alt-transparent.png create mode 100644 public/images/favicon.png diff --git a/package-lock.json b/package-lock.json index db4e50a..8d36f05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "express": "^4.18.2", "fs": "^0.0.1-security", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "morgan": "~1.9.1", + "nodemon": "^3.1.9" } }, "node_modules/accepts": { @@ -44,6 +45,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -70,6 +84,18 @@ "node": ">= 0.8" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -154,6 +180,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -190,6 +228,30 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -510,6 +572,18 @@ "node": ">=10" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -567,6 +641,20 @@ "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -589,6 +677,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -677,6 +777,12 @@ "node": ">=0.10.0" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "license": "ISC" + }, "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -690,6 +796,48 @@ "node": ">= 0.10" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/jake": { "version": "10.8.7", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", @@ -797,6 +945,87 @@ "node": ">= 0.6" } }, + "node_modules/nodemon": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -837,6 +1066,18 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -849,6 +1090,12 @@ "node": ">= 0.10" } }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "license": "MIT" + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -926,6 +1173,18 @@ "node": ">= 0.8" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -936,6 +1195,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1063,6 +1334,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -1082,6 +1365,18 @@ "node": ">=8" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1090,6 +1385,15 @@ "node": ">=0.6" } }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1102,6 +1406,12 @@ "node": ">= 0.6" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "license": "MIT" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1145,6 +1455,15 @@ "color-convert": "^2.0.1" } }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -1168,6 +1487,11 @@ "safe-buffer": "5.1.2" } }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" + }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -1238,6 +1562,14 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "requires": { + "fill-range": "^7.1.1" + } + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1262,6 +1594,21 @@ "supports-color": "^7.1.0" } }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1496,6 +1843,14 @@ } } }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -1540,6 +1895,12 @@ "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "optional": true + }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1556,6 +1917,14 @@ "hasown": "^2.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -1614,6 +1983,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -1624,6 +1998,32 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, "jake": { "version": "10.8.7", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", @@ -1698,6 +2098,56 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "nodemon": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", + "requires": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "requires": { + "ms": "^2.1.3" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, "object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1726,6 +2176,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1735,6 +2190,11 @@ "ipaddr.js": "1.9.1" } }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, "qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1793,6 +2253,14 @@ } } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1803,6 +2271,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1908,6 +2381,14 @@ "object-inspect": "^1.9.0" } }, + "simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "requires": { + "semver": "^7.5.3" + } + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -1921,11 +2402,24 @@ "has-flag": "^4.0.0" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1935,6 +2429,11 @@ "mime-types": "~2.1.24" } }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index ad2820c..ad3f765 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "express": "^4.18.2", "fs": "^0.0.1-security", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "morgan": "~1.9.1", + "nodemon": "^3.1.9" } } diff --git a/public/images/Kainos 800x250 Logo (Transparent BG).png b/public/images/Kainos 800x250 Logo (Transparent BG).png new file mode 100644 index 0000000000000000000000000000000000000000..0dff4eb9a5a73f88a8f7acbfee8120a8617a63be GIT binary patch literal 21738 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 k5 Add New User + +
+ +

Add New User

@@ -22,5 +28,7 @@
+ +

Kainos 4-6 Upper Cres, Belfast BT7 1NT

diff --git a/views/deleteUser.ejs b/views/deleteUser.ejs index 4da5af6..1bed31a 100644 --- a/views/deleteUser.ejs +++ b/views/deleteUser.ejs @@ -5,6 +5,7 @@ Delete User + @@ -17,5 +18,6 @@ +

Kainos 4-6 Upper Cres, Belfast BT7 1NT

diff --git a/views/error.ejs b/views/error.ejs index 7cf94ed..21f6d06 100644 --- a/views/error.ejs +++ b/views/error.ejs @@ -1,3 +1,4 @@

<%= message %>

<%= error.status %>

<%= error.stack %>
+

Kainos 4-6 Upper Cres, Belfast BT7 1NT

\ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index 7b7a1d6..34dffd6 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,11 +1,26 @@ + + + + <%= title %> + + - -

<%= title %>

-

Welcome to <%= title %>

+ + +
+ + +

<%= title %>

+

Welcome to <%= title %>

+ + +

Kainos 4-6 Upper Cres, Belfast BT7 1NT

diff --git a/views/updateUser.ejs b/views/updateUser.ejs index 6132846..c3f1e59 100644 --- a/views/updateUser.ejs +++ b/views/updateUser.ejs @@ -5,6 +5,7 @@ Update User + @@ -22,5 +23,6 @@ +

Kainos 4-6 Upper Cres, Belfast BT7 1NT

diff --git a/views/user.ejs b/views/user.ejs index 2a8df0d..26681d4 100644 --- a/views/user.ejs +++ b/views/user.ejs @@ -5,9 +5,14 @@ User Information + +
+

User Information

<% if (user) { %> @@ -30,7 +35,7 @@ <% } else { %>

No user found.

<% } %> - +

Kainos 4-6 Upper Cres, Belfast BT7 1NT

diff --git a/views/users.ejs b/views/users.ejs index f323c63..b0a6689 100644 --- a/views/users.ejs +++ b/views/users.ejs @@ -5,9 +5,16 @@ User List + + +
+ +

User List

<% if (users && users.length > 0) { %> @@ -42,5 +49,7 @@
+ +

Kainos 4-6 Upper Cres, Belfast BT7 1NT

From caf0d02566fdc9685d1c569e195e8fe1e728be05 Mon Sep 17 00:00:00 2001 From: Noblenog <147069847+Noblenog@users.noreply.github.com> Date: Fri, 24 Jan 2025 10:55:12 +0000 Subject: [PATCH 07/16] View employees changes + additional employee (#1) * Recommit last commit * styling added to user and made details viewable in table * improve styling and user details card * fleshed out JSON data, added salary, and employee number * updated json entries * PLace holder user image added * updated background colour on user list container box --------- Co-authored-by: John Livingstone --- public/stylesheets/style.css | 178 ++++++++++++++++++++++++++++++++++- views/user.ejs | 74 +++++++++------ views/users.ejs | 2 +- 3 files changed, 221 insertions(+), 33 deletions(-) diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 9453385..7c53f14 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -1,8 +1,178 @@ -body { +/* General styles */ +* { + box-sizing: border-box; +} + +.user-list-container { + background-color: #ffffff; + font-family: "Lucida Grande", Helvetica, Arial, sans-serif; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + min-height: 100vh; + margin: 0; padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; + width: 80%; +} + +.user-table { + width: 100%; + border-collapse: collapse; + margin-bottom: 20px; +} + +.user-table th, .user-table td { + border: 1px solid #ddd; + padding: 8px; + text-align: left; +} + +.user-table th { + background-color: #f2f2f2; +} + +/* Buttons */ +.btn-view, .btn-edit, .btn-delete { + margin-right: 5px; + padding: 5px 10px; + text-decoration: none; + color: white; + border-radius: 3px; +} + +.btn-view { + background-color: #4CAF50; +} + +.btn-edit { + background-color: #FFC107; +} + +.btn-delete { + background-color: #F44336; +} + +.create-user-form { + text-align: right; +} + +.btn-create { + padding: 10px 20px; + background-color: #008CBA; + color: white; + border: none; + border-radius: 3px; + cursor: pointer; +} + +.btn-create:hover { + background-color: #005f73; +} + +h1 { + text-align: center; + color: #283583; +} + +p { + font-size: 14px; + line-height: 21px; + color: #ffffff; + text-align: center; +} + +h3 { + margin: 10px 0; + color: #41679f; +} + +h6 { + margin: 5px 0; + text-transform: uppercase; + color: #a8a3a3; +} + +/* Container styles */ +.container { + width: 80%; + margin: 0 auto; + padding: 20px; + background-color: #f9f9f9; + border-radius: 8px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +@import url('https://fonts.googleapis.com/css?family=Montserrat'); + +body { + background-image: linear-gradient(to right top, #1a2447, #283583, #3b4da6, #5b6ec8, #7f93eb); + font-family: Montserrat, sans-serif; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + min-height: 100vh; + margin: 0; +} + +.card-container { + background-color: #231E39; + border-radius: 25px; + box-shadow: 10px 10px 15px rgba(0,0,0,0.35); + color: #B3B8CD; + padding: 30px 0 0; + position: relative; + width: 350px; + height: 550px; + max-width: 100%; + text-align: center; + margin: 20px 0; + overflow: hidden; +} + + +.card-container img { + border: 1px solid #41679f; + border-radius: 50%; + padding: 7px; + height: 150px; + width: 150px; +} + +button.primary { + background-color: #41679f; + border: 1px solid #41679f; + border-radius: 3px; + color: #fff; + font-family: Montserrat, sans-serif; + font-weight: 500; + padding: 10px 25px; +} + +button.primary.ghost { + background-color: transparent; + color: #41679f; +} + +.skills { + background-color: #1F1A36; + text-align: left; + padding: 15px; + margin-top: 30px; +} + +.skills ul { + list-style-type: none; + margin: 0; + padding: 0; } -a { - color: #00B7FF; +.skills ul li { + border: 1px solid #2D2747; + border-radius: 2px; + display: inline-block; + font-size: 12px; + margin: 0 7px 7px 0; + padding: 7px; } diff --git a/views/user.ejs b/views/user.ejs index 2a8df0d..933bc35 100644 --- a/views/user.ejs +++ b/views/user.ejs @@ -1,36 +1,54 @@ - + - - User Information - + Employee Details + + -

User Information

- - <% if (user) { %> - - - - - - - - - - - - - - - -
NameEmailRole
<%= user.name %><%= user.email %><%= user.role %>
- <% } else { %> -

No user found.

- <% } %> +
+
+ user + +
+ +
+
+
+
Email
+

<%= user.email %>

+
+
+
+
Address
+

<%= user.address %>

+
+
+
+
Role
+

<%= user.role %>

+
+
+
+
Salary
+

<%= user.salary %>

+
+
- - +
+ + +
+
+ + diff --git a/views/users.ejs b/views/users.ejs index 08221c1..9058c10 100644 --- a/views/users.ejs +++ b/views/users.ejs @@ -8,7 +8,7 @@ -
+

User List

<% if (users && users.length > 0) { %> From 347b6c53ddc38b814276f159f2de7c3c627f059b Mon Sep 17 00:00:00 2001 From: Noblenog Date: Fri, 24 Jan 2025 11:41:57 +0000 Subject: [PATCH 08/16] routing to the login page and ejs file showing login page, with styling present --- app.js | 2 ++ routes/login.js | 9 +++++++++ views/login.ejs | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 routes/login.js create mode 100644 views/login.ejs diff --git a/app.js b/app.js index ff3080d..6c96d5d 100644 --- a/app.js +++ b/app.js @@ -7,6 +7,7 @@ require('dotenv').config(); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); +var loginRouter = require('./routes/login'); var app = express(); @@ -22,6 +23,7 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); +app.use('/login', loginRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { diff --git a/routes/login.js b/routes/login.js new file mode 100644 index 0000000..784bb45 --- /dev/null +++ b/routes/login.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +// Route to render the login page +router.get('/', (req, res) => { + res.render('login'); +}); + +module.exports = router; \ No newline at end of file diff --git a/views/login.ejs b/views/login.ejs new file mode 100644 index 0000000..e011a1a --- /dev/null +++ b/views/login.ejs @@ -0,0 +1,24 @@ + + + + + + Login + + + + +
+

Login

+
+
+
+ +
+
+ + +
+
+ + \ No newline at end of file From 5a44f15686963dfaee711446426d34772cc13091 Mon Sep 17 00:00:00 2001 From: Noblenog Date: Fri, 24 Jan 2025 12:18:51 +0000 Subject: [PATCH 09/16] added login button for index page --- views/index.ejs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/views/index.ejs b/views/index.ejs index 34dffd6..95b0c1a 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,17 +1,11 @@ - - - - <%= title %> - -
From 104502a478f3bdfdb9521230162dfd3ce2844194 Mon Sep 17 00:00:00 2001 From: John Livingstone Date: Fri, 24 Jan 2025 12:25:38 +0000 Subject: [PATCH 10/16] fixed index formating --- public/stylesheets/style.css | 59 +++++++++++++++++++++++++----------- views/index.ejs | 45 +++++++++++++++++++-------- 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index bba9a69..5ded3c1 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -178,39 +178,62 @@ button.primary.ghost { } -footer{ - background-color: #283583; +.f1{ + font-size: 1em; + padding-top: 5rem; + padding-left: 30rem; +} + +header{ color: white; position: relative; width: 100%; + height: 15%; font-family: Galano Grotesque; - padding-bottom: 2rem; -} - -.f1{ - font-size: 2em; - padding-top: 5rem; - padding-left: 30rem; } .hometitle{ - font-size: 5em; - position: center; - padding-left: 35rem; + font-size: 3.5em; font-family: Galano Grotesque; + align-items: center; + color: white; + margin-top: 0rem; + margin-bottom: 0rem; } -.logo{ +.Company-Logo{ + align-self: center; padding-left: 20rem; - width: 400px; - height: 125px; - padding-bottom: 5rem; } .welcome{ font-size: 2em; - padding-bottom: 10rem; font-family: Galano Grotesque; - + +} + +.main-section{ + background-color: #f9f9f9; + padding-top: 1rem; + padding-bottom: 5rem; + width: 100%; + +} + +.main-section .welcome{ + font-size: 3em; + padding-bottom: 2rem; + font-family: Galano Grotesque; + color: #283583; + height: 60%; +} + +footer{ + background-color: #283583; + color: white; + position: relative; + width: 100%; + font-family: Galano Grotesque; + margin-top: 0rem; } \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index 34dffd6..006ef6c 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,26 +1,45 @@ - + - - - <%= title %> - - + + + <%= title %> + + + - +
- -

<%= title %>

-

Welcome to <%= title %>

+

+ <%= title %> +

-

Kainos 4-6 Upper Cres, Belfast BT7 1NT

- +
+ + +

Welcome to <%= title %> +

+
+ +
+
+ + +
+

Kainos 4-6 Upper Cres, Belfast BT7 1NT

+
+ + + + \ No newline at end of file From a948c4b9105a6ce938628569ddb2ee992f7dba01 Mon Sep 17 00:00:00 2001 From: Noblenog Date: Fri, 24 Jan 2025 12:46:03 +0000 Subject: [PATCH 11/16] added POST routing for login details, added some rudimentary passwords to user data --- routes/login.js | 28 ++++++++++++++++++++++++++++ users.json | 5 ++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/routes/login.js b/routes/login.js index 784bb45..5136f33 100644 --- a/routes/login.js +++ b/routes/login.js @@ -1,4 +1,6 @@ var express = require('express'); +var fs = require('fs'); +var path = require('path'); var router = express.Router(); // Route to render the login page @@ -6,4 +8,30 @@ router.get('/', (req, res) => { res.render('login'); }); +// Handle login form submission +router.post('/', (req, res) => { + const { email, password } = req.body; + + // Read the users.json file + fs.readFile(path.join(__dirname, '../users.json'), 'utf8', (err, data) => { + if (err) { + console.error(err); + return res.status(500).send('Internal Server Error'); + } + + const users = JSON.parse(data); + + // Check if the email and password match any user + const user = users.find(user => user.email === email && user.password === password); + + if (user) { + // Authentication successful + res.redirect('/users'); + } else { + // Authentication failed + res.status(401).send('Invalid email or password'); + } + }); +}); + module.exports = router; \ No newline at end of file diff --git a/users.json b/users.json index d7d44fb..9df70d1 100644 --- a/users.json +++ b/users.json @@ -4,6 +4,7 @@ "employee number": "12345678", "name": "Shaun", "email": "shaun@test.com", + "password": "password", "role": "Software Engineer", "address": "1234 Main St", "salary": "£50,000" @@ -13,7 +14,8 @@ "employee number": "23456789", "name": "Noble", "email": "Noble@test.com", - "role": "Super Senior Software Engineer", + "password": "password123", + "role": "Software Engineer", "address": "256 Main St", "salary": "£80,000" }, @@ -22,6 +24,7 @@ "employee number": "34567890", "name": "Abbey", "email": "abbey@test.com", + "password": "password456", "role": "Software Engineer", "address": "742 Main St", "salary": "£55,000" From 96a1d801c6b92d1f9109d0daf12d509a676face3 Mon Sep 17 00:00:00 2001 From: Noblenog Date: Fri, 24 Jan 2025 13:01:07 +0000 Subject: [PATCH 12/16] validation for login page, to give warning for wrong login details, and not allow entry --- public/stylesheets/style.css | 5 +++++ routes/login.js | 6 +++--- views/login.ejs | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index bba9a69..4ea92dc 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -16,6 +16,11 @@ width: 80%; } +.error { + color: red; + font-weight: bold; +} + .user-table { width: 100%; border-collapse: collapse; diff --git a/routes/login.js b/routes/login.js index 5136f33..8b01f06 100644 --- a/routes/login.js +++ b/routes/login.js @@ -5,7 +5,7 @@ var router = express.Router(); // Route to render the login page router.get('/', (req, res) => { - res.render('login'); + res.render('login', { error: null }); }); // Handle login form submission @@ -28,8 +28,8 @@ router.post('/', (req, res) => { // Authentication successful res.redirect('/users'); } else { - // Authentication failed - res.status(401).send('Invalid email or password'); + // Authentication failed, render the login page with an error message + res.render('login', { error: 'Invalid email or password' }); } }); }); diff --git a/views/login.ejs b/views/login.ejs index e011a1a..745c8de 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -10,6 +10,9 @@

Login

+ <% if (error) { %> +

<%= error %>

+ <% } %>


From 8134d22a10c7dbd8aff22a57e975475f45762360 Mon Sep 17 00:00:00 2001 From: John Livingstone Date: Fri, 24 Jan 2025 13:26:36 +0000 Subject: [PATCH 13/16] Fixed formating on users.ejs --- public/stylesheets/style.css | 9 ++++-- views/users.ejs | 54 +++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 5ded3c1..23c6c96 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -12,14 +12,15 @@ flex-direction: column; min-height: 100vh; margin: 0; - padding: 50px; + /* padding: 10px; */ width: 80%; } .user-table { - width: 100%; + width: 80%; border-collapse: collapse; - margin-bottom: 20px; + margin-bottom: 10px; + align-items: center; } .user-table th, .user-table td { @@ -192,6 +193,8 @@ header{ font-family: Galano Grotesque; } + + .hometitle{ font-size: 3.5em; font-family: Galano Grotesque; diff --git a/views/users.ejs b/views/users.ejs index 982e19a..4517d89 100644 --- a/views/users.ejs +++ b/views/users.ejs @@ -1,6 +1,7 @@ + @@ -8,16 +9,20 @@ + -
+
+
+ -

User List

+ +

User List

- <% if (users && users.length > 0) { %> + <% if (users && users.length> 0) { %> @@ -28,31 +33,42 @@ - <% users.forEach(user => { %> + <% users.forEach(user=> { %> - - - + + + - <% }); %> + <% }); %>
<%= user.name %><%= user.email %><%= user.role %> + <%= user.name %> + + <%= user.email %> + + <%= user.role %> + View Edit Delete
- <% } else { %> -

No users found.

- <% } %> + <% } else { %> +

No users found.

+ <% } %> - - - +
+ +
- Return to Home -
+ Return to Home +
+ -

Kainos 4-6 Upper Cres, Belfast BT7 1NT

+ +
+

Kainos 4-6 Upper Cres, Belfast BT7 1NT

+
- + + \ No newline at end of file From 0668fa0cdce152f2dfdcb054d1bdf44262e323ee Mon Sep 17 00:00:00 2001 From: John Livingstone Date: Fri, 24 Jan 2025 13:28:55 +0000 Subject: [PATCH 14/16] formatting fixed in user.ejs --- public/stylesheets/style.css | 2 +- views/user.ejs | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 23c6c96..b3c78dc 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -12,7 +12,7 @@ flex-direction: column; min-height: 100vh; margin: 0; - /* padding: 10px; */ + padding: 10px; width: 80%; } diff --git a/views/user.ejs b/views/user.ejs index 8330d67..551c231 100644 --- a/views/user.ejs +++ b/views/user.ejs @@ -11,11 +11,6 @@ -
- -
From 15cc0fa15285f4d1126ab37347a7d7f75be248c1 Mon Sep 17 00:00:00 2001 From: Noblenog Date: Fri, 24 Jan 2025 13:55:18 +0000 Subject: [PATCH 15/16] reworked login button --- views/index.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/index.ejs b/views/index.ejs index 8630feb..e3f1fa9 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -26,7 +26,7 @@

Welcome to <%= title %>