From 29b85bc38cfee5a24288a1df24f543ce79b4f3ae Mon Sep 17 00:00:00 2001 From: rocord01 Date: Sat, 20 Dec 2025 23:14:48 -0500 Subject: [PATCH] made dashboard look nicer --- buttons.json | 14 +- index.js | 28 +- pnpm-lock.yaml | 699 +++++++++++++++++++++++++++++++++++++ static/assets/img/logo.png | Bin 0 -> 17953 bytes views/index.ejs | 183 ++++++---- views/login.ejs | 96 +++-- 6 files changed, 889 insertions(+), 131 deletions(-) create mode 100644 pnpm-lock.yaml create mode 100644 static/assets/img/logo.png diff --git a/buttons.json b/buttons.json index 2f611de..c855509 100644 --- a/buttons.json +++ b/buttons.json @@ -1,9 +1,5 @@ { - "COLS": [ - "Normal Announcements", - "Emergency Announcements" - ], - "ROWS": [ + "Normal Announcements": [ { "text": "Live Page", "btnClass": "btn-primary", @@ -15,7 +11,10 @@ "timeout": 30000, "cid": "Live Page" } - }, + } + ], + + "Emergency Announcements": [ { "text": "Emergency Announcement", "btnClass": "btn-danger", @@ -28,7 +27,7 @@ "cid": "Emergency Announcement" } }, - {}, + { "text": "Tornado Alert", "btnClass": "btn-warning", @@ -43,4 +42,5 @@ } } ] + } \ No newline at end of file diff --git a/index.js b/index.js index 97a1c89..f5d8bd7 100644 --- a/index.js +++ b/index.js @@ -9,18 +9,18 @@ const buttonsCfg = require('./buttons.json'); const contexts = {}; // Generate contexts from buttonsCfg -if (buttonsCfg && buttonsCfg.ROWS) { - buttonsCfg.ROWS.forEach(button => { - if (button.name && button.context) { - contexts[button.name] = { - context: button.context.context, - timeout: button.context.timeout, - cid: button.context.cid, - ...(button.context.dial && { dial: button.context.dial }) - }; - } - }); -} +Object.keys(buttonsCfg).forEach(category => { + buttonsCfg[category].forEach(button => { + if (button.name && button.context) { + contexts[button.name] = { + context: button.context.context, + timeout: button.context.timeout, + cid: button.context.cid, + ...(button.context.dial && { dial: button.context.dial }) + }; + } + }); +}); console.log('Generated contexts:', contexts); @@ -95,6 +95,10 @@ app.get('/', (req, res) => { res.render('index', { session: req.session, phones: phonesCfg, buttons: require("./buttons.json") }); }); +app.get('/login', (req, res) => { + res.render('login', { session: req.session }); +}); + app.post('/trig', async (req, res) => { console.log('Triggering call with data:', req.body); trigCall(req.body.pageType, req.body.phone); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..17da460 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,699 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + ejs: + specifier: ^3.1.10 + version: 3.1.10 + express: + specifier: ^5.2.1 + version: 5.2.1 + express-session: + specifier: ^1.18.2 + version: 1.18.2 + +packages: + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + body-parser@2.2.1: + resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} + engines: {node: '>=18'} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + express-session@1.18.2: + resolution: {integrity: sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A==} + engines: {node: '>= 0.8.0'} + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.7.1: + resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==} + engines: {node: '>=0.10.0'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + random-bytes@1.0.0: + resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} + engines: {node: '>= 0.8'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + uid-safe@2.1.5: + resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} + engines: {node: '>= 0.8'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + +snapshots: + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + async@3.2.6: {} + + balanced-match@1.0.2: {} + + body-parser@2.2.1: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.1 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + + cookie-signature@1.0.7: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + depd@2.0.0: {} + + dotenv@17.2.3: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.4 + + encodeurl@2.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + escape-html@1.0.3: {} + + etag@1.8.1: {} + + express-session@1.18.2: + dependencies: + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + on-headers: 1.1.0 + parseurl: 1.3.3 + safe-buffer: 5.2.1 + uid-safe: 2.1.5 + transitivePeerDependencies: + - supports-color + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.1 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + iconv-lite@0.7.1: + dependencies: + safer-buffer: 2.1.2 + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + is-promise@4.0.0: {} + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.4 + picocolors: 1.1.1 + + math-intrinsics@1.1.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.2 + + ms@2.0.0: {} + + ms@2.1.3: {} + + negotiator@1.0.0: {} + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + parseurl@1.3.3: {} + + path-to-regexp@8.3.0: {} + + picocolors@1.1.1: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + random-bytes@1.0.0: {} + + range-parser@1.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.1 + unpipe: 1.0.0 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + statuses@2.0.2: {} + + toidentifier@1.0.1: {} + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + + uid-safe@2.1.5: + dependencies: + random-bytes: 1.0.0 + + unpipe@1.0.0: {} + + vary@1.1.2: {} + + wrappy@1.0.2: {} diff --git a/static/assets/img/logo.png b/static/assets/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..01d7aa8b9dcfa01c2e3d2d1a01379a4e842f7a9d GIT binary patch literal 17953 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 literal 0 HcmV?d00001 diff --git a/views/index.ejs b/views/index.ejs index e0c0770..e280272 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -4,94 +4,127 @@ - + Paging Console - - -
- -
+ + <% // determine columns and chunk rows - const cols = (buttons && buttons.COLS) || ['']; + const cols = Object.keys(buttons); const numCols = Math.max(1, cols.length); - const rowsFlat = (buttons && buttons.ROWS) || []; - const chunks = []; - for (let i = 0; i < rowsFlat.length; i += numCols) { - const slice = rowsFlat.slice(i, i + numCols); - // pad short slice with empty objects so layout stays consistent - while (slice.length < numCols) slice.push({}); - chunks.push(slice); - } %> -
-
- - - - <% for (let c = 0; c < numCols; c++) { %> - - <% } %> - - - - <% chunks.forEach((row) => { %> - - <% for (let c = 0; c < numCols; c++) { - const cell = row[c] || {}; - const isBlank = Object.keys(cell).length === 0; - %> - - <% } %> - - <% }); %> - -
-

<%= cols[c] || '' %>

-
- <% if (isBlank) { %> - - <% } else { - const ctx = cell.context || {}; - %> - - <% } %> -
+
+
+
+ <% cols.forEach(col => { %> +
+
+

+ <%= col %> +

+
+ + <% buttons[col].forEach((cell) => { + const ctx = cell.context || {}; + %> + + <% }); %> +
+ <% }); %> +
-
+ - - - + Sign In + - -
-
-
-
-
-

Sign in

- - <% if (typeof error !== 'undefined' && error) { %> - - <% } %> - -
-
- - -
- -
- - -
- -
- - -
- - -
- -

Return to home

+ +
+
+
+
+
+ Logo
+

Paging Console

+

Please sign in to your account

+ + <% if (typeof error !== 'undefined' && error) { %> + + <% } %> + +
+
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+ + +
+
+ + +
- - - \ No newline at end of file