From cbe002f4c4f9ad53015b6ca030ce6c74305dbf8e Mon Sep 17 00:00:00 2001 From: Drake Marino Date: Thu, 19 Jun 2025 17:14:18 -0500 Subject: [PATCH] Fixes --- package-lock.json | 640 +++++++++++++++++- package.json | 3 +- src/app.css | 6 +- src/lib/db/index.server.ts | 186 +++-- src/lib/shared.server.ts | 7 +- src/lib/shared.svelte.ts | 2 +- src/routes/+error.svelte | 7 +- src/routes/account/+page.svelte | 60 +- .../account/editapplication/+page.server.ts | 47 ++ .../account/editapplication/+page.svelte | 117 ++++ .../admin/users/[user]/edit/+page.svelte | 6 +- src/routes/admin/users/create/+page.svelte | 6 +- src/routes/postings/+page.svelte | 2 +- src/routes/postings/[posting]/+page.svelte | 2 +- .../postings/[posting]/manage/+page.svelte | 2 +- .../manage/applications/+page.svelte | 66 +- .../[posting]/manage/edit/+page.svelte | 2 +- 17 files changed, 1052 insertions(+), 109 deletions(-) create mode 100644 src/routes/account/editapplication/+page.server.ts create mode 100644 src/routes/account/editapplication/+page.svelte diff --git a/package-lock.json b/package-lock.json index 7fe661f..795d542 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@sveltejs/adapter-node": "^5.2.9", "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/vite": "^4.1.10", "autoprefixer": "^10.4.20", "bcrypt": "^5.1.1", "desm": "^1.3.1", @@ -40,7 +41,7 @@ "prettier-plugin-tailwindcss": "^0.6.9", "svelte": "^5.0.0", "svelte-check": "^4.0.0", - "tailwindcss": "^3.4.9", + "tailwindcss": "^3.4.17", "typescript": "^5.0.0", "typescript-eslint": "^8.0.0", "vite": "^6.0.0" @@ -763,6 +764,27 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@isaacs/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", @@ -1329,6 +1351,360 @@ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" } }, + "node_modules/@tailwindcss/node": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.10.tgz", + "integrity": "sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.10" + } + }, + "node_modules/@tailwindcss/node/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/@tailwindcss/node/node_modules/tailwindcss": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz", + "integrity": "sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==", + "license": "MIT" + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.10.tgz", + "integrity": "sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.10", + "@tailwindcss/oxide-darwin-arm64": "4.1.10", + "@tailwindcss/oxide-darwin-x64": "4.1.10", + "@tailwindcss/oxide-freebsd-x64": "4.1.10", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.10", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.10", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.10", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.10", + "@tailwindcss/oxide-linux-x64-musl": "4.1.10", + "@tailwindcss/oxide-wasm32-wasi": "4.1.10", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.10", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.10" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.10.tgz", + "integrity": "sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.10.tgz", + "integrity": "sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.10.tgz", + "integrity": "sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.10.tgz", + "integrity": "sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.10.tgz", + "integrity": "sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.10.tgz", + "integrity": "sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.10.tgz", + "integrity": "sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.10.tgz", + "integrity": "sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.10.tgz", + "integrity": "sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.10.tgz", + "integrity": "sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.10", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.10.tgz", + "integrity": "sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.10.tgz", + "integrity": "sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.10.tgz", + "integrity": "sha512-QWnD5HDY2IADv+vYR82lOhqOlS1jSCUUAmfem52cXAhRTKxpDh3ARX8TTXJTCCO7Rv7cD2Nlekabv02bwP3a2A==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.10", + "@tailwindcss/oxide": "4.1.10", + "tailwindcss": "4.1.10" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6" + } + }, + "node_modules/@tailwindcss/vite/node_modules/tailwindcss": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz", + "integrity": "sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==", + "license": "MIT" + }, "node_modules/@types/bcrypt": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", @@ -2449,9 +2825,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -2543,6 +2919,19 @@ "node": ">= 0.8" } }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -3385,6 +3774,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3783,6 +4178,234 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -5823,6 +6446,15 @@ "node": ">=8.10.0" } }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tar": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", diff --git a/package.json b/package.json index 9830bf8..8d929d8 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "prettier-plugin-tailwindcss": "^0.6.9", "svelte": "^5.0.0", "svelte-check": "^4.0.0", - "tailwindcss": "^3.4.9", + "tailwindcss": "^3.4.17", "typescript": "^5.0.0", "typescript-eslint": "^8.0.0", "vite": "^6.0.0" @@ -39,6 +39,7 @@ "dependencies": { "@sveltejs/adapter-node": "^5.2.9", "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/vite": "^4.1.10", "autoprefixer": "^10.4.20", "bcrypt": "^5.1.1", "desm": "^1.3.1", diff --git a/src/app.css b/src/app.css index 5feff15..c12fde8 100644 --- a/src/app.css +++ b/src/app.css @@ -20,12 +20,12 @@ [data-theme='dark'] { --text-color: #f4f4f4; --bg-color: #0c0c0c; - --hover-bg-color: #1a1c1c; - --separator-line-color: #1a2029; + --hover-bg-color: #1c1e1e; + --separator-line-color: #2e343d; --low-emphasis-text-color: #999999; --primary-color: #1F96F3; --dull-primary-color: #1569ab; - --elevated-bg-color: #151516; + --elevated-bg-color: #1a1a1b; --bg-accent-color: #202020; --danger-color: #ff1d1f; --hyperlink-color: #3b82f6; diff --git a/src/lib/db/index.server.ts b/src/lib/db/index.server.ts index 4f719cc..d173355 100644 --- a/src/lib/db/index.server.ts +++ b/src/lib/db/index.server.ts @@ -40,31 +40,30 @@ export async function updateUser(user: User): Promise { } // Construct the SQL query - const response = await sql`UPDATE users - SET username = ${user.username}, - ${ - user.perms !== undefined - ? sql`perms - = - ${user.perms},` - : sql`` - } - ${ - user.active !== undefined - ? sql`active - = - ${user.active},` - : sql`` - } ${ - password_hash !== null - ? sql`password_hash - = - ${password_hash},` - : sql`` - } - email = ${user.email}, phone = ${user.phone}, full_name = ${user.fullName}, company_code = ${user.companyCode} - WHERE id = ${user.id} - RETURNING id;`; + const response = await sql` + UPDATE users + SET username = ${user.username}, + ${ + user.perms !== undefined + ? sql`perms = ${user.perms},` + : sql`` + } + ${ + user.active !== undefined + ? sql`active = ${user.active},` + : sql`` + } + ${ + password_hash !== null + ? sql`password_hash = ${password_hash},` + : sql`` + } + email = ${user.email}, + phone = ${user.phone}, + full_name = ${user.fullName}, + company_code = ${user.companyCode} + WHERE id = ${user.id} + RETURNING id;`; await saveAvatar(user); @@ -220,7 +219,8 @@ export async function getUserWithCompanyAndApplications( application_data AS (SELECT id, posting_id AS "postingId", (SELECT title FROM postings WHERE id = posting_id) AS "postingTitle", - created_at AT TIME ZONE 'UTC' AS "createdAt" + created_at AT TIME ZONE 'UTC' AS "createdAt", + candidate_statement AS "candidateStatement" FROM applications WHERE "user_id" = ${id}) SELECT (SELECT row_to_json(company_data) @@ -236,7 +236,7 @@ export async function getUserWithCompanyAndApplications( if (!data) { error(404, 'User not found'); } - let user = data[0].user; + const user = data[0].user; if (data[0].company) { user.company = data[0].company; } @@ -246,7 +246,7 @@ export async function getUserWithCompanyAndApplications( if (user.company) { user.company.createdAt = new Date(user.company.createdAt); } - let applications = data[0].applications; + const applications = data[0].applications; if (applications) { applications.forEach((application: { createdAt: string | number | Date }) => { application.createdAt = new Date(application.createdAt); @@ -509,8 +509,8 @@ export async function getCompanyEmployers( if (data[0].users) { data[0].users.forEach( (user: { - company: { id: any }; - companyId: any; + company: { id: unknown }; + companyId: unknown; createdAt: string | number | Date; lastSignIn: string | number | Date; }) => { @@ -576,8 +576,8 @@ export async function getCompanyEmployersAndRequests( if (data[0].employers) { data[0].employers.forEach( (user: { - company: { id: any }; - companyId: any; + company: { id: unknown }; + companyId: unknown; createdAt: string | number | Date; lastSignIn: string | number | Date; }) => { @@ -593,8 +593,8 @@ export async function getCompanyEmployersAndRequests( if (data[0].requests) { data[0].requests.forEach( (user: { - company: { id: any }; - companyId: any; + company: { id: unknown }; + companyId: unknown; createdAt: string | number | Date; lastSignIn: string | number | Date; }) => { @@ -751,7 +751,7 @@ export async function getPostingWithCompanyUser(id: number): Promise { if (!data) { error(404, 'Posting not found'); } - let posting = data[0].posting; + const posting = data[0].posting; posting.company = data[0].company; posting.employer = data[0].user; @@ -765,16 +765,107 @@ export async function getPostingWithCompanyUser(id: number): Promise { return posting; } -export async function createApplication(application: Application): Promise { - const response = await sql` - INSERT INTO applications (posting_id, user_id, candidate_statement, created_at) - VALUES (${application.postingId}, ${application.userId}, ${application.candidateStatement}, NOW()) RETURNING id; + +export async function getEditApplicationPageData(applicationId: number): Promise<{ posting: Posting; application: Application }> { + const data = await sql` + WITH application_data AS ( + SELECT id AS application_id, + candidate_statement, + posting_id + FROM applications + WHERE id = ${applicationId} + ), + company_data AS ( + SELECT id, + name, + description, + website, + created_at AS "createdAt" + FROM companies + WHERE id = ( + SELECT company_id + FROM postings + WHERE id = (SELECT posting_id FROM application_data) + ) + ), + user_data AS ( + SELECT username, + email, + phone, + full_name AS "fullName" + FROM users + WHERE company_id = ( + SELECT company_id + FROM postings + WHERE id = (SELECT posting_id FROM application_data) + ) + ), + posting_data AS ( + SELECT id, + title, + description, + employer_id AS "employerId", + address, + employment_type AS "employmentType", + wage, + link, + tag_ids AS "tagIds", + created_at AT TIME ZONE 'UTC' AS "createdAt", + updated_at AT TIME ZONE 'UTC' AS "updatedAt", + flyer_link AS "flyerLink" + FROM postings + WHERE id = (SELECT posting_id FROM application_data) + ) + SELECT + (SELECT row_to_json(company_data) FROM company_data) AS company, + (SELECT row_to_json(user_data) FROM user_data) AS user, + (SELECT row_to_json(posting_data) FROM posting_data) AS posting, + (SELECT row_to_json(application_data) FROM application_data) AS application; `; - sendEmployerNotificationEmail(application.postingId).catch((err) => { - console.error('Failed to send employer notification email: ', err); - }); - return response[0].id; + if (!data || !data[0]?.posting) { + error(404, 'Posting not found'); + } + + const posting = data[0].posting; + posting.company = data[0].company; + posting.employer = data[0].user; + + if (posting.createdAt) { + posting.createdAt = new Date(posting.createdAt); + } + if (posting.updatedAt) { + posting.updatedAt = new Date(posting.updatedAt); + } + + const application = { + id: data[0].application.application_id, + candidateStatement: data[0].application.candidate_statement + }; + + return { posting, application }; +} + +export async function createApplication(application: Application): Promise { + try { + + const response = await sql` + INSERT INTO applications (posting_id, user_id, candidate_statement, created_at) + VALUES (${application.postingId}, ${application.userId}, ${application.candidateStatement}, NOW()) RETURNING id; + `; + sendEmployerNotificationEmail(application.postingId).catch((err) => { + console.error('Failed to send employer notification email: ', err); + }); + return response[0].id; + + } catch (err) { + if (err instanceof Error && err.message.includes('duplicate key value')) { + error(400, 'You have already applied for this job'); + } else { + error(500, 'Internal server error while creating application'); + } + } + } export async function deleteApplication(id: number): Promise { @@ -789,7 +880,6 @@ export async function deleteApplicationWithUser( applicationId: number, userId: number ): Promise { - console.log(applicationId, userId); await sql` DELETE FROM applications @@ -798,6 +888,14 @@ export async function deleteApplicationWithUser( `; } +export async function editApplication(application: Application): Promise { + await sql` + UPDATE applications + SET candidate_statement = ${application.candidateStatement} + WHERE id = ${application.id}; + `; +} + export async function getApplications(postingId: number): Promise { const data = await sql` SELECT a.id, diff --git a/src/lib/shared.server.ts b/src/lib/shared.server.ts index 3a70b53..aa4db1b 100644 --- a/src/lib/shared.server.ts +++ b/src/lib/shared.server.ts @@ -13,8 +13,13 @@ export function setJWT(cookies: Cookies, user: User) { if (process.env.JWT_SECRET === undefined) { throw new Error('JWT_SECRET not defined'); } + if (process.env.BASE_URL === undefined) { + throw new Error('BASE_URL not defined'); + } + + const secure: boolean = process.env.BASE_URL?.includes('https://'); const maxAge = 60 * 60 * 24 * 30; // 30 days const JWT = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '30d' }); - cookies.set('jwt', JWT, { maxAge, path: '/', httpOnly: false }); + cookies.set('jwt', JWT, { maxAge, path: '/', httpOnly: secure, secure: secure }); } diff --git a/src/lib/shared.svelte.ts b/src/lib/shared.svelte.ts index c32d728..a9cc3fe 100644 --- a/src/lib/shared.svelte.ts +++ b/src/lib/shared.svelte.ts @@ -26,7 +26,7 @@ export function telFormatter(initial: string) { return initial; } -export const getCookieValue = (name: String) => +export const getCookieValue = (name: string) => document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)')?.pop() || ''; export function updateUserState() { diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte index 59290ed..65b3043 100644 --- a/src/routes/+error.svelte +++ b/src/routes/+error.svelte @@ -22,8 +22,13 @@

This one is on our end...

We are working to resolve this as fast as possible.

{/if} - {#if $page.status !== 404 && $page.status !== 403 && $page.status !== 401 && $page.status !== 500} + {#if $page.status === 400} +

Invalid request!

+

Make sure you have correctly inputted all information.

+ {/if} + {#if $page.status !== 404 && $page.status !== 403 && $page.status !== 401 && $page.status !== 500 && $page.status !== 400}

An unexpected error has occurred.

Please try again later

{/if} +

Error: {$page.error?.message}

diff --git a/src/routes/account/+page.svelte b/src/routes/account/+page.svelte index 2043e0a..5e3184f 100644 --- a/src/routes/account/+page.svelte +++ b/src/routes/account/+page.svelte @@ -1,6 +1,7 @@ + +
+
+
+
+
+ Company Logo logoFallback(e, data.posting)} + src="/uploads/logos/{data.posting?.company.id}.jpg" + width="64" + /> +
+

{data.posting.title}

+

Company: {data.posting.company.name}

+
+
+
+
+

Contact

+

{data.posting.employer?.fullName} ({data.posting.employer?.username})

+ {data.posting.employer?.email} + {data.posting.employer?.phone} +

Details

+ {#if data.posting.employmentType} +

{employmentTypeDisplayName(data.posting.employmentType)}

+ {/if} + {#if data.posting.address} + Address: {data.posting.address} + {/if} + {#if data.posting.wage} +

Wage: {data.posting.wage}

+ {/if} + {#if data.posting.createdAt} +

Posted: {data.posting.createdAt.toLocaleDateString('en-US', dateFormatOptions)}

+ {/if} + {#if data.posting.link} + More information: {data.posting.link} + {/if} + {#if data.posting.flyerLink} + Flyer: {data.posting.flyerLink} + {/if} +

Job Description

+

{data.posting.description}

+
+
+
+
+
Edit Application
+
+
+
+ Why do you believe you are the best fit for this role? * + +
+

+ Your account information and résumé (if supplied) will be submitted along with this + application. If there is any other information you would like the employer to know, please + add it in the box above. +

+ + {#if form?.errorMessage} +
{form.errorMessage}
+ {/if} + +
+
+
+
diff --git a/src/routes/admin/users/[user]/edit/+page.svelte b/src/routes/admin/users/[user]/edit/+page.svelte index a448fb0..bb45076 100644 --- a/src/routes/admin/users/[user]/edit/+page.svelte +++ b/src/routes/admin/users/[user]/edit/+page.svelte @@ -10,7 +10,7 @@ let passwordVisible = $state(false); function showPassword() { - const password = document.querySelector('input[name="password"]'); + const password = document.querySelector('input[name="newPassword"]'); if (password) { if (password.getAttribute('type') === 'password') { password.setAttribute('type', 'text'); @@ -122,8 +122,8 @@ New password (optional) diff --git a/src/routes/admin/users/create/+page.svelte b/src/routes/admin/users/create/+page.svelte index 1685d14..5c25f9d 100644 --- a/src/routes/admin/users/create/+page.svelte +++ b/src/routes/admin/users/create/+page.svelte @@ -9,7 +9,7 @@ let passwordVisible = $state(false); function showPassword() { - const password = document.querySelector('input[name="password"]'); + const password = document.querySelector('input[name="newPassword"]'); if (password) { if (password.getAttribute('type') === 'password') { password.setAttribute('type', 'text'); @@ -102,8 +102,8 @@ Password * = 0 && ((userState.perms & PERMISSIONS.MANAGE_POSTINGS) > 0 || ((userState.perms & PERMISSIONS.SUBMIT_POSTINGS) > 0 && userState.companyId === details.company.id))} Manage postingManage posting {:else if (userState.perms & PERMISSIONS.APPLY_FOR_JOBS) > 0} = 0 && ((userState.perms & PERMISSIONS.MANAGE_POSTINGS) > 0 || ((userState.perms & PERMISSIONS.SUBMIT_POSTINGS) > 0 && userState.companyId === data.posting.company.id))} Manage postingManage posting {:else if (userState.perms & PERMISSIONS.APPLY_FOR_JOBS) > 0} +
@@ -52,7 +52,7 @@ Company Logo logoFallback(e, application)} @@ -70,36 +70,34 @@