diff --git a/.env.example b/.env.example index 5af36fd3..1aefaa87 100644 --- a/.env.example +++ b/.env.example @@ -19,8 +19,3 @@ DISCORD_CLIENT_SECRET= # Next Auth GitHub Provider GITHUB_CLIENT_ID= GITHUB_CLIENT_SECRET= - -# Sponsorship Gmail Drafts -SPONSORSHIP_GOOGLE_CLIENT_ID= -SPONSORSHIP_GOOGLE_CLIENT_SECRET= -SPONSORSHIP_GOOGLE_REFRESH_TOKEN= diff --git a/package-lock.json b/package-lock.json index d4414d48..1bc2f14c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,14 @@ "version": "0.1.0", "hasInstallScript": true, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-brands-svg-icons": "^6.5.1", + "@fortawesome/free-regular-svg-icons": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", "@google-cloud/local-auth": "^2.1.1", "@next-auth/prisma-adapter": "^1.0.7", - "@prisma/client": "^5.3.1", + "@prisma/client": "^5.6.0", "@tanstack/react-query": "^4.35.0", "@trpc/client": "^10.38.2", "@trpc/next": "^10.38.2", @@ -21,8 +26,8 @@ "googleapis": "^120.0.0", "i18next": "^22.4.9", "mimetext": "^3.0.15", - "next": "13.1.6", - "next-auth": "^4.20.1", + "next": "^13.5.6", + "next-auth": "^4.24.5", "next-i18next": "^13.1.5", "next-pwa": "^5.6.0", "qr-scanner": "^1.4.2", @@ -37,7 +42,7 @@ "rehype-slug": "^5.1.0", "remark-toc": "^8.0.1", "superjson": "1.12.2", - "zod": "^3.22.3" + "zod": "^3.20.6" }, "devDependencies": { "@faker-js/faker": "^8.0.2", @@ -54,10 +59,10 @@ "autoprefixer": "^10.4.13", "eslint": "^8.34.0", "eslint-config-next": "13.1.6", - "postcss": "^8.4.31", + "postcss": "^8.4.21", "prettier": "^2.8.4", "prettier-plugin-tailwindcss": "^0.2.2", - "prisma": "^5.3.1", + "prisma": "^5.6.0", "tailwindcss": "^3.2.6", "ts-node": "^10.9.1", "typescript": "^4.9.5" @@ -97,11 +102,11 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -218,11 +223,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", "dependencies": { - "@babel/types": "^7.22.15", + "@babel/types": "^7.23.4", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -359,20 +364,20 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -514,17 +519,17 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -564,11 +569,11 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -641,9 +646,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1797,18 +1802,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", - "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "dependencies": { + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.16", - "@babel/types": "^7.22.17", + "@babel/parser": "^7.23.4", + "@babel/types": "^7.23.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1825,12 +1830,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", - "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1931,6 +1936,75 @@ "npm": ">=6.14.13" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz", + "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz", + "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz", + "integrity": "sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz", + "integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz", + "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@google-cloud/local-auth": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@google-cloud/local-auth/-/local-auth-2.1.1.tgz", @@ -2040,9 +2114,9 @@ } }, "node_modules/@next/env": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.1.6.tgz", - "integrity": "sha512-s+W9Fdqh5MFk6ECrbnVmmAOwxKQuhGMT7xXHrkYIBMBcTiOqNWhv5KbJIboKR5STXxNXl32hllnvKaffzFaWQg==" + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.6.tgz", + "integrity": "sha512-Yac/bV5sBGkkEXmAX5FWPS9Mmo2rthrOPRQQNfycJPkjUAUclomCPH7QFVCDQ4Mp2k2K1SSM6m0zrxYrOwtFQw==" }, "node_modules/@next/eslint-plugin-next": { "version": "13.1.6", @@ -2053,40 +2127,10 @@ "glob": "7.1.7" } }, - "node_modules/@next/swc-android-arm-eabi": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.1.6.tgz", - "integrity": "sha512-F3/6Z8LH/pGlPzR1AcjPFxx35mPqjE5xZcf+IL+KgbW9tMkp7CYi1y7qKrEWU7W4AumxX/8OINnDQWLiwLasLQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-android-arm64": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.1.6.tgz", - "integrity": "sha512-cMwQjnB8vrYkWyK/H0Rf2c2pKIH4RGjpKUDvbjVAit6SbwPDpmaijLio0LWFV3/tOnY6kvzbL62lndVA0mkYpw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.1.6.tgz", - "integrity": "sha512-KKRQH4DDE4kONXCvFMNBZGDb499Hs+xcFAwvj+rfSUssIDrZOlyfJNy55rH5t2Qxed1e4K80KEJgsxKQN1/fyw==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.6.tgz", + "integrity": "sha512-5nvXMzKtZfvcu4BhtV0KH1oGv4XEW+B+jOfmBdpFI3C7FrB/MfujRpWYSBBO64+qbW8pkZiSyQv9eiwnn5VIQA==", "cpu": [ "arm64" ], @@ -2099,9 +2143,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.1.6.tgz", - "integrity": "sha512-/uOky5PaZDoaU99ohjtNcDTJ6ks/gZ5ykTQDvNZDjIoCxFe3+t06bxsTPY6tAO6uEAw5f6vVFX5H5KLwhrkZCA==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.6.tgz", + "integrity": "sha512-6cgBfxg98oOCSr4BckWjLLgiVwlL3vlLj8hXg2b+nDgm4bC/qVXXLfpLB9FHdoDu4057hzywbxKvmYGmi7yUzA==", "cpu": [ "x64" ], @@ -2113,40 +2157,10 @@ "node": ">= 10" } }, - "node_modules/@next/swc-freebsd-x64": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.1.6.tgz", - "integrity": "sha512-qaEALZeV7to6weSXk3Br80wtFQ7cFTpos/q+m9XVRFggu+8Ib895XhMWdJBzew6aaOcMvYR6KQ6JmHA2/eMzWw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm-gnueabihf": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.1.6.tgz", - "integrity": "sha512-OybkbC58A1wJ+JrJSOjGDvZzrVEQA4sprJejGqMwiZyLqhr9Eo8FXF0y6HL+m1CPCpPhXEHz/2xKoYsl16kNqw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.1.6.tgz", - "integrity": "sha512-yCH+yDr7/4FDuWv6+GiYrPI9kcTAO3y48UmaIbrKy8ZJpi7RehJe3vIBRUmLrLaNDH3rY1rwoHi471NvR5J5NQ==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.6.tgz", + "integrity": "sha512-txagBbj1e1w47YQjcKgSU4rRVQ7uF29YpnlHV5xuVUsgCUf2FmyfJ3CPjZUvpIeXCJAoMCFAoGnbtX86BK7+sg==", "cpu": [ "arm64" ], @@ -2159,9 +2173,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.1.6.tgz", - "integrity": "sha512-ECagB8LGX25P9Mrmlc7Q/TQBb9rGScxHbv/kLqqIWs2fIXy6Y/EiBBiM72NTwuXUFCNrWR4sjUPSooVBJJ3ESQ==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.6.tgz", + "integrity": "sha512-cGd+H8amifT86ZldVJtAKDxUqeFyLWW+v2NlBULnLAdWsiuuN8TuhVBt8ZNpCqcAuoruoSWynvMWixTFcroq+Q==", "cpu": [ "arm64" ], @@ -2174,9 +2188,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.1.6.tgz", - "integrity": "sha512-GT5w2mruk90V/I5g6ScuueE7fqj/d8Bui2qxdw6lFxmuTgMeol5rnzAv4uAoVQgClOUO/MULilzlODg9Ib3Y4Q==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.6.tgz", + "integrity": "sha512-Mc2b4xiIWKXIhBy2NBTwOxGD3nHLmq4keFk+d4/WL5fMsB8XdJRdtUlL87SqVCTSaf1BRuQQf1HvXZcy+rq3Nw==", "cpu": [ "x64" ], @@ -2189,9 +2203,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.1.6.tgz", - "integrity": "sha512-keFD6KvwOPzmat4TCnlnuxJCQepPN+8j3Nw876FtULxo8005Y9Ghcl7ACcR8GoiKoddAq8gxNBrpjoxjQRHeAQ==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.6.tgz", + "integrity": "sha512-CFHvP9Qz98NruJiUnCe61O6GveKKHpJLloXbDSWRhqhkJdZD2zU5hG+gtVJR//tyW897izuHpM6Gtf6+sNgJPQ==", "cpu": [ "x64" ], @@ -2204,9 +2218,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.1.6.tgz", - "integrity": "sha512-OwertslIiGQluFvHyRDzBCIB07qJjqabAmINlXUYt7/sY7Q7QPE8xVi5beBxX/rxTGPIbtyIe3faBE6Z2KywhQ==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.6.tgz", + "integrity": "sha512-aFv1ejfkbS7PUa1qVPwzDHjQWQtknzAZWGTKYIAaS4NMtBlk3VyA6AYn593pqNanlicewqyl2jUhQAaFV/qXsg==", "cpu": [ "arm64" ], @@ -2219,9 +2233,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.1.6.tgz", - "integrity": "sha512-g8zowiuP8FxUR9zslPmlju7qYbs2XBtTLVSxVikPtUDQedhcls39uKYLvOOd1JZg0ehyhopobRoH1q+MHlIN/w==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.6.tgz", + "integrity": "sha512-XqqpHgEIlBHvzwG8sp/JXMFkLAfGLqkbVsyN+/Ih1mR8INb6YCc2x/Mbwi6hsAgUnqQztz8cvEbHJUbSl7RHDg==", "cpu": [ "ia32" ], @@ -2234,9 +2248,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.1.6.tgz", - "integrity": "sha512-Ls2OL9hi3YlJKGNdKv8k3X/lLgc3VmLG3a/DeTkAd+lAituJp8ZHmRmm9f9SL84fT3CotlzcgbdaCDfFwFA6bA==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.6.tgz", + "integrity": "sha512-Cqfe1YmOS7k+5mGu92nl5ULkzpKuxJrP3+4AEuPmrpFZ3BHxTY3TnHmU1On3bFmFFs6FbTcdF58CCUProGpIGQ==", "cpu": [ "x64" ], @@ -2289,12 +2303,12 @@ } }, "node_modules/@prisma/client": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.3.1.tgz", - "integrity": "sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.6.0.tgz", + "integrity": "sha512-mUDefQFa1wWqk4+JhKPYq8BdVoFk9NFMBXUI8jAkBfQTtgx8WPx02U2HB/XbAz3GSUJpeJOKJQtNvaAIDs6sug==", "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59" + "@prisma/engines-version": "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee" }, "engines": { "node": ">=16.13" @@ -2309,16 +2323,16 @@ } }, "node_modules/@prisma/engines": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.3.1.tgz", - "integrity": "sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.6.0.tgz", + "integrity": "sha512-Mt2q+GNJpU2vFn6kif24oRSBQv1KOkYaterQsi0k2/lA+dLvhRX6Lm26gon6PYHwUM8/h8KRgXIUMU0PCLB6bw==", "devOptional": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz", - "integrity": "sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w==" + "version": "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee.tgz", + "integrity": "sha512-UoFgbV1awGL/3wXuUK3GDaX2SolqczeeJ5b4FVec9tzeGbSWJboPSbT0psSrmgYAKiKnkOPFSLlH6+b+IyOwAw==" }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", @@ -2412,9 +2426,9 @@ } }, "node_modules/@swc/helpers": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", "dependencies": { "tslib": "^2.4.0" } @@ -3664,6 +3678,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -5201,8 +5226,7 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "peer": true + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, "node_modules/globals": { "version": "13.21.0", @@ -7111,49 +7135,43 @@ "peer": true }, "node_modules/next": { - "version": "13.1.6", - "resolved": "https://registry.npmjs.org/next/-/next-13.1.6.tgz", - "integrity": "sha512-hHlbhKPj9pW+Cymvfzc15lvhaOZ54l+8sXDXJWm3OBNBzgrVj6hwGPmqqsXg40xO1Leq+kXpllzRPuncpC0Phw==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/next/-/next-13.5.6.tgz", + "integrity": "sha512-Y2wTcTbO4WwEsVb4A8VSnOsG1I9ok+h74q0ZdxkwM3EODqrs4pasq7O0iUxbcS9VtWMicG7f3+HAj0r1+NtKSw==", "dependencies": { - "@next/env": "13.1.6", - "@swc/helpers": "0.4.14", + "@next/env": "13.5.6", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", - "postcss": "8.4.14", - "styled-jsx": "5.1.1" + "postcss": "8.4.31", + "styled-jsx": "5.1.1", + "watchpack": "2.4.0" }, "bin": { "next": "dist/bin/next" }, "engines": { - "node": ">=14.6.0" + "node": ">=16.14.0" }, "optionalDependencies": { - "@next/swc-android-arm-eabi": "13.1.6", - "@next/swc-android-arm64": "13.1.6", - "@next/swc-darwin-arm64": "13.1.6", - "@next/swc-darwin-x64": "13.1.6", - "@next/swc-freebsd-x64": "13.1.6", - "@next/swc-linux-arm-gnueabihf": "13.1.6", - "@next/swc-linux-arm64-gnu": "13.1.6", - "@next/swc-linux-arm64-musl": "13.1.6", - "@next/swc-linux-x64-gnu": "13.1.6", - "@next/swc-linux-x64-musl": "13.1.6", - "@next/swc-win32-arm64-msvc": "13.1.6", - "@next/swc-win32-ia32-msvc": "13.1.6", - "@next/swc-win32-x64-msvc": "13.1.6" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^6.0.0 || ^7.0.0", + "@next/swc-darwin-arm64": "13.5.6", + "@next/swc-darwin-x64": "13.5.6", + "@next/swc-linux-arm64-gnu": "13.5.6", + "@next/swc-linux-arm64-musl": "13.5.6", + "@next/swc-linux-x64-gnu": "13.5.6", + "@next/swc-linux-x64-musl": "13.5.6", + "@next/swc-win32-arm64-msvc": "13.5.6", + "@next/swc-win32-ia32-msvc": "13.5.6", + "@next/swc-win32-x64-msvc": "13.5.6" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" }, "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { + "@opentelemetry/api": { "optional": true }, "sass": { @@ -7162,9 +7180,9 @@ } }, "node_modules/next-auth": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.23.1.tgz", - "integrity": "sha512-mL083z8KgRtlrIV6CDca2H1kduWJuK/3pTS0Fe2og15KOm4v2kkLGdSDfc2g+019aEBrJUT0pPW2Xx42ImN1WA==", + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.5.tgz", + "integrity": "sha512-3RafV3XbfIKk6rF6GlLE4/KxjTcuMCifqrmD+98ejFq73SRoj2rmzoca8u764977lH/Q7jo6Xu6yM+Re1Mz/Og==", "dependencies": { "@babel/runtime": "^7.20.13", "@panva/hkdf": "^1.0.2", @@ -7177,7 +7195,7 @@ "uuid": "^8.3.2" }, "peerDependencies": { - "next": "^12.2.5 || ^13", + "next": "^12.2.5 || ^13 || ^14", "nodemailer": "^6.6.5", "react": "^17.0.2 || ^18", "react-dom": "^17.0.2 || ^18" @@ -7247,29 +7265,6 @@ "next": ">=9.0.0" } }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -7733,7 +7728,6 @@ "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -7991,13 +7985,13 @@ "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" }, "node_modules/prisma": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.3.1.tgz", - "integrity": "sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.6.0.tgz", + "integrity": "sha512-EEaccku4ZGshdr2cthYHhf7iyvCcXqwJDvnoQRAJg5ge2Tzpv0e2BaMCp+CbbDUwoVTzwgOap9Zp+d4jFa2O9A==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.3.1" + "@prisma/engines": "5.6.0" }, "bin": { "prisma": "build/index.js" @@ -8805,6 +8799,14 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -9793,7 +9795,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -10397,9 +10398,9 @@ } }, "node_modules/zod": { - "version": "3.22.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz", - "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==", + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index b083b17c..651d723c 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,14 @@ "format": "prettier --write ." }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-brands-svg-icons": "^6.5.1", + "@fortawesome/free-regular-svg-icons": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", "@google-cloud/local-auth": "^2.1.1", "@next-auth/prisma-adapter": "^1.0.7", - "@prisma/client": "^5.3.1", + "@prisma/client": "^5.6.0", "@tanstack/react-query": "^4.35.0", "@trpc/client": "^10.38.2", "@trpc/next": "^10.38.2", @@ -23,8 +28,8 @@ "googleapis": "^120.0.0", "i18next": "^22.4.9", "mimetext": "^3.0.15", - "next": "13.1.6", - "next-auth": "^4.20.1", + "next": "^13.5.6", + "next-auth": "^4.24.5", "next-i18next": "^13.1.5", "next-pwa": "^5.6.0", "qr-scanner": "^1.4.2", @@ -39,7 +44,7 @@ "rehype-slug": "^5.1.0", "remark-toc": "^8.0.1", "superjson": "1.12.2", - "zod": "^3.22.3" + "zod": "^3.20.6" }, "devDependencies": { "@faker-js/faker": "^8.0.2", @@ -56,10 +61,10 @@ "autoprefixer": "^10.4.13", "eslint": "^8.34.0", "eslint-config-next": "13.1.6", - "postcss": "^8.4.31", + "postcss": "^8.4.21", "prettier": "^2.8.4", "prettier-plugin-tailwindcss": "^0.2.2", - "prisma": "^5.3.1", + "prisma": "^5.6.0", "tailwindcss": "^3.2.6", "ts-node": "^10.9.1", "typescript": "^4.9.5" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f1aaf3e3..0f080e16 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -2,193 +2,244 @@ // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { - provider = "prisma-client-js" + provider = "prisma-client-js" } datasource db { - provider = "mysql" - // NOTE: When using postgresql, mysql or sqlserver, uncomment the @db.Text annotations in model Account below - // Further reading: - // https://next-auth.js.org/adapters/prisma#create-the-prisma-schema - // https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string - url = env("DATABASE_URL") - relationMode = "prisma" + provider = "mysql" + // NOTE: When using postgresql, mysql or sqlserver, uncomment the @db.Text annotations in model Account below + // Further reading: + // https://next-auth.js.org/adapters/prisma#create-the-prisma-schema + // https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string + url = env("DATABASE_URL") + relationMode = "prisma" } // Necessary for Next auth model Account { - id String @id @default(cuid()) - userId String - type String - provider String - providerAccountId String - refresh_token String? @db.Text - refresh_token_expires_in Int? - access_token String? @db.Text - ext_expires_in Int? - expires_at Int? - token_type String? - scope String? - id_token String? @db.Text - session_state String? - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@unique([provider, providerAccountId]) - @@index([userId]) -} - -model AuditLog { - id Int @id @default(autoincrement()) - timestamp DateTime @default(now()) - user_id String - author String @default("") - route String - action String - details String? - user User[] - - @@index([user_id]) + id String @id @default(cuid()) + userId String + type String + provider String + providerAccountId String + refresh_token String? @db.Text + refresh_token_expires_in Int? + access_token String? @db.Text + expires_at Int? + token_type String? + scope String? + id_token String? @db.Text + session_state String? + ext_expires_in Int? + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([provider, providerAccountId]) + @@index([userId]) } model Session { - id String @id @default(cuid()) - sessionToken String @unique - userId String - expires DateTime - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - @@index([userId]) + id String @id @default(cuid()) + sessionToken String @unique + userId String + expires DateTime + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@index([userId]) } model User { - id String @id @default(cuid()) - name String? - email String? @unique - emailVerified DateTime? - image String? - passwordHash String? @db.Text - salt String? - role Role @default(HACKER) - accounts Account[] - sessions Session[] - hackerInfo HackerInfo[] - auditLog AuditLog[] + id String @id @default(cuid()) + username String? @map("name") + email String? @unique + profileImage String? @map("image") + role Role @default(HACKER) + accounts Account[] + sessions Session[] + hackerInfo HackerInfo[] + auditLog AuditLog[] + event Event[] } model VerificationToken { - identifier String - token String @unique - expires DateTime + identifier String + token String @unique + expires DateTime - @@unique([identifier, token]) + @@unique([identifier, token]) } model HackerInfo { - id String @id @default(cuid()) @map("submissionID") - preferredLanguage Language @default(EN) - email String - firstName String - lastName String - gender String @default("Prefer not to say") - phoneNumber String - university String? - studyLevel String? - studyProgram String? - graduationYear Int? - attendanceType AttendanceType @default(IN_PERSON) - location String? @map("attendanceLocation") - transportationRequired Boolean @default(false) - dietaryRestrictions String @db.Text - accessibilityRequirements String @db.Text - shirtSize ShirtSize? - emergencyContactName String - emergencyContactRelationship String - emergencyContactPhoneNumber String - numberOfPreviousHackathons Int? - linkGithub String? - linkLinkedin String? - linkPersonalSite String? - linkResume String? @db.Text - lookingForwardTo String? @db.Text - formStartDate DateTime? - formEndDate DateTime? - confirmed Boolean @default(false) - user User? @relation(fields: [userId], references: [id]) - userId String? - unsubscribed Boolean @default(false) - unsubscribeToken String? @unique @default(cuid()) - onlyOnline Boolean @default(false) - acceptanceExpiry DateTime? - walkIn Boolean @default(false) - winner Boolean @default(false) - presenceInfo PresenceInfo? - - @@index([userId]) + id String @id @default(cuid()) @map("submissionID") + preferredLanguage Language @default(EN) + email String + firstName String + lastName String + gender String @default("Prefer not to say") + pronouns String @default("Prefer not to say") + phoneNumber String + university String? + studyLevel String? + studyProgram String? + graduationYear Int? + attendanceType AttendanceType @default(IN_PERSON) + location String? @map("attendanceLocation") + transportationRequired Boolean @default(false) + dietaryRestrictions String @db.Text + accessibilityRequirements String @db.Text + shirtSize ShirtSize? + emergencyContactName String + emergencyContactRelationship String + emergencyContactPhoneNumber String + numberOfPreviousHackathons Int? + linkGithub String? + linkLinkedin String? + linkPersonalSite String? + linkResume String? @db.Text + lookingForwardTo String? @db.Text + formStartDate DateTime? + formEndDate DateTime? + confirmed Boolean @default(false) + userId String? + unsubscribed Boolean @default(false) + unsubscribeToken String? @unique @default(cuid()) + onlyOnline Boolean @default(false) + acceptanceExpiry DateTime? + walkIn Boolean @default(false) + winner Boolean @default(false) + user User? @relation(fields: [userId], references: [id]) + presenceInfo PresenceInfo? + responses Response[] + @@index([userId]) } model PresenceInfo { - id String @id @default(cuid()) - checkedIn Boolean @default(false) - breakfast1 Boolean @default(false) - lunch1 Boolean @default(false) - dinner1 Boolean @default(false) - snacks Boolean @default(false) - snacks2 Boolean @default(false) - redbull Boolean @default(false) - breakfast2 Boolean @default(false) - lunch2 Boolean @default(false) - lunch22 Boolean @default(false) - hackerInfo HackerInfo @relation(fields: [hackerInfoId], references: [id]) - hackerInfoId String @unique + id String @id @default(cuid()) + checkedIn Boolean @default(false) + breakfast1 Boolean @default(false) + lunch1 Boolean @default(false) + dinner1 Boolean @default(false) + snacks Boolean @default(false) + snacks2 Boolean @default(false) + redbull Boolean @default(false) + breakfast2 Boolean @default(false) + lunch2 Boolean @default(false) + lunch22 Boolean @default(false) + hackerInfo HackerInfo @relation(fields: [hackerInfoId], references: [id]) + hackerInfoId String @unique + wieSignUp Boolean @default(false) } model Event { - id String @id @default(cuid()) - start DateTime - end DateTime - name String - type EventType @default(ALL) - host String? - description String @db.Text - room String - image String? - link String? - linkText String? - tiktok String? + id String @id @default(cuid()) + start DateTime + end DateTime + name String + type EventType @default(ALL) + host String? + description String @db.Text + room String + tiktok String? + image String? + link String? + linkText String? + registeredUser User[] + questions Question[] +} + +model Question { + id String @id @default(cuid()) + eventId String + question String @db.Text + event Event @relation(fields: [eventId], references: [id]) + responses Response[] + wordMax Int @default(250) + wordMinimum Int @default(10) +} + +model Response { + id String @id @default(cuid()) + hackerInfoId String + questionId String + question Question@relation(fields: [questionId], references: [id]) + hackerInfo HackerInfo@relation(fields: [hackerInfoId], references: [id]) + response String @db.Text + @@index([hackerInfoId]) + @@index([questionId]) } model Follow { - id String @id @default(cuid()) - email String @unique + id String @id @default(cuid()) + email String @unique +} + +model AuditLog { + id Int @id @default(autoincrement()) + timestamp DateTime @default(now()) + userId String @map("user_id") + author String @default("") + route String + action String + details String? + user User[] + + @@index([userId]) +} + +model Payment { + id String @id @default(cuid()) + companyName String @map("company_name") + repName String @map("reps_name") + amount Int + tier Tiers + logo String + paid String + date DateTime + invoice String +} + +model Link { + id String @id + label String + link String } enum Language { - EN - FR + EN + FR } enum AttendanceType { - IN_PERSON - ONLINE + IN_PERSON + ONLINE } enum ShirtSize { - S - M - L - XL - XXL + S + M + L + XL + XXL } enum Role { - HACKER - ORGANIZER - SPONSOR + HACKER + ORGANIZER + SPONSOR } enum EventType { - ALL - WORKSHOP - SOCIAL - CAREER_FAIR - FOOD + ALL + WORKSHOP + SOCIAL + CAREER_FAIR + FOOD +} + +enum Tiers { + STARTUP + MAYOR + PREMIER + GOVERNOR + PRIME_MINISTER + CUSTOM } diff --git a/prisma/seeders/events.mts b/prisma/seeders/events.mts index f6a2190d..ffa0403d 100644 --- a/prisma/seeders/events.mts +++ b/prisma/seeders/events.mts @@ -1,3 +1,4 @@ +import { faker } from "@faker-js/faker"; import { EventType } from "@prisma/client"; const day1 = "2023-08-8"; diff --git a/prisma/seeders/index.mts b/prisma/seeders/index.mts index c4154200..cd3229c6 100644 --- a/prisma/seeders/index.mts +++ b/prisma/seeders/index.mts @@ -17,7 +17,6 @@ async function main() { console.log("Creating dummy events..."); await insertRecords(prisma.event, events); } - main() .then(async () => { await prisma.$disconnect(); diff --git a/prisma/seeders/users.mts b/prisma/seeders/users.mts index 5555a26d..57850bdd 100644 --- a/prisma/seeders/users.mts +++ b/prisma/seeders/users.mts @@ -1,8 +1,8 @@ import { faker } from "@faker-js/faker"; import { Role, Language, PrismaClient } from "@prisma/client"; -// Generates dummy users -const user = () => { +//generates dummy users +let user = () => { const firstName = faker.person.firstName(); const lastName = faker.person.lastName(); const name = `${firstName} ${lastName}`; @@ -21,23 +21,21 @@ const user = () => { preferredLanguage: Language.EN, phoneNumber, email, - emergencyContactName: "", - emergencyContactRelationship: "", - emergencyContactPhoneNumber: "", - dietaryRestrictions: "", - accessibilityRequirements: "", + emergencyContactName: "null", + emergencyContactRelationship: "null", + emergencyContactPhoneNumber: "null", }, }, }; }; /** - * Generates an array of users + * generates an array of users * @param n number of users to generate * @returns [] array of users */ function generateUsers(n = 10) { - const users = []; + let users = []; for (let i = 0; i < n; i++) { users.push(user()); } diff --git a/prisma/seeders/utils.mts b/prisma/seeders/utils.mts index 2b36efd8..33a393cb 100644 --- a/prisma/seeders/utils.mts +++ b/prisma/seeders/utils.mts @@ -1,13 +1,21 @@ -async function insertRecords(db: any, rows: object[]) { +async function insertRecords(db: iDatabaseTable, rows: object[]) { try { - rows.forEach(row => - db.create({ + rows.map(async row => { + await db.create({ data: row, - }), - ); - } catch (error) { - console.log(error); + }); + }); + } catch (e) { + console.log(e); } } +export interface iDatabaseTable { + findMany(fields: object): any; + findUnique(criteria: object): any; + update(data: object): any; + delete(data: object): any; + create(data: object): any; +} + export { insertRecords }; diff --git a/public/assets/events/wie-hack-background.png b/public/assets/events/wie-hack-background.png new file mode 100644 index 00000000..8a8a7966 Binary files /dev/null and b/public/assets/events/wie-hack-background.png differ diff --git a/public/assets/hackthehill-logo.svg b/public/assets/hackthehill-logo.svg index 52ebea67..2cc4c64d 100644 --- a/public/assets/hackthehill-logo.svg +++ b/public/assets/hackthehill-logo.svg @@ -1 +1,35 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/home.svg b/public/assets/home.svg index 24303b1f..b87d918c 100644 --- a/public/assets/home.svg +++ b/public/assets/home.svg @@ -1 +1,9 @@ - + + + + + + + + + diff --git a/public/assets/maps.svg b/public/assets/maps.svg index 0ffe7e8d..1a5bad6c 100644 --- a/public/assets/maps.svg +++ b/public/assets/maps.svg @@ -1 +1,5 @@ - + + + + + diff --git a/public/assets/resources.svg b/public/assets/resources.svg index d844d096..32adee86 100644 --- a/public/assets/resources.svg +++ b/public/assets/resources.svg @@ -1 +1,4 @@ - + + + + diff --git a/public/assets/schedule.svg b/public/assets/schedule.svg index 25c4b795..c38f0401 100644 --- a/public/assets/schedule.svg +++ b/public/assets/schedule.svg @@ -1 +1,13 @@ - + + + + + + + + + + + + + diff --git a/public/locales/en/common.json b/public/locales/en/common.json index c5aed613..74896a4d 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -4,5 +4,6 @@ "loading": "Loading...", "error": "Error: {{message}}", "contact-us": "Contact us for help", + "unknown-error": "Unknown error", "not-authorized-to-view-this-page": "You are not authorized to view this page." } diff --git a/public/locales/en/index.json b/public/locales/en/index.json index b20a687d..2210caf9 100644 --- a/public/locales/en/index.json +++ b/public/locales/en/index.json @@ -1,5 +1,5 @@ { "welcome": "Welcome to the Hack the Hill's Track the Hack app!", - "explanation": "The event is over now, but we hope to see you next year!", - "get-started": "Get Started" + "get-started": "Get Started", + "description": "The event is over now, but we hope to see you next year!" } diff --git a/public/locales/en/logs.json b/public/locales/en/logs.json new file mode 100644 index 00000000..dcd5019c --- /dev/null +++ b/public/locales/en/logs.json @@ -0,0 +1,7 @@ +{ + "user": "User", + "action": "Action", + "timestamp": "Timestamp", + "details": "Details", + "id": "ID" +} diff --git a/public/locales/en/navbar.json b/public/locales/en/navbar.json index 5ef122b6..e69de29b 100644 --- a/public/locales/en/navbar.json +++ b/public/locales/en/navbar.json @@ -1,13 +0,0 @@ -{ - "home": "Home", - "qr": "QR", - "schedule": "Schedule", - "maps": "Maps", - "resources": "Resources", - "hackers": "Hackers", - "navigation": "Navigation", - "logo": "Logo", - "sign-out": "Sign Out", - "sign-in": "Sign In", - "bottom-navigation": "Bottom Navigation" -} diff --git a/public/locales/en/qr.json b/public/locales/en/qr.json index fe2f50e4..732d6eb3 100644 --- a/public/locales/en/qr.json +++ b/public/locales/en/qr.json @@ -2,6 +2,5 @@ "title": "QR Code", "use-qr": "Show this QR code to organizers to check in", "scan-qr": "Ready to scan a QR code", - "mascot-choco-alt": "Hack the Hill mascot with hot chocolate", - "sign-in-to-access": "You need to sign in to access the QR page." + "mascot-choco-alt": "Hack the Hill mascot with hot chocolate" } diff --git a/public/locales/en/registration.json b/public/locales/en/registration.json new file mode 100644 index 00000000..97209d72 --- /dev/null +++ b/public/locales/en/registration.json @@ -0,0 +1,34 @@ +{ + "title": "Registration", + "subtitle": "Please fill out the following form to register for the event", + "application": "Application", + "submit": "Submit", + "new": "New", + "select": "Select", + "email": "Email", + "firstName": "First Name", + "lastName": "Last Name", + "pronouns": "Pronouns", + "phoneNumber": "Phone Number", + "dietaryRestrictions": "Dietary Restrictions", + "accessibilityRequirements": "Accessibility Requirements", + "emergencyContactName": "Emergency Contact Name", + "emergencyContactRelationship": "Emergency Contact Relationship", + "emergencyContactPhoneNumber": "Emergency Contact Phone Number", + "preferredLanguage": "Preferred Language", + "en": "English", + "fr": "French", + "gender": "Gender", + "university": "University", + "studyLevel": "Study Level", + "studyProgram": "Study Program", + "graduationYear": "Graduation Year", + "location": "City", + "shirtSize": "Shirt Size", + "numberOfPreviousHackathons": "Number of Previous Hackathons", + "linkGithub": "Link to Github", + "linkLinkedin": "Link to LinkedIn", + "linkPersonalSite": "Link to Personal Site", + "invalid-form": "Please fill out all required fields correctly.", + "applicationInstructions" : "Please fill answer the following questions to complete your application." +} diff --git a/public/locales/en/sponsorship-gmail-drafts.json b/public/locales/en/sponsorship-gmail-drafts.json index 92d2b41e..c78ef89b 100644 --- a/public/locales/en/sponsorship-gmail-drafts.json +++ b/public/locales/en/sponsorship-gmail-drafts.json @@ -6,12 +6,5 @@ "company-name": "Company Name", "company-rep-name": "Company Representative's Name", "company-email": "Company Email", - "select-template": "Select Template", - "subject": "Subject", - "custom-template": "Custom Template", - "copy-to-clipboard": "Copy to Clipboard", - "copied-to-clipboard": "Copied to Clipboard", - "create-draft-email": "Create Draft Email", - "created-draft-email": "Created Draft Email", "invalid-form": "Please fill out all required fields correctly." } diff --git a/public/locales/fr/index.json b/public/locales/fr/index.json index 84846327..e0993e57 100644 --- a/public/locales/fr/index.json +++ b/public/locales/fr/index.json @@ -1,5 +1,5 @@ { "welcome": "Bienvenue sur l'application Track the Hack de Hack the Hill !", - "explanation": "L'événement est terminé maintenant, mais nous espérons vous voir l'année prochaine !", - "get-started": "Commencez" + "get-started": "Commencez", + "description": "L'événement est terminé maintenant, mais nous espérons vous voir l'année prochaine !" } diff --git a/public/locales/fr/logs.json b/public/locales/fr/logs.json new file mode 100644 index 00000000..50743426 --- /dev/null +++ b/public/locales/fr/logs.json @@ -0,0 +1,7 @@ +{ + "user": "utilisateur", + "action": "Action", + "timestamp": "Date", + "details": "Détails", + "id": "ID" +} diff --git a/public/locales/fr/navbar.json b/public/locales/fr/navbar.json index f3d31c74..e69de29b 100644 --- a/public/locales/fr/navbar.json +++ b/public/locales/fr/navbar.json @@ -1,13 +0,0 @@ -{ - "home": "Acceuil", - "qr": "QR", - "schedule": "Horaire", - "maps": "Carte", - "resources": "Ressources", - "hackers": "Hackers", - "navigation": "Navigation", - "logo": "Logo", - "sign-out": "Déconnexion", - "sign-in": "Connexion", - "bottom-navigation": "Navigation du bas" -} diff --git a/public/locales/fr/qr.json b/public/locales/fr/qr.json index 1ae0c4cf..65e91281 100644 --- a/public/locales/fr/qr.json +++ b/public/locales/fr/qr.json @@ -2,6 +2,5 @@ "title": "Code QR", "use-qr": "Montrer ce code QR aux organisateurs pour participer", "scan-qr": "Prêt à scanner un code QR", - "mascot-choco-alt": "Mascotte Hack the Hill avec du chocolat chaud", - "sign-in-to-access": "Vous devez vous connecter pour accéder à la page QR." + "mascot-choco-alt": "Mascotte Hack the Hill avec du chocolat chaud" } diff --git a/public/locales/fr/registration.json b/public/locales/fr/registration.json new file mode 100644 index 00000000..987d61f8 --- /dev/null +++ b/public/locales/fr/registration.json @@ -0,0 +1,34 @@ +{ + "title": "Inscription", + "subtitle": "Veuillez remplir le formulaire suivant pour vous inscrire à l'événement", + "application": "Application", + "submit": "Soumettre", + "new": "Nouveau", + "select": "Sélectionner", + "email": "Courriel", + "firstName": "Prénom", + "lastName": "Nom de famille", + "pronouns": "Pronoms", + "phoneNumber": "Numéro de téléphone", + "dietaryRestrictions": "Restrictions alimentaires", + "accessibilityRequirements": "Exigences d'accessibilité", + "emergencyContactName": "Nom du contact d'urgence", + "emergencyContactRelationship": "Relation avec le contact d'urgence", + "emergencyContactPhoneNumber": "Numéro de téléphone du contact d'urgence", + "preferredLanguage": "Langue préférée", + "en": "Anglais", + "fr": "Français", + "gender": "Genre", + "university": "Université", + "studyLevel": "Niveau d'études", + "studyProgram": "Programme d'études", + "graduationYear": "Année de graduation", + "location": "Ville", + "shirtSize": "Taille de chemise", + "numberOfPreviousHackathons": "Nombre de hackathons précédents", + "linkGithub": "Lien vers Github", + "linkLinkedin": "Lien vers LinkedIn", + "linkPersonalSite": "Lien vers le site personnel", + "invalid-form": "Veuillez remplir tous les champs requis correctement.", + "applicationInstructions" : "Veuillez répondre aux questions suivantes pour compléter votre candidature." +} diff --git a/public/locales/fr/sponsorship-gmail-drafts.json b/public/locales/fr/sponsorship-gmail-drafts.json index 1a8f862d..12a64795 100644 --- a/public/locales/fr/sponsorship-gmail-drafts.json +++ b/public/locales/fr/sponsorship-gmail-drafts.json @@ -6,13 +6,5 @@ "company-name": "Nom de l'entreprise", "company-rep-name": "Nom du représentant de l'entreprise", "company-email": "Courriel de l'entreprise", - "select-template": "Sélectionner un modèle", - "subject": "Sujet", - "custom-template": "Modèle personnalisé", - "custom-template-note": "Veuillez noter que toutes les modifications seront perdues si vous changez de modèle ou décochez la case « Personnaliser le modèle ».", - "copy-to-clipboard": "Copier dans le presse-papiers", - "copied-to-clipboard": "Copié dans le presse-papiers", - "create-draft-email": "Créer un brouillon de courriel", - "created-draft-email": "Brouillon de courriel créé", "invalid-form": "Veuillez remplir correctement tous les champs obligatoires." } diff --git a/src/components/Error.tsx b/src/components/Error.tsx index c2b09b5c..3909aff3 100644 --- a/src/components/Error.tsx +++ b/src/components/Error.tsx @@ -18,7 +18,7 @@ const Error = ({ message }: ErrorProps) => { diff --git a/src/components/FormPage.tsx b/src/components/FormPage.tsx index 09b10b1e..1bdc5d25 100644 --- a/src/components/FormPage.tsx +++ b/src/components/FormPage.tsx @@ -36,7 +36,7 @@ const FormPage = ({ children, onSubmit, error, invalid, loading, path, user, tit return ( <> -
+
-

+

Hack the Hill

diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx index 1fc4ba45..923bec5e 100644 --- a/src/components/Loading.tsx +++ b/src/components/Loading.tsx @@ -6,7 +6,7 @@ const Loading = () => { return (
{ - const { t } = useTranslation("navbar"); - const { data: sessionData } = useSession(); - - const hackerId = trpc.users.getHackerId.useQuery( - { id: sessionData?.user?.id ?? "" }, - { enabled: !!sessionData?.user?.id }, - ); - - const role = trpc.users.getRole.useQuery({ id: sessionData?.user?.id ?? "" }, { enabled: !!sessionData?.user?.id }); - - return ( - <> - - {bottom ? : t("home")} - - {sessionData?.user && ((role.data === Role.HACKER && hackerId.data) || role.data === Role.ORGANIZER) && ( - - {bottom ? : t("qr")} - - )} - - {bottom ? ( - - ) : ( - t("schedule") - )} - - - {bottom ? : t("maps")} - - - {bottom ? ( - - ) : ( - t("resources") - )} - - {sessionData?.user && ( - <> - role === Role.ORGANIZER || role === Role.SPONSOR}> - - {bottom ? ( - - ) : ( - t("hackers") - )} - - - - )} - - ); -}; - type NavbarProps = { integrated?: boolean; }; @@ -96,15 +13,14 @@ type NavbarProps = { const Navbar = ({ integrated }: NavbarProps) => { const { t } = useTranslation("navbar"); const { data: sessionData } = useSession(); - return (
+
{ src="/assets/hackthehill-logo.svg" height={64} width={64} - alt={t("logo")} + alt="Home" /> {t("logo")}
@@ -130,10 +46,10 @@ const Navbar = ({ integrated }: NavbarProps) => {
); @@ -141,15 +57,114 @@ const Navbar = ({ integrated }: NavbarProps) => { const BottomMenu = () => { const { t } = useTranslation("navbar"); + const { data: sessionData } = useSession(); + const hackerQuery = trpc.users.getHackerId.useQuery( + { id: sessionData?.user?.id ?? "" }, + { enabled: !!sessionData?.user?.id }, + ); return ( ); }; +const Links = () => { + const { t } = useTranslation("navbar"); + const { data: sessionData } = useSession(); + + const hackerQuery = trpc.users.getHackerId.useQuery( + { id: sessionData?.user?.id ?? "" }, + { enabled: !!sessionData?.user?.id }, + ); + + return ( + <> + + Home + + {sessionData?.user && hackerQuery.data && ( + role === Role.HACKER}> + + QR + + + )} + + Events + + + Maps + + + Resources + + {sessionData?.user && ( + <> + role === Role.ORGANIZER || role === Role.SPONSOR}> + + Hackers + + + role === Role.ORGANIZER}> + + Walk-In + + + + )} + + ); +}; + export { BottomMenu, Navbar }; diff --git a/src/components/PhysicalScanner.tsx b/src/components/PhysicalScanner.tsx deleted file mode 100644 index bc0bef3d..00000000 --- a/src/components/PhysicalScanner.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useState, type FormEvent } from "react"; - -type PhysicalScannerProps = { - onScan: (data: string) => void; -}; - -const PhysicalScanner = (props: PhysicalScannerProps) => { - const [scannedCode, setScannedCode] = useState(""); - - const onSubmit = (event: FormEvent) => { - event.preventDefault(); - props.onScan(scannedCode); - setScannedCode(""); - }; - - const onChange = (event: FormEvent) => { - setScannedCode(event.currentTarget.value); - }; - - return ( - - - - ); -}; - -export default PhysicalScanner; diff --git a/src/components/QRCode.tsx b/src/components/QRCode.tsx index 2c40b4b8..8b569fa8 100644 --- a/src/components/QRCode.tsx +++ b/src/components/QRCode.tsx @@ -55,9 +55,7 @@ const QRCode = ({ setError, id }: QRCodeProps) => { setError?.(true); return ; } - setError?.(false); - return ( { > {isSubmitted ? (
-

+

{t("thank-you-for-confirming-your-attendance")}

-

+

{t("we-look-forward-to-seeing-you")}

) : (
-

+

{t("congratulations-for-your-acceptance", { name: query.data?.firstName ?? "", })} @@ -124,7 +124,7 @@ const Confirm: NextPage = () => {

{query.data?.walkIn === false && (query.data?.onlyOnline ? ( -

+

{t("only-online")}

) : ( @@ -156,7 +156,7 @@ const Confirm: NextPage = () => { value={AttendanceType.IN_PERSON} checked={attendanceType === AttendanceType.IN_PERSON} onChange={handleAttendanceTypeChange} - className="flex h-4 w-4 appearance-none items-center justify-center rounded-full border border-medium bg-transparent text-black after:m-0.5 after:block after:h-full after:w-full after:border-black after:leading-[calc(100%*3/4)] after:checked:content-check" + className="border-medium flex h-4 w-4 appearance-none items-center justify-center rounded-full border bg-transparent text-black after:m-0.5 after:block after:h-full after:w-full after:border-black after:leading-[calc(100%*3/4)] after:checked:content-check" />
+ +
+ {!idsOfEventsUserSignedUpTo?.includes(modalId) ? ( + + ) : ( + + )} +
+

FOLLOW US

+
+ + + + + + + + + + + + +
+

NEED HELP ?

+
+ + Contact the event organiser + +
+
+
+ + + + + ); +}; + +interface ModalProps { + isOpen: boolean; + onClose: () => void; + children: React.ReactNode; +} + +const Modal = ({ isOpen, onClose, children }: ModalProps) => { + const modalClasses = isOpen ? "fixed inset-0 overflow-y-auto flex items-center justify-center" : "hidden"; + + return ( +
+
+
+ {/* Ajoutez max-h-[80vh] pour définir une hauteur maximale de 80% de la hauteur de la vue */} + + {children} +
+
+ ); +}; + +export default Events; diff --git a/src/pages/events/registration.tsx b/src/pages/events/registration.tsx new file mode 100644 index 00000000..2413dd6c --- /dev/null +++ b/src/pages/events/registration.tsx @@ -0,0 +1,335 @@ +import { Role } from "@prisma/client"; +import { signIn, useSession } from "next-auth/react"; +import { useTranslation } from "next-i18next"; +import { serverSideTranslations } from "next-i18next/serverSideTranslations"; +import type { GetStaticProps, NextPage } from "next/types"; +import { useEffect, useState } from "react"; + +import App from "../../components/App"; +import Error from "../../components/Error"; +import OnlyRole from "../../components/OnlyRole"; +import QRCode from "../../components/QRCode"; +import { useRouter } from "next/router"; +import { trpc } from "../../utils/api"; +import { walkInSchema } from "../../utils/common"; +import z from "zod"; +export const getStaticProps: GetStaticProps = async ({ locale }) => { + return { + props: await serverSideTranslations(locale ?? "en", ["common", "registration"]), + }; +}; + +const Registration: NextPage = () => { + const { t } = useTranslation("registration"); + const { data: sessionData } = useSession(); + const id = sessionData?.user?.id; + const router = useRouter(); + const eventId = router.query.eventId as string; + const signUpMutation = trpc.users.signUp.useMutation(); + const questionMutation = trpc.response.createMany.useMutation(); + const mutation = trpc.hackers.walkIn.useMutation(); + const [error, setError] = useState(""); + const [success, setSuccess] = useState(false); + const hackerIdQuery = trpc.users.getHackerId.useQuery({ id: id ?? "" }, { enabled: !!id }); + const applicationQuestions = trpc.question.all.useQuery({eventId: eventId}, { enabled: !!eventId }); + + //Hackers with a hacker info should be re-directed to the events page + // if (hackerIdQuery.data) { + // void router.push("/events"); + // } + + useEffect(() => { + + if(sessionData === null) { + void signIn(); + } + }, [t, sessionData]); + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const data = Object.fromEntries(formData) as Record; + + if (data.preferredLanguage === "en" || data.preferredLanguage === "fr") { + data.preferredLanguage = data.preferredLanguage.toUpperCase(); + } else { + data.preferredLanguage = undefined; + } + + if (typeof data.graduationYear === "string") { + data.graduationYear = parseInt(data.graduationYear); + if (Number.isNaN(data.graduationYear)) { + data.graduationYear = undefined; + } + } + + if (data.shirtSize === "") { + data.shirtSize = undefined; + } + + if (typeof data.numberOfPreviousHackathons === "string") { + data.numberOfPreviousHackathons = parseInt(data.numberOfPreviousHackathons); + if (Number.isNaN(data.numberOfPreviousHackathons)) { + data.numberOfPreviousHackathons = undefined; + } + } + + const applicationParse : Record= {}; + applicationQuestions.data?.map(question => { + applicationParse[question.id] = z.string(); + }); + + const hackerInfoResponses : Record = {} + const applicationResponses : Record = {} + const idsOfApplicationQuestions = applicationQuestions.data?.map(item => item.id); + + Object.entries(data).forEach(([key, value]) => { + if(idsOfApplicationQuestions?.includes(key)) { + applicationResponses[key] = value; + } + else { + hackerInfoResponses[key] = value; + } + }); + const hackerInfoParse = walkInSchema.safeParse(hackerInfoResponses); + const applicationParseResult = z.object(applicationParse).safeParse(applicationResponses); + + + + + if(hackerIdQuery.data) { + if (!applicationParseResult.success) { + setError(t("invalid-form")); + console.error(t("error")); + } else { + questionMutation.mutate({questionIdsToResponses: applicationParseResult.data, hackerInfoId: mutation.data?.id ?? ""}); + //void router.push("/events?eventId=" + eventId); + if (eventId) { + signUpMutation.mutate({ eventId: eventId }); + } + } + } else { + if (!hackerInfoParse.success || !applicationParseResult.success) { + setError(t("invalid-form")); + console.error(t("error")); + } else { + //create and link a hackerInfo + mutation.mutate({...hackerInfoParse.data, userId: id, questionIdsToResponses: applicationParseResult.data}); + console.log(`hello1 ${mutation.data?.id ?? ""}`) + if(!mutation.isError) { + setError(""); + setSuccess(true); + event.currentTarget.reset(); + if (eventId) { + signUpMutation.mutate({ eventId: eventId }); + } + void router.push("/events?eventId=" + eventId); + } + } + } + }; + + const fields = [ + { + name: "preferredLanguage", + type: "select", + options: ["en", "fr"], + required: false, + }, + { + name: "email", + type: "email", + required: true, + }, + { + name: "firstName", + type: "text", + required: true, + }, + { + name: "lastName", + type: "text", + required: true, + }, + { + name: "university", + type: "text", + required: true, + }, + { + name: "location", + type: "text", + required: true, + }, + { + name: "pronouns", + type: "text", + required: true, + }, + { + name: "gender", + type: "text", + required: false, + }, + { + name: "phoneNumber", + type: "tel", + required: true, + }, + { + name: "dietaryRestrictions", + type: "text", + required: false, + }, + { + name: "accessibilityRequirements", + type: "text", + required: false, + }, + { + name: "emergencyContactName", + type: "text", + required: true, + }, + { + name: "emergencyContactRelationship", + type: "text", + required: true, + }, + { + name: "emergencyContactPhoneNumber", + type: "tel", + required: true, + }, + { + name: "studyLevel", + type: "text", + required: false, + }, + { + name: "studyProgram", + type: "text", + required: false, + }, + { + name: "graduationYear", + type: "number", + required: false, + }, + { + name: "shirtSize", + type: "select", + options: ["S", "M", "L", "XL", "XXL"], + required: false, + }, + { + name: "numberOfPreviousHackathons", + type: "number", + required: false, + }, + { + name: "linkGithub", + type: "url", + required: false, + }, + { + name: "linkLinkedin", + type: "url", + required: false, + }, + { + name: "linkPersonalSite", + type: "url", + required: false, + }, + ] as const; + + const patterns = { + tel: "/^+?d{10,15}$/", + url: undefined, + number: "/^d+$/", + email: undefined, + text: undefined, + } as const; + console.log(eventId); + + return ( + +
+
+ {!hackerIdQuery.data && (<> +
+

{t("title")}

+

{t("subtitle")}

+ {fields.map(field => ( +
+ + {field.type === "select" ? ( + + ) : ( + + )} +
+ ))} +
+ )} + +

{t("application")}

+

{t("applicationInstructions")}

+ { + + applicationQuestions.data?.map(question => ( +
+ +