From d711c3f774bb8b271f4aece294ed18ae2b020db4 Mon Sep 17 00:00:00 2001 From: Kiet Phan Date: Tue, 12 Apr 2022 18:40:57 +0700 Subject: [PATCH 1/8] Dockerization --- Dockerfile | 17 ++++++++++++++--- docker-compose.yml | 19 ++++++++++++++++--- package.json | 5 ++++- src/pages/puzzles/map/index.tsx | 8 ++++---- tsconfig.json | 2 +- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index d1f6e11..c93a629 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,22 @@ -FROM node:14 +FROM node:16 WORKDIR . -COPY package*.json . -RUN npm i --production +ARG DATABASE_URL +ARG GOOGLE_CLIENT_ID +ARG GOOGLE_CLIENT_SECRET +ARG AUTH_SECRET +ARG AUTH_URL +ARG NEXT_PUBLIC_BASE_URL +ARG NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN +ARG SENDGRID_API_KEY +ARG SENDGRID_SENDER +COPY package*.json . +RUN npm ci --production +RUN npm i --save-dev typescript postcss ts-node COPY . . +RUN npm run db:generate RUN npm run build EXPOSE 3000 diff --git a/docker-compose.yml b/docker-compose.yml index 8645ab1..0d28e35 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,8 +2,21 @@ version: "3.6" services: app: - build: . - env_file: .env + build: + context: . + dockerfile: Dockerfile + args: + DATABASE_URL: ${DATABASE_URL} + GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID} + GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET} + AUTH_SECRET: ${AUTH_SECRET} + AUTH_URL: ${AUTH_URL} + NEXT_PUBLIC_BASE_URL: ${NEXT_PUBLIC_BASE_URL} + NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN: ${NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN} + SENDGRID_API_KEY: ${SENDGRID_API_KEY} + SENDGRID_SENDER: ${SENDGRID_SENDER} + env_file: .env.production + image: computational_puzzles ports: - "3000:3000" volumes: @@ -17,7 +30,7 @@ services: image: postgres:9.6 volumes: - db_data:/var/lib/postgresql/data - env_file: .env + env_file: .env.production environment: POSTGRES_USER: computational_puzzles POSTGRES_PASSWORD: computational_puzzles # This is used to create development database, please change when migrate to production diff --git a/package.json b/package.json index defb462..118f564 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,10 @@ "lint": "next lint", "test": "jest --runInBand", "prettify": "npx prettier --write src/", - "db:push": "prisma db push" + "db:push": "prisma db push", + "db:generate": "prisma generate", + "migrate:prod": "prisma migrate deploy", + "db:seed": "ts-node prisma/seed/index.ts" }, "dependencies": { "@maptiler/geocoder": "^1.1.0", diff --git a/src/pages/puzzles/map/index.tsx b/src/pages/puzzles/map/index.tsx index 66e868b..30fb7f3 100644 --- a/src/pages/puzzles/map/index.tsx +++ b/src/pages/puzzles/map/index.tsx @@ -73,7 +73,7 @@ const PuzzleMap = ({ puzzleInstances }: PuzzleMapProps) => {
- @@ -88,13 +88,13 @@ const PuzzleMap = ({ puzzleInstances }: PuzzleMapProps) => { userMarker={userMarker} mapCenter={mapCenter} setMapCenter={setMapCenter} - /> + />}
Nearest Puzzles From Map Center:
- @@ -121,7 +121,7 @@ const PuzzleMap = ({ puzzleInstances }: PuzzleMapProps) => { ] }; })} - /> + />}
diff --git a/tsconfig.json b/tsconfig.json index 718b7ef..a2050e9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,7 @@ "strict": false, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, - "module": "esnext", + "module": "commonjs", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, From 842279ba1702fb41c6e3cdca709109956663f9b8 Mon Sep 17 00:00:00 2001 From: Kiet Phan Date: Tue, 19 Apr 2022 19:24:38 +0700 Subject: [PATCH 2/8] + TODO 1: Make sure Difficult values are matched with the db. Solution: Load from prisma/client to use --- package-lock.json | 246 +++++++++--------- package.json | 2 +- prisma/seed/index.ts | 5 +- src/__mocks__/pages/api/auth/index.ts | 2 +- src/__mocks__/pages/api/puzzles/index.ts | 2 +- .../pages/api/puzzles/instances/create.ts | 5 +- .../pages/api/user/update-username.test.ts | 2 +- .../App/DisplayPuzzleInstances/index.tsx | 2 +- src/pages/api/puzzles/instances/create.ts | 3 +- src/pages/puzzles/[instanceId]/index.tsx | 3 +- src/services/getUserByEmail.ts | 2 +- src/services/puzzleInstance.ts | 2 +- src/services/updateUsername.ts | 2 +- .../api/puzzles/instances/puzzleInstance.ts | 2 +- src/types/api/puzzles/puzzle.ts | 2 +- src/utils/puzzles.ts | 2 +- 16 files changed, 144 insertions(+), 140 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53ec6a6..1640ee7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", - "babel-jest": "^27.2.3", + "babel-jest": "^27.5.1", "dotenv": "^14.3.2", "eslint": "^7.32.0", "eslint-config-next": "11.1.2", @@ -1090,23 +1090,23 @@ } }, "node_modules/@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -1195,9 +1195,9 @@ } }, "node_modules/@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -1902,9 +1902,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1915,9 +1915,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -2669,18 +2669,18 @@ "dev": true }, "node_modules/babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dev": true, "dependencies": { - "@jest/transform": "^27.4.5", - "@jest/types": "^27.4.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.4.0", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { @@ -2777,9 +2777,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -2832,12 +2832,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.4.0", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -4863,9 +4863,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/harmony-reflect": { "version": "1.6.2", @@ -6083,21 +6083,21 @@ } }, "node_modules/jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "micromatch": "^4.0.4", "walker": "^1.0.7" }, @@ -6426,9 +6426,9 @@ } }, "node_modules/jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6750,13 +6750,13 @@ } }, "node_modules/jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dev": true, "dependencies": { "@types/node": "*", - "graceful-fs": "^4.2.4" + "graceful-fs": "^4.2.9" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6883,16 +6883,16 @@ } }, "node_modules/jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" }, "engines": { @@ -7157,9 +7157,9 @@ } }, "node_modules/jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "dependencies": { "@types/node": "*", @@ -10802,23 +10802,23 @@ } }, "@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -10882,9 +10882,9 @@ } }, "@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -11348,9 +11348,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -11361,9 +11361,9 @@ } }, "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -11944,18 +11944,18 @@ "dev": true }, "babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dev": true, "requires": { - "@jest/transform": "^27.4.5", - "@jest/types": "^27.4.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.4.0", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "dependencies": { @@ -12024,9 +12024,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -12066,12 +12066,12 @@ } }, "babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.4.0", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -13609,9 +13609,9 @@ } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "harmony-reflect": { "version": "1.6.2", @@ -14496,22 +14496,22 @@ "dev": true }, "jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "micromatch": "^4.0.4", "walker": "^1.0.7" } @@ -14752,9 +14752,9 @@ "requires": {} }, "jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true }, "jest-resolve": { @@ -15004,13 +15004,13 @@ } }, "jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dev": true, "requires": { "@types/node": "*", - "graceful-fs": "^4.2.4" + "graceful-fs": "^4.2.9" } }, "jest-snapshot": { @@ -15106,16 +15106,16 @@ } }, "jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" }, "dependencies": { @@ -15308,9 +15308,9 @@ } }, "jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "requires": { "@types/node": "*", diff --git a/package.json b/package.json index 6dcad7f..b0b64a1 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", - "babel-jest": "^27.2.3", + "babel-jest": "^27.5.1", "dotenv": "^14.3.2", "eslint": "^7.32.0", "eslint-config-next": "11.1.2", diff --git a/prisma/seed/index.ts b/prisma/seed/index.ts index 4c9bf63..b3e2393 100644 --- a/prisma/seed/index.ts +++ b/prisma/seed/index.ts @@ -1,4 +1,5 @@ -import { PrismaClient, Puzzle, PuzzleType } from '@prisma/client'; +import { PrismaClient } from '@prisma/client'; +import type { Puzzle, PuzzleType } from '@prisma/client'; const prisma = new PrismaClient(); @@ -68,7 +69,7 @@ const createPuzzleInstance = (createdPuzzles: Puzzle[]) => { hint: puzzleInstance.hint, longitude: parseFloat(puzzleInstance.longtitude), latitude: parseFloat(puzzleInstance.latitude), - address: puzzleInstance.address, + address: puzzleInstance.address } }); }); diff --git a/src/__mocks__/pages/api/auth/index.ts b/src/__mocks__/pages/api/auth/index.ts index cee877a..dfb828f 100644 --- a/src/__mocks__/pages/api/auth/index.ts +++ b/src/__mocks__/pages/api/auth/index.ts @@ -1,4 +1,4 @@ -import { User } from '@prisma/client'; +import type { User } from '@prisma/client'; import * as faker from 'faker'; import { prisma } from '../../..'; diff --git a/src/__mocks__/pages/api/puzzles/index.ts b/src/__mocks__/pages/api/puzzles/index.ts index 923e091..237ec38 100644 --- a/src/__mocks__/pages/api/puzzles/index.ts +++ b/src/__mocks__/pages/api/puzzles/index.ts @@ -1,4 +1,4 @@ -import { Puzzle, PuzzleInstance, PuzzleType } from '@prisma/client'; +import type { Puzzle, PuzzleInstance, PuzzleType } from '@prisma/client'; import { prisma } from '../../..'; import { diff --git a/src/__mocks__/pages/api/puzzles/instances/create.ts b/src/__mocks__/pages/api/puzzles/instances/create.ts index 083948d..518df6a 100644 --- a/src/__mocks__/pages/api/puzzles/instances/create.ts +++ b/src/__mocks__/pages/api/puzzles/instances/create.ts @@ -2,8 +2,9 @@ import * as faker from 'faker'; import { DIFFICULTY } from '../../../../../types/global'; import { getRandomNumberRange, getRandomString } from '../../../../getRandom'; -// TODO: Ensure this list matches DB's configuration -const DIFFICULTY_LIST = ['EASY', 'MEDIUM', 'HARD']; +import { Difficulty } from '@prisma/client'; + +const DIFFICULTY_LIST = Object.values(Difficulty); export const mockName = (): string => { return faker.random.word() + faker.random.word() + faker.random.word(); diff --git a/src/__tests__/pages/api/user/update-username.test.ts b/src/__tests__/pages/api/user/update-username.test.ts index 04fd81d..7c5ed44 100644 --- a/src/__tests__/pages/api/user/update-username.test.ts +++ b/src/__tests__/pages/api/user/update-username.test.ts @@ -1,5 +1,5 @@ import { NextApiRequest, NextApiResponse } from 'next'; -import { User } from '@prisma/client'; +import type { User } from '@prisma/client'; import { mockEmail, mockPassword, diff --git a/src/components/App/DisplayPuzzleInstances/index.tsx b/src/components/App/DisplayPuzzleInstances/index.tsx index bbae03d..64993db 100644 --- a/src/components/App/DisplayPuzzleInstances/index.tsx +++ b/src/components/App/DisplayPuzzleInstances/index.tsx @@ -3,7 +3,7 @@ import { useState, useEffect } from 'react'; import styles from './DisplayPuzzleInstances.module.scss'; import { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; import { getAllPuzzleInstances } from '../../../services'; -import { PuzzleInstance } from '@prisma/client'; +import type { PuzzleInstance } from '@prisma/client'; import { Button } from '../../Global'; import { QRGenerator } from '../../App'; import toast from 'react-hot-toast'; diff --git a/src/pages/api/puzzles/instances/create.ts b/src/pages/api/puzzles/instances/create.ts index 82e73e8..5b776d7 100644 --- a/src/pages/api/puzzles/instances/create.ts +++ b/src/pages/api/puzzles/instances/create.ts @@ -1,4 +1,5 @@ -import { PrismaClient, PuzzleInstance } from '@prisma/client'; +import { PrismaClient } from '@prisma/client'; +import type { PuzzleInstance } from '@prisma/client'; import { NextApiRequest, NextApiResponse } from 'next'; const prisma = new PrismaClient(); diff --git a/src/pages/puzzles/[instanceId]/index.tsx b/src/pages/puzzles/[instanceId]/index.tsx index d8ce38e..d0c1563 100644 --- a/src/pages/puzzles/[instanceId]/index.tsx +++ b/src/pages/puzzles/[instanceId]/index.tsx @@ -3,7 +3,8 @@ import { GetServerSideProps } from 'next'; import Image from 'next/image'; import { getSession, signIn, useSession } from 'next-auth/react'; import { User } from 'next-auth'; -import { Prisma, Puzzle } from '@prisma/client'; +import { Prisma } from '@prisma/client'; +import type { Puzzle } from '@prisma/client'; import toast from 'react-hot-toast'; import { Button, Difficulty, Navbar } from '../../../components/Global'; import { FeedbackGif, PuzzleInput } from '../../../components/App'; diff --git a/src/services/getUserByEmail.ts b/src/services/getUserByEmail.ts index af35061..8b242b3 100644 --- a/src/services/getUserByEmail.ts +++ b/src/services/getUserByEmail.ts @@ -1,4 +1,4 @@ -import { User } from '@prisma/client'; +import type { User } from '@prisma/client'; import Axios from './axios'; export const getUserByEmail = async (data: { diff --git a/src/services/puzzleInstance.ts b/src/services/puzzleInstance.ts index 42af87e..fa7c4b5 100644 --- a/src/services/puzzleInstance.ts +++ b/src/services/puzzleInstance.ts @@ -1,5 +1,5 @@ import Axios from './axios'; -import { Puzzle, PuzzleInstance } from '@prisma/client'; +import type { Puzzle, PuzzleInstance } from '@prisma/client'; import { User } from 'next-auth'; import { puzzleSubmissionProps } from '../types/api/puzzles/submission'; import { handleServiceError } from '../utils/error'; diff --git a/src/services/updateUsername.ts b/src/services/updateUsername.ts index 9e05ef9..50ff0e0 100644 --- a/src/services/updateUsername.ts +++ b/src/services/updateUsername.ts @@ -1,4 +1,4 @@ -import { User } from '@prisma/client'; +import type { User } from '@prisma/client'; import Axios from './axios'; export const updateUsername = async (data: { diff --git a/src/types/api/puzzles/instances/puzzleInstance.ts b/src/types/api/puzzles/instances/puzzleInstance.ts index 079b123..244fe95 100644 --- a/src/types/api/puzzles/instances/puzzleInstance.ts +++ b/src/types/api/puzzles/instances/puzzleInstance.ts @@ -1,4 +1,4 @@ -import { PuzzleInstance } from '@prisma/client'; +import type { PuzzleInstance } from '@prisma/client'; import { PuzzleCustom } from '../puzzle'; export type PuzzleInstanceCustom = PuzzleInstance & { diff --git a/src/types/api/puzzles/puzzle.ts b/src/types/api/puzzles/puzzle.ts index 7712d4c..32194ea 100644 --- a/src/types/api/puzzles/puzzle.ts +++ b/src/types/api/puzzles/puzzle.ts @@ -1,4 +1,4 @@ -import { Puzzle, PuzzleType } from '@prisma/client'; +import type { Puzzle, PuzzleType } from '@prisma/client'; export type PuzzleCustom = Puzzle & { puzzleType?: PuzzleType; diff --git a/src/utils/puzzles.ts b/src/utils/puzzles.ts index debf2e9..cf74261 100644 --- a/src/utils/puzzles.ts +++ b/src/utils/puzzles.ts @@ -1,4 +1,4 @@ -import { Puzzle } from '@prisma/client'; +import type { Puzzle } from '@prisma/client'; const checkPuzzleAnswer = ( puzzle: Puzzle, From c720ace59411dca59f4f3765b8bde9d72a61b258 Mon Sep 17 00:00:00 2001 From: Kiet Phan Date: Tue, 19 Apr 2022 19:44:46 +0700 Subject: [PATCH 3/8] Add type for all type importing --- prisma/seed/index.ts | 7 +++--- .../pages/api/puzzles/instances/create.ts | 8 +++---- src/__tests__/utils/error.test.ts | 2 +- src/components/App/CardGrid/index.tsx | 2 +- .../App/DisplayPuzzleInstances/index.tsx | 2 +- src/components/App/FeedbackGif/index.tsx | 2 +- src/components/App/MapGeocoder/index.tsx | 2 +- src/components/App/MapRenderer/index.tsx | 2 +- src/components/App/PuzzleGenerate/index.tsx | 2 +- src/components/App/PuzzleInfomation/index.tsx | 2 +- src/components/App/PuzzleInput/index.tsx | 2 +- src/components/Global/Button/index.tsx | 2 +- src/components/Global/Difficulty/index.tsx | 2 +- src/components/Global/Filter/index.tsx | 2 +- src/components/Global/Input/index.tsx | 2 +- .../Global/LogStatusButton/index.tsx | 2 +- src/components/Global/Logo/index.tsx | 2 +- src/components/Global/Navbar/index.tsx | 4 ++-- src/components/Global/PuzzleCard/index.tsx | 5 ++--- src/components/Global/RadioButton/index.tsx | 4 ++-- .../Global/SearchAndFilter/index.tsx | 2 +- src/pages/admin/index.tsx | 4 ++-- src/pages/api/auth/reset-password.ts | 2 +- src/pages/api/auth/signup.ts | 2 +- src/pages/puzzles/[instanceId]/index.tsx | 22 ++++++++++--------- src/pages/puzzles/map/index.tsx | 2 +- src/services/puzzleInstance.ts | 2 +- src/types/global.ts | 2 -- src/utils/difficulty.ts | 4 ++-- src/utils/error.ts | 2 +- 30 files changed, 49 insertions(+), 53 deletions(-) diff --git a/prisma/seed/index.ts b/prisma/seed/index.ts index b3e2393..260a5e1 100644 --- a/prisma/seed/index.ts +++ b/prisma/seed/index.ts @@ -1,10 +1,9 @@ -import { PrismaClient } from '@prisma/client'; +import { PrismaClient, Difficulty } from '@prisma/client'; import type { Puzzle, PuzzleType } from '@prisma/client'; const prisma = new PrismaClient(); import seedData from './seed.json'; -import type { DIFFICULTY } from '../../src/types/global'; const createPuzzleType = () => { const puzzleTypes = seedData.puzzleType; @@ -19,7 +18,7 @@ const createPuzzleType = () => { ); }; -const difficulties: DIFFICULTY[] = ['EASY', 'MEDIUM', 'HARD']; +const difficulties: Difficulty[] = Object.values(Difficulty); const createPuzzle = (createdPuzzleTypes: PuzzleType[]) => { const puzzles = seedData.puzzle; @@ -42,7 +41,7 @@ const createPuzzle = (createdPuzzleTypes: PuzzleType[]) => { id: puzzleType.id } }, - difficulty: puzzle.difficulty as DIFFICULTY, + difficulty: puzzle.difficulty as Difficulty, content: puzzle.content, variables: puzzle.variables, question: puzzle.question, diff --git a/src/__mocks__/pages/api/puzzles/instances/create.ts b/src/__mocks__/pages/api/puzzles/instances/create.ts index 518df6a..c72771b 100644 --- a/src/__mocks__/pages/api/puzzles/instances/create.ts +++ b/src/__mocks__/pages/api/puzzles/instances/create.ts @@ -1,8 +1,6 @@ import * as faker from 'faker'; -import { DIFFICULTY } from '../../../../../types/global'; -import { getRandomNumberRange, getRandomString } from '../../../../getRandom'; - import { Difficulty } from '@prisma/client'; +import { getRandomNumberRange, getRandomString } from '../../../../getRandom'; const DIFFICULTY_LIST = Object.values(Difficulty); @@ -14,10 +12,10 @@ export const mockContent = (): string => { return faker.lorem.paragraph(); }; -export const mockDifficulty = (): DIFFICULTY => { +export const mockDifficulty = (): Difficulty => { return DIFFICULTY_LIST[ Math.floor(Math.random() * DIFFICULTY_LIST.length) - ] as DIFFICULTY; + ] as Difficulty; }; export const mockOfficialAnswer = (): string => { diff --git a/src/__tests__/utils/error.test.ts b/src/__tests__/utils/error.test.ts index 271f7eb..b6fb2f1 100644 --- a/src/__tests__/utils/error.test.ts +++ b/src/__tests__/utils/error.test.ts @@ -1,5 +1,5 @@ import { handleServiceError } from '../../utils/error'; -import { HandledError } from '../../types/error'; +import type { HandledError } from '../../types/error'; describe('HTTP response status', () => { it('is 400', () => { diff --git a/src/components/App/CardGrid/index.tsx b/src/components/App/CardGrid/index.tsx index b9da8fb..960774e 100644 --- a/src/components/App/CardGrid/index.tsx +++ b/src/components/App/CardGrid/index.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { PuzzleCard } from '../../Global'; import styles from './CardGrid.module.scss'; -import { CardProps } from '../../../types/cards'; +import type { CardProps } from '../../../types/cards'; const CardGrid = ({ cardList }: { cardList: CardProps[] }) => { return ( diff --git a/src/components/App/DisplayPuzzleInstances/index.tsx b/src/components/App/DisplayPuzzleInstances/index.tsx index 64993db..27e863e 100644 --- a/src/components/App/DisplayPuzzleInstances/index.tsx +++ b/src/components/App/DisplayPuzzleInstances/index.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { useState, useEffect } from 'react'; import styles from './DisplayPuzzleInstances.module.scss'; -import { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; +import type { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; import { getAllPuzzleInstances } from '../../../services'; import type { PuzzleInstance } from '@prisma/client'; import { Button } from '../../Global'; diff --git a/src/components/App/FeedbackGif/index.tsx b/src/components/App/FeedbackGif/index.tsx index 83a494d..dcc5e28 100644 --- a/src/components/App/FeedbackGif/index.tsx +++ b/src/components/App/FeedbackGif/index.tsx @@ -1,4 +1,4 @@ -import { FeedbackGifProps } from '../../../types/feedbackGif'; +import type { FeedbackGifProps } from '../../../types/feedbackGif'; import Image from 'next/image'; import styles from './FeedbackGif.module.scss'; diff --git a/src/components/App/MapGeocoder/index.tsx b/src/components/App/MapGeocoder/index.tsx index 462252e..f101dcf 100644 --- a/src/components/App/MapGeocoder/index.tsx +++ b/src/components/App/MapGeocoder/index.tsx @@ -3,7 +3,7 @@ import { Geocoder } from '@maptiler/geocoder'; import { Button, Input } from '../../Global'; import mapGeocoderStyles from './MapGeocoder.module.scss'; -import { MapAnchor } from '../../../types/map'; +import type { MapAnchor } from '../../../types/map'; const MAPTILER_ACCESS_TOKEN = process.env.NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN; diff --git a/src/components/App/MapRenderer/index.tsx b/src/components/App/MapRenderer/index.tsx index 80c3b75..a40583e 100644 --- a/src/components/App/MapRenderer/index.tsx +++ b/src/components/App/MapRenderer/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Map, Marker, ZoomControl } from 'pigeon-maps'; import { maptiler } from 'pigeon-maps/providers'; import mapRendererStyles from './MapRenderer.module.scss'; -import { MapAnchor, MapMarker, MapRendererProps } from '../../../types/map'; +import type { MapAnchor, MapMarker, MapRendererProps } from '../../../types/map'; const MAPTILER_ACCESS_TOKEN = process.env.NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN; diff --git a/src/components/App/PuzzleGenerate/index.tsx b/src/components/App/PuzzleGenerate/index.tsx index 1edc4da..030ef52 100644 --- a/src/components/App/PuzzleGenerate/index.tsx +++ b/src/components/App/PuzzleGenerate/index.tsx @@ -7,7 +7,7 @@ import Modal from 'react-modal'; import { Button, Input } from '../../Global'; import { LocationSearchModal } from '..'; import { createPuzzleInstance } from '../../../services'; -import { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; +import type { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; const PuzzleGenerate = ({ puzzlesList, modalIsOpen, setModalIsOpen }) => { const [hint, setHint] = useState(''); diff --git a/src/components/App/PuzzleInfomation/index.tsx b/src/components/App/PuzzleInfomation/index.tsx index 7d8103c..913b73a 100644 --- a/src/components/App/PuzzleInfomation/index.tsx +++ b/src/components/App/PuzzleInfomation/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; +import type { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; import styles from './PuzzleInfomation.module.scss'; const PuzzleInfomation = ({ puzzlesList }: { puzzlesList: PuzzleCustom[] }) => { diff --git a/src/components/App/PuzzleInput/index.tsx b/src/components/App/PuzzleInput/index.tsx index 443b909..bad811d 100644 --- a/src/components/App/PuzzleInput/index.tsx +++ b/src/components/App/PuzzleInput/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { PuzzleInputProps } from '../../../types/puzzle'; +import type { PuzzleInputProps } from '../../../types/puzzle'; import { Input } from '../../Global'; import styles from './PuzzleInput.module.scss'; diff --git a/src/components/Global/Button/index.tsx b/src/components/Global/Button/index.tsx index 0e61350..a155eba 100644 --- a/src/components/Global/Button/index.tsx +++ b/src/components/Global/Button/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import Link from 'next/link'; import styles from './Button.module.scss'; -import { +import type { ArrowDirectionType, ArrowType, ButtonContentProps, diff --git a/src/components/Global/Difficulty/index.tsx b/src/components/Global/Difficulty/index.tsx index cb4e909..9a2a96b 100644 --- a/src/components/Global/Difficulty/index.tsx +++ b/src/components/Global/Difficulty/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { DIFFICULTY } from '../../../types/global'; +import type { Difficulty as DIFFICULTY } from '@prisma/client'; import { difficultySentenceCase } from '../../../utils/difficulty'; import styles from './Difficulty.module.scss'; diff --git a/src/components/Global/Filter/index.tsx b/src/components/Global/Filter/index.tsx index aded5f5..a3e08bc 100644 --- a/src/components/Global/Filter/index.tsx +++ b/src/components/Global/Filter/index.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import RadioButton from '../RadioButton'; import styles from './Filter.module.scss'; -import { FilterProps } from '../../../types/filter'; +import type { FilterProps } from '../../../types/filter'; const Filter = ({ setFilterFields }: FilterProps) => { const [easyChecked, setEasyChecked] = useState(true); diff --git a/src/components/Global/Input/index.tsx b/src/components/Global/Input/index.tsx index 27fd4b0..50947b7 100644 --- a/src/components/Global/Input/index.tsx +++ b/src/components/Global/Input/index.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import styles from './Input.module.scss'; -import { InputProps } from '../../../types/global'; +import type { InputProps } from '../../../types/global'; const Input = ({ type, diff --git a/src/components/Global/LogStatusButton/index.tsx b/src/components/Global/LogStatusButton/index.tsx index a7577aa..b4cfa99 100644 --- a/src/components/Global/LogStatusButton/index.tsx +++ b/src/components/Global/LogStatusButton/index.tsx @@ -1,7 +1,7 @@ import { Button } from '../index'; import { signIn, signOut } from 'next-auth/react'; import React from 'react'; -import { LogStatusButtonProps } from '../../../types/logStatusButton'; +import type { LogStatusButtonProps } from '../../../types/logStatusButton'; const LogStatusButton = ({ status, useLogIn }: LogStatusButtonProps) => { return status === 'authenticated' ? ( diff --git a/src/components/Global/Logo/index.tsx b/src/components/Global/Logo/index.tsx index b81f112..7265383 100644 --- a/src/components/Global/Logo/index.tsx +++ b/src/components/Global/Logo/index.tsx @@ -3,7 +3,7 @@ import Image from 'next/image'; import Link from 'next/link'; import logo from '../../../../public/assets/logo.jpg'; import logoStyles from './Logo.module.scss'; -import { LogoProps } from '../../../types/global'; +import type { LogoProps } from '../../../types/global'; const LogoContent = ({ showMark, showType }: LogoProps) => { return ( diff --git a/src/components/Global/Navbar/index.tsx b/src/components/Global/Navbar/index.tsx index ce453e1..57992cc 100644 --- a/src/components/Global/Navbar/index.tsx +++ b/src/components/Global/Navbar/index.tsx @@ -4,10 +4,10 @@ import styles from './Navbar.module.scss'; import Link from 'next/link'; import Image from 'next/image'; import { useRouter } from 'next/router'; +import { useSession } from 'next-auth/react'; import { Button, Logo, LogStatusButton } from '..'; -import { HeaderProps } from '../../../types/global'; +import type { HeaderProps } from '../../../types/global'; import { isAdmin } from '../../../services'; -import { useSession } from 'next-auth/react'; const Header = ({ profilePicture }: HeaderProps) => { const [activeTab, setActiveTab] = React.useState<0 | 1>(0); diff --git a/src/components/Global/PuzzleCard/index.tsx b/src/components/Global/PuzzleCard/index.tsx index 2480e93..c93fe47 100644 --- a/src/components/Global/PuzzleCard/index.tsx +++ b/src/components/Global/PuzzleCard/index.tsx @@ -1,10 +1,9 @@ import * as React from 'react'; -import { Button } from '../'; -import { Difficulty } from '../'; +import { Button, Difficulty } from '../'; import styles from './PuzzleCard.module.scss'; -import { CardProps } from '../../../types/cards'; +import type { CardProps } from '../../../types/cards'; const PuzzleCard = ({ name, diff --git a/src/components/Global/RadioButton/index.tsx b/src/components/Global/RadioButton/index.tsx index 279c94e..a23c44b 100644 --- a/src/components/Global/RadioButton/index.tsx +++ b/src/components/Global/RadioButton/index.tsx @@ -1,9 +1,9 @@ import React from 'react'; import styles from './RadioButton.module.scss'; import { RadioButtonProps } from '../../../types/radioButton'; -import { DIFFICULTY } from '../../../types/global'; +import type { Difficulty } from '@prisma/client'; -const getLabelColor = (difficulty: DIFFICULTY) => { +const getLabelColor = (difficulty: Difficulty) => { if (difficulty === 'EASY') return styles.easy; if (difficulty === 'MEDIUM') return styles.medium; if (difficulty === 'HARD') return styles.hard; diff --git a/src/components/Global/SearchAndFilter/index.tsx b/src/components/Global/SearchAndFilter/index.tsx index ec5feb9..6d91d2f 100644 --- a/src/components/Global/SearchAndFilter/index.tsx +++ b/src/components/Global/SearchAndFilter/index.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { Filter, Input } from '../index'; import styles from './SearchAndFilter.module.scss'; -import { SearchAndFilterProps } from '../../../types/searchAndFilter'; +import type { SearchAndFilterProps } from '../../../types/searchAndFilter'; const SearchAndFilter = ({ setSearchNFilterVal }: SearchAndFilterProps) => { const [searchText, setSearchText] = useState(''); diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index 7a72b08..847aa02 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -2,14 +2,14 @@ import * as React from 'react'; import styles from '../../styles/pages/admin.module.scss'; import Router from 'next/router'; import { useSession } from 'next-auth/react'; +import { GetServerSideProps } from 'next'; import { DisplayPuzzleInstances, PuzzleGenerate, PuzzleInfomation } from '../../components/App'; +import { Header } from '../../components/Product'; import { getAllPuzzles, isAdmin } from '../../services'; -import { GetServerSideProps } from 'next'; -import { Header } from '../../components/Global'; import type { PuzzleCustom } from '../../types/api/puzzles/puzzle'; const Admin = ({ puzzlesList }: { puzzlesList: PuzzleCustom[] }) => { diff --git a/src/pages/api/auth/reset-password.ts b/src/pages/api/auth/reset-password.ts index 8d95129..306b0dd 100644 --- a/src/pages/api/auth/reset-password.ts +++ b/src/pages/api/auth/reset-password.ts @@ -2,7 +2,7 @@ import { PrismaClient } from '@prisma/client'; import { NextApiRequest, NextApiResponse } from 'next'; import { checkHash, hashFunction } from '../../../utils/password'; -import { resetPasswordProps } from '../../../types/api/auth/reset-password'; +import type { resetPasswordProps } from '../../../types/api/auth/reset-password'; const prisma = new PrismaClient(); diff --git a/src/pages/api/auth/signup.ts b/src/pages/api/auth/signup.ts index 5a68ff3..8a0867b 100644 --- a/src/pages/api/auth/signup.ts +++ b/src/pages/api/auth/signup.ts @@ -2,7 +2,7 @@ import { PrismaAdapter } from '@next-auth/prisma-adapter'; import { PrismaClient } from '@prisma/client'; import { NextApiRequest, NextApiResponse } from 'next'; import { hashFunction } from '../../../utils/password'; -import { signUpData } from '../../../types/api/auth/sign-up'; +import type { signUpData } from '../../../types/api/auth/sign-up'; const prisma = new PrismaClient(); diff --git a/src/pages/puzzles/[instanceId]/index.tsx b/src/pages/puzzles/[instanceId]/index.tsx index d0c1563..582097f 100644 --- a/src/pages/puzzles/[instanceId]/index.tsx +++ b/src/pages/puzzles/[instanceId]/index.tsx @@ -1,21 +1,23 @@ import React, { useState } from 'react'; -import { GetServerSideProps } from 'next'; +import styles from '../../../styles/pages/PuzzlePage.module.scss'; import Image from 'next/image'; -import { getSession, signIn, useSession } from 'next-auth/react'; -import { User } from 'next-auth'; -import { Prisma } from '@prisma/client'; -import type { Puzzle } from '@prisma/client'; +import Router from 'next/router'; import toast from 'react-hot-toast'; + +import { Prisma } from '@prisma/client'; +import { GetServerSideProps } from 'next'; +import { User } from 'next-auth'; +import { getSession, signIn, useSession } from 'next-auth/react'; import { Button, Difficulty, Navbar } from '../../../components/Global'; import { FeedbackGif, PuzzleInput } from '../../../components/App'; import { getPuzzleInstance, submitPuzzleInstance } from '../../../services'; -import { PuzzleInstanceCustom } from '../../../types/api/puzzles/instances/puzzleInstance'; -import styles from '../../../styles/pages/PuzzlePage.module.scss'; -import { HandledError } from '../../../types/error'; import { initializeRandomGifSrc } from '../../../services/feedbackGif'; -import { FeedbackGifList } from '../../../types/feedbackGif'; import { getRandomGifSrc } from '../../../utils/feedbackGif'; -import Router from 'next/router'; + +import type { Puzzle } from '@prisma/client'; +import type { HandledError } from '../../../types/error'; +import type { FeedbackGifList } from '../../../types/feedbackGif'; +import type { PuzzleInstanceCustom } from '../../../types/api/puzzles/instances/puzzleInstance'; const PuzzlePage = ({ puzzleInstance, diff --git a/src/pages/puzzles/map/index.tsx b/src/pages/puzzles/map/index.tsx index 3bd9ede..42d7478 100644 --- a/src/pages/puzzles/map/index.tsx +++ b/src/pages/puzzles/map/index.tsx @@ -4,7 +4,7 @@ import { GetServerSideProps } from 'next'; import puzzleMapStyles from '../../../styles/pages/PuzzleMap.module.scss'; import { Filter, Navbar } from '../../../components/Global'; import { getAllPuzzleInstances } from '../../../services/puzzleInstance'; -import { PuzzleMapProps } from '../../../types/puzzle'; +import type { PuzzleMapProps } from '../../../types/puzzle'; import type { MapAnchor, MapMarker } from '../../../types/map'; const PuzzleMap = ({ puzzleInstances }: PuzzleMapProps) => { diff --git a/src/services/puzzleInstance.ts b/src/services/puzzleInstance.ts index fa7c4b5..7f165b9 100644 --- a/src/services/puzzleInstance.ts +++ b/src/services/puzzleInstance.ts @@ -1,7 +1,7 @@ import Axios from './axios'; import type { Puzzle, PuzzleInstance } from '@prisma/client'; import { User } from 'next-auth'; -import { puzzleSubmissionProps } from '../types/api/puzzles/submission'; +import type { puzzleSubmissionProps } from '../types/api/puzzles/submission'; import { handleServiceError } from '../utils/error'; const getAllPuzzleInstances = async (verbose: boolean = false) => { diff --git a/src/types/global.ts b/src/types/global.ts index 661e9ba..5555b02 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -1,7 +1,5 @@ import { Dispatch, SetStateAction } from 'react'; -export type DIFFICULTY = 'HARD' | 'MEDIUM' | 'EASY'; - export type HeaderProps = { profilePicture?: string; }; diff --git a/src/utils/difficulty.ts b/src/utils/difficulty.ts index 5c71548..63f446f 100644 --- a/src/utils/difficulty.ts +++ b/src/utils/difficulty.ts @@ -1,6 +1,6 @@ -import { DIFFICULTY } from '../types/global'; +import { Difficulty } from "@prisma/client"; -const difficultySentenceCase = (difficulty: DIFFICULTY) => { +const difficultySentenceCase = (difficulty: Difficulty) => { return difficulty.charAt(0).toUpperCase() + difficulty.slice(1).toLowerCase(); }; diff --git a/src/utils/error.ts b/src/utils/error.ts index ca60ee9..0838f58 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -1,4 +1,4 @@ -import { HandledError } from '../types/error'; +import type { HandledError } from '../types/error'; const handleServiceError = (status, message?) => { if (status === 400) { From f8e75214c443665c4008204dc114cd5681c543b1 Mon Sep 17 00:00:00 2001 From: Kiet Phan Date: Tue, 19 Apr 2022 19:54:47 +0700 Subject: [PATCH 4/8] Prettify --- src/components/App/MapRenderer/index.tsx | 6 +- .../Global/LogStatusButton/index.tsx | 2 +- src/pages/puzzles/map/index.tsx | 92 ++++++++++--------- src/utils/difficulty.ts | 2 +- 4 files changed, 55 insertions(+), 47 deletions(-) diff --git a/src/components/App/MapRenderer/index.tsx b/src/components/App/MapRenderer/index.tsx index a40583e..3127847 100644 --- a/src/components/App/MapRenderer/index.tsx +++ b/src/components/App/MapRenderer/index.tsx @@ -2,7 +2,11 @@ import React from 'react'; import { Map, Marker, ZoomControl } from 'pigeon-maps'; import { maptiler } from 'pigeon-maps/providers'; import mapRendererStyles from './MapRenderer.module.scss'; -import type { MapAnchor, MapMarker, MapRendererProps } from '../../../types/map'; +import type { + MapAnchor, + MapMarker, + MapRendererProps +} from '../../../types/map'; const MAPTILER_ACCESS_TOKEN = process.env.NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN; diff --git a/src/components/Global/LogStatusButton/index.tsx b/src/components/Global/LogStatusButton/index.tsx index b4cfa99..a3499c7 100644 --- a/src/components/Global/LogStatusButton/index.tsx +++ b/src/components/Global/LogStatusButton/index.tsx @@ -1,6 +1,6 @@ -import { Button } from '../index'; import { signIn, signOut } from 'next-auth/react'; import React from 'react'; +import { Button } from '..'; import type { LogStatusButtonProps } from '../../../types/logStatusButton'; const LogStatusButton = ({ status, useLogIn }: LogStatusButtonProps) => { diff --git a/src/pages/puzzles/map/index.tsx b/src/pages/puzzles/map/index.tsx index 42d7478..d89a7e7 100644 --- a/src/pages/puzzles/map/index.tsx +++ b/src/pages/puzzles/map/index.tsx @@ -73,55 +73,59 @@ const PuzzleMap = ({ puzzleInstances }: PuzzleMapProps) => {
- {puzzleInstances && - difficultySelected[instance.puzzle.difficulty] === true - ) - .map(instance => { - return { - anchor: [instance.latitude, instance.longitude], - zoom: 16 - }; - })} - userMarker={userMarker} - mapCenter={mapCenter} - setMapCenter={setMapCenter} - />} + {puzzleInstances && ( + + difficultySelected[instance.puzzle.difficulty] === true + ) + .map(instance => { + return { + anchor: [instance.latitude, instance.longitude], + zoom: 16 + }; + })} + userMarker={userMarker} + mapCenter={mapCenter} + setMapCenter={setMapCenter} + /> + )}
Nearest Puzzles From Map Center:
- {puzzleInstances && - difficultySelected[instance.puzzle.difficulty] === true - ) - .map((instance, index) => { - return { - ...instance.puzzle, - content: [ - `Find at: ${instance.address}`, - `Hint: ${instance.hint}` - ], - buttonActions: [ - { - text: 'Solve Online', - style: 'primary', - link: `/puzzles/${instance.id}` - }, - { - text: 'View On Map', - style: 'secondary', - action: () => setMapCenterFromInstanceIndex(index) - } - ] - }; - })} - />} + {puzzleInstances && ( + + difficultySelected[instance.puzzle.difficulty] === true + ) + .map((instance, index) => { + return { + ...instance.puzzle, + content: [ + `Find at: ${instance.address}`, + `Hint: ${instance.hint}` + ], + buttonActions: [ + { + text: 'Solve Online', + style: 'primary', + link: `/puzzles/${instance.id}` + }, + { + text: 'View On Map', + style: 'secondary', + action: () => setMapCenterFromInstanceIndex(index) + } + ] + }; + })} + /> + )}
diff --git a/src/utils/difficulty.ts b/src/utils/difficulty.ts index 63f446f..06558c0 100644 --- a/src/utils/difficulty.ts +++ b/src/utils/difficulty.ts @@ -1,4 +1,4 @@ -import { Difficulty } from "@prisma/client"; +import { Difficulty } from '@prisma/client'; const difficultySentenceCase = (difficulty: Difficulty) => { return difficulty.charAt(0).toUpperCase() + difficulty.slice(1).toLowerCase(); From 4bbbc64a52ddc8551ebc53198a5a77a2e0c4cf8f Mon Sep 17 00:00:00 2001 From: Kiet Phan Date: Tue, 19 Apr 2022 20:11:13 +0700 Subject: [PATCH 5/8] Fix hash functions structure --- src/utils/password.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/utils/password.ts b/src/utils/password.ts index 399551f..e9a36dd 100644 --- a/src/utils/password.ts +++ b/src/utils/password.ts @@ -1,19 +1,21 @@ import argon2 from 'argon2'; -const hashFunction = (secret: string) => { - try { - return argon2.hash(secret, { type: argon2.argon2id }); - } catch (err) { - throw err; - } +const hashFunction = (secret: string): Promise => { + return new Promise((resolve, reject) => { + argon2 + .hash(secret, { type: argon2.argon2id }) + .then(hash => resolve(hash)) + .catch(err => reject(err)); + }); }; -const checkHash = (secret: string, hashValue: string) => { - try { - return argon2.verify(hashValue, secret); - } catch (err) { - throw err; - } +const checkHash = (secret: string, hashValue: string): Promise => { + return new Promise((resolve, _reject) => { + argon2 + .verify(hashValue, secret) + .then(res => resolve(res)) + .catch(() => resolve(false)); + }); }; export { hashFunction, checkHash }; From 2d638cf9124b2729f341c8f278aa0142d10706a2 Mon Sep 17 00:00:00 2001 From: Kiet Phan Date: Tue, 19 Apr 2022 20:27:29 +0700 Subject: [PATCH 6/8] Use regexp to convert str to bool --- src/pages/api/puzzles/instances/[instanceId]/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/api/puzzles/instances/[instanceId]/index.ts b/src/pages/api/puzzles/instances/[instanceId]/index.ts index 86ac7e0..00690de 100644 --- a/src/pages/api/puzzles/instances/[instanceId]/index.ts +++ b/src/pages/api/puzzles/instances/[instanceId]/index.ts @@ -12,7 +12,7 @@ const getPuzzleInstanceHandler = async ( verbose: string; }; - const verboseBool = verbose.toLowerCase() === 'true'; // TODO: seems weak + const verboseBool = (/true/i).test(verbose.toLowerCase()); if (!instanceId) { return res.status(400).json({ From 922657b1bb842e8f6cb2f52f35d79b46368f820c Mon Sep 17 00:00:00 2001 From: Kiet Phan Date: Tue, 3 May 2022 13:56:50 +0700 Subject: [PATCH 7/8] Calculate success rate --- Dockerfile | 1 + docker-compose.yml | 1 + package-lock.json | 2 +- package.json | 2 +- src/components/App/PuzzleInfomation/index.tsx | 39 ++++++++++++++++++- src/components/Global/Navbar/index.tsx | 2 +- src/pages/api/puzzles/{[id].tsx => [id].ts} | 0 src/pages/api/puzzles/{index.tsx => index.ts} | 0 src/pages/api/submissions/index.ts | 20 ++++++++++ src/pages/auth/login/index.tsx | 3 +- src/pages/auth/profile/index.tsx | 3 +- src/services/index.ts | 28 ++++--------- src/services/submissions.ts | 16 ++++++++ src/types/cards.ts | 4 +- src/types/radioButton.ts | 4 +- 15 files changed, 94 insertions(+), 31 deletions(-) rename src/pages/api/puzzles/{[id].tsx => [id].ts} (100%) rename src/pages/api/puzzles/{index.tsx => index.ts} (100%) create mode 100644 src/pages/api/submissions/index.ts create mode 100644 src/services/submissions.ts diff --git a/Dockerfile b/Dockerfile index c93a629..613e593 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,7 @@ FROM node:16 WORKDIR . +ARG NODE_ENV ARG DATABASE_URL ARG GOOGLE_CLIENT_ID ARG GOOGLE_CLIENT_SECRET diff --git a/docker-compose.yml b/docker-compose.yml index 0d28e35..6ea9f56 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,6 +6,7 @@ services: context: . dockerfile: Dockerfile args: + NODE_ENV: ${NODE_ENV} DATABASE_URL: ${DATABASE_URL} GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID} GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET} diff --git a/package-lock.json b/package-lock.json index 1640ee7..4277dcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@next-auth/prisma-adapter": "^0.5.2-next.19", "@prisma/client": "^3.6.0", "@types/react": "^17.0.27", - "argon2": "^0.28.3", + "argon2": "^0.28.5", "axios": "^0.24.0", "babel-plugin-superjson-next": "^0.4.2", "next": "^12.0.7", diff --git a/package.json b/package.json index b0b64a1..e61f545 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@next-auth/prisma-adapter": "^0.5.2-next.19", "@prisma/client": "^3.6.0", "@types/react": "^17.0.27", - "argon2": "^0.28.3", + "argon2": "^0.28.5", "axios": "^0.24.0", "babel-plugin-superjson-next": "^0.4.2", "next": "^12.0.7", diff --git a/src/components/App/PuzzleInfomation/index.tsx b/src/components/App/PuzzleInfomation/index.tsx index 913b73a..8d00329 100644 --- a/src/components/App/PuzzleInfomation/index.tsx +++ b/src/components/App/PuzzleInfomation/index.tsx @@ -1,8 +1,44 @@ import * as React from 'react'; +import type { PuzzleInstance, Submission } from '@prisma/client'; import type { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; import styles from './PuzzleInfomation.module.scss'; +import { getAllPuzzleInstances, getAllSubmissions } from '../../../services'; const PuzzleInfomation = ({ puzzlesList }: { puzzlesList: PuzzleCustom[] }) => { + const allPuzzleInstances = React.useRef([]); + const allSubmissions = React.useRef([]); + + // TODO: apply SWR + React.useEffect(() => { + getAllPuzzleInstances().then((res: PuzzleInstance[]) => { + allPuzzleInstances.current = res; + }); + getAllSubmissions().then((res: Submission[]) => { + allSubmissions.current = res; + }); + }, []); + + + const calculateSuccessRate = (puzzle: PuzzleCustom) => { + const puzzleId = puzzle.id; + const puzzleAnswer = puzzle.variables['answer']; + const puzzleInstances = allPuzzleInstances.current; + const submissions = allSubmissions.current; + + const filteredPuzzleInstances = puzzleInstances.filter((instance) => instance.puzzleId === puzzleId); + let countSuccess = 0; + let totalLength = 0; + filteredPuzzleInstances.forEach((puzzleInstance) => { + const filteredSubmissions = submissions.filter((submission) => submission.puzzleInstanceId === puzzleInstance.id); + totalLength += filteredSubmissions.length; + countSuccess += filteredSubmissions.filter((submission) => submission.isCorrect).length; + }); + if (totalLength === 0) { + return 'No submission recorded'; + } + return `${countSuccess / totalLength}`; + } + return (

Puzzle Infomation

@@ -20,8 +56,7 @@ const PuzzleInfomation = ({ puzzlesList }: { puzzlesList: PuzzleCustom[] }) => {
{puzzle.name}
{puzzle.difficulty}
- {/* TODO: Calculate success Rate */} - N/A + {calculateSuccessRate(puzzle)}
{/* TODO: Implement Age */} diff --git a/src/components/Global/Navbar/index.tsx b/src/components/Global/Navbar/index.tsx index 57992cc..b725996 100644 --- a/src/components/Global/Navbar/index.tsx +++ b/src/components/Global/Navbar/index.tsx @@ -48,7 +48,7 @@ const Header = ({ profilePicture }: HeaderProps) => {
{status !== 'authenticated' ? (
- +
) : (
diff --git a/src/pages/api/puzzles/[id].tsx b/src/pages/api/puzzles/[id].ts similarity index 100% rename from src/pages/api/puzzles/[id].tsx rename to src/pages/api/puzzles/[id].ts diff --git a/src/pages/api/puzzles/index.tsx b/src/pages/api/puzzles/index.ts similarity index 100% rename from src/pages/api/puzzles/index.tsx rename to src/pages/api/puzzles/index.ts diff --git a/src/pages/api/submissions/index.ts b/src/pages/api/submissions/index.ts new file mode 100644 index 0000000..c5c33d8 --- /dev/null +++ b/src/pages/api/submissions/index.ts @@ -0,0 +1,20 @@ +import { PrismaClient } from '@prisma/client'; +import { NextApiRequest, NextApiResponse } from 'next'; + +const prisma = new PrismaClient(); + +const listAllSubmissions = async ( + req: NextApiRequest, + res: NextApiResponse +) => { + try { + const puzzles = await prisma.submission.findMany(); + return res.status(200).json(puzzles); + } catch (error) { + return res.status(500).json({ + message: error.message + }); + } +}; + +export default listAllSubmissions; diff --git a/src/pages/auth/login/index.tsx b/src/pages/auth/login/index.tsx index e7c4475..d2b89fd 100644 --- a/src/pages/auth/login/index.tsx +++ b/src/pages/auth/login/index.tsx @@ -17,6 +17,7 @@ export default function LoginPage({ providers, csrfToken }) { const loginWithGoogle = () => { signIn('google').then(r => { // TODO: save session into db (?) + console.log(r); console.log('Signed in with Google'); }); }; @@ -53,7 +54,7 @@ export default function LoginPage({ providers, csrfToken }) { style={'primary'} content={'Log In'} type={'submit'} - onClick={() => {}} + onClick={() => { }} />
) : ( <> - {validAdmin && + {NavContent(true)} -
+ ); }; diff --git a/src/pages/api/puzzles/instances/[instanceId]/index.ts b/src/pages/api/puzzles/instances/[instanceId]/index.ts index 00690de..6d4aeb4 100644 --- a/src/pages/api/puzzles/instances/[instanceId]/index.ts +++ b/src/pages/api/puzzles/instances/[instanceId]/index.ts @@ -12,7 +12,7 @@ const getPuzzleInstanceHandler = async ( verbose: string; }; - const verboseBool = (/true/i).test(verbose.toLowerCase()); + const verboseBool = /true/i.test(verbose.toLowerCase()); if (!instanceId) { return res.status(400).json({ diff --git a/src/pages/auth/login/index.tsx b/src/pages/auth/login/index.tsx index d2b89fd..35ca324 100644 --- a/src/pages/auth/login/index.tsx +++ b/src/pages/auth/login/index.tsx @@ -54,7 +54,7 @@ export default function LoginPage({ providers, csrfToken }) { style={'primary'} content={'Log In'} type={'submit'} - onClick={() => { }} + onClick={() => {}} />