From 5ce7d5a91db38eaa0048bb09f388961c0cddf7cb Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 22 Aug 2024 01:51:41 -0400 Subject: [PATCH 01/18] stuff --- src/middleware.ts | 43 +++++++++++++++++++++++++++++++++++ src/utils/getCurrentSprint.ts | 4 +--- 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/middleware.ts diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 00000000..2ffaa5e2 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,43 @@ +import { NextResponse } from "next/server"; +import type { NextRequest } from "next/server"; +import { getRefreshToken } from "./utils/getCookie"; + +export async function middleware(request: NextRequest) { + console.log(request.cookies.getAll()); + if (request.cookies.has("refresh_token")) { + if (request.cookies.has("access_token")) { + return NextResponse.next(); + } + const token = getRefreshToken()!; + const res = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/api/v1/auth/refresh`, + { + method: "POST", + headers: { + Cookie: token, + }, + }, + ); + + console.log(res.headers.getSetCookie()); + + // if (!res.ok) { + // throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + // } + + // const accessToken = res.headers.getSetCookie()[0].split("access_token=")[1]; + // const accessTokenValue = accessToken.split("; ")[0]; + // const accessTokenMaxAge = accessToken.split("; ")[1].split("=")[1]; + // const response = NextResponse.next(); + // response.cookies.set({ + // name: "access_token", + // value: accessTokenValue, + // httpOnly: true, + // maxAge: +accessTokenMaxAge, + // path: "/", + // secure: true, + // }); + // return response; + } + return NextResponse.next(); +} diff --git a/src/utils/getCurrentSprint.ts b/src/utils/getCurrentSprint.ts index 2ea96c1d..746451b7 100644 --- a/src/utils/getCurrentSprint.ts +++ b/src/utils/getCurrentSprint.ts @@ -3,9 +3,7 @@ import { isWithinInterval } from "date-fns"; import { type Sprint } from "@/store/features/sprint/sprintSlice"; export const currentDate = - process.env.NODE_ENV === "development" - ? new Date(2024, 5, 10, 12) - : new Date(); + process.env.NODE_ENV === "development" ? new Date(2024, 5, 10) : new Date(); export function getCurrentSprint(sprints: Sprint[]) { const currentSprint = sprints.find((sprint) => From 1505fa7a81fc87d25289ee70b92ac70866494a65 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 22 Aug 2024 04:30:00 -0400 Subject: [PATCH 02/18] still issue with refreshing issue before executing server action --- src/middleware.ts | 56 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/src/middleware.ts b/src/middleware.ts index 2ffaa5e2..1d18ce64 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -3,7 +3,6 @@ import type { NextRequest } from "next/server"; import { getRefreshToken } from "./utils/getCookie"; export async function middleware(request: NextRequest) { - console.log(request.cookies.getAll()); if (request.cookies.has("refresh_token")) { if (request.cookies.has("access_token")) { return NextResponse.next(); @@ -16,28 +15,49 @@ export async function middleware(request: NextRequest) { headers: { Cookie: token, }, + credentials: "include", + cache: "no-store", }, ); - console.log(res.headers.getSetCookie()); + if (!res.ok) { + throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + } + + const accessToken = res.headers.getSetCookie()[0].split("access_token=")[1]; + const refreshToken = res.headers + .getSetCookie()[0] + .split(";") + .slice(5) + .join("") + .split(",") + .slice(1) + .join(""); + const accessTokenValue = accessToken.split("; ")[0]; + const accessTokenMaxAge = accessToken.split("; ")[1].split("=")[1]; + const refreshTokenValue = refreshToken.match(/refresh_token=([^ ]+)/)![1]; + const refreshTokenMaxAge = refreshToken.match(/Max-Age=(\d+)/)![1]; + + const response = NextResponse.next(); - // if (!res.ok) { - // throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); - // } + response.cookies.set({ + name: "access_token", + value: accessTokenValue, + httpOnly: true, + maxAge: +accessTokenMaxAge, + path: "/", + secure: true, + }); - // const accessToken = res.headers.getSetCookie()[0].split("access_token=")[1]; - // const accessTokenValue = accessToken.split("; ")[0]; - // const accessTokenMaxAge = accessToken.split("; ")[1].split("=")[1]; - // const response = NextResponse.next(); - // response.cookies.set({ - // name: "access_token", - // value: accessTokenValue, - // httpOnly: true, - // maxAge: +accessTokenMaxAge, - // path: "/", - // secure: true, - // }); - // return response; + response.cookies.set({ + name: "refresh_token", + value: refreshTokenValue, + httpOnly: true, + maxAge: +refreshTokenMaxAge, + path: "/", + secure: true, + }); + return response; } return NextResponse.next(); } From bfa064c1e7fee01698bd08efce646ba57d75c158 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 22 Aug 2024 05:22:37 -0400 Subject: [PATCH 03/18] upgrade nextjs version --- package.json | 8 +- .../features/components/AddFeaturesInput.tsx | 21 ++ yarn.lock | 305 +++++++++++------- 3 files changed, 218 insertions(+), 116 deletions(-) diff --git a/package.json b/package.json index 2964c5e2..d9a0440c 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,11 @@ "date-fns-tz": "^3.1.3", "framer-motion": "^10.16.4", "lottie-react": "^2.4.0", - "next": "^14.0.3", + "next": "^14.2.6", "next-themes": "^0.2.1", - "react": "^18.2.0", + "react": "^18.3.1", "react-datepicker": "^6.1.0", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-hook-form": "^7.46.2", "react-redux": "^8.1.2", "redux-persist": "^6.0.0", @@ -58,7 +58,7 @@ "autoprefixer": "10.4.14", "cypress": "^12.17.3", "eslint": "8.46.0", - "eslint-config-next": "^14.0.3", + "eslint-config-next": "^14.2.6", "eslint-config-prettier": "^8.10.0", "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-import": "^2.28.0", diff --git a/src/app/(main)/my-voyage/[teamId]/features/components/AddFeaturesInput.tsx b/src/app/(main)/my-voyage/[teamId]/features/components/AddFeaturesInput.tsx index 0a71bc7b..778a461f 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/components/AddFeaturesInput.tsx +++ b/src/app/(main)/my-voyage/[teamId]/features/components/AddFeaturesInput.tsx @@ -75,6 +75,27 @@ export default function AddFeaturesInput({ featureCategoryId: id, }); + // if (error) { + // const unauthorized = error.message.split(" ")[2]; + + // if (unauthorized) { + // setTimeout(() => { + // void (async () => { + // await addFeatureAction({ + // teamId, + // description, + // featureCategoryId: id, + // }); + // })(); + // }, 1); + // } else { + // console.log("asd"); + // dispatch( + // onOpenModal({ type: "error", content: { message: error.message } }), + // ); + // } + // } + if (error) { dispatch( onOpenModal({ type: "error", content: { message: error.message } }), diff --git a/yarn.lock b/yarn.lock index 6f51f2de..5560cb17 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2395,19 +2395,19 @@ __metadata: languageName: node linkType: hard -"@next/env@npm:14.0.4": - version: 14.0.4 - resolution: "@next/env@npm:14.0.4" - checksum: 59b893d30aea0556379a24f6e4eac830677feb149bd8416b72383ea2600ce194fa22a79b2dd86e0b295c4a8f0702e461f48edaff1ac9173eddef42a4cce7fd98 +"@next/env@npm:14.2.6": + version: 14.2.6 + resolution: "@next/env@npm:14.2.6" + checksum: 9217847e1beb087d4adf25052337712d29150ff7f29e31616dd059154a319c9a8170c3a6d6d273b7adadf568cc604a5c2d0379a15aa3c149c0f78441a514c31c languageName: node linkType: hard -"@next/eslint-plugin-next@npm:14.0.4": - version: 14.0.4 - resolution: "@next/eslint-plugin-next@npm:14.0.4" +"@next/eslint-plugin-next@npm:14.2.6": + version: 14.2.6 + resolution: "@next/eslint-plugin-next@npm:14.2.6" dependencies: - glob: "npm:7.1.7" - checksum: 0e93cb704efdedbe20978c4ffa4856f818cebd91255db859bd88ff1b1f206e92ee61a22b047db87b32cd2f544e3ee0e31ac41f877e1c9a0a7a3b6096513f3376 + glob: "npm:10.3.10" + checksum: 52ca55d98bb72a3bccaa08859036d312bc4936be00923bd8c6399472928e6d2b295f4e2f5f94bec30c8b9274f02bb170ee272b1242ca6cad3ae3d1b4a0ceb53e languageName: node linkType: hard @@ -2420,65 +2420,65 @@ __metadata: languageName: node linkType: hard -"@next/swc-darwin-arm64@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-darwin-arm64@npm:14.0.4" +"@next/swc-darwin-arm64@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-darwin-arm64@npm:14.2.6" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@next/swc-darwin-x64@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-darwin-x64@npm:14.0.4" +"@next/swc-darwin-x64@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-darwin-x64@npm:14.2.6" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@next/swc-linux-arm64-gnu@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-linux-arm64-gnu@npm:14.0.4" +"@next/swc-linux-arm64-gnu@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-linux-arm64-gnu@npm:14.2.6" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-arm64-musl@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-linux-arm64-musl@npm:14.0.4" +"@next/swc-linux-arm64-musl@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-linux-arm64-musl@npm:14.2.6" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@next/swc-linux-x64-gnu@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-linux-x64-gnu@npm:14.0.4" +"@next/swc-linux-x64-gnu@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-linux-x64-gnu@npm:14.2.6" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-x64-musl@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-linux-x64-musl@npm:14.0.4" +"@next/swc-linux-x64-musl@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-linux-x64-musl@npm:14.2.6" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@next/swc-win32-arm64-msvc@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-win32-arm64-msvc@npm:14.0.4" +"@next/swc-win32-arm64-msvc@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-win32-arm64-msvc@npm:14.2.6" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@next/swc-win32-ia32-msvc@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-win32-ia32-msvc@npm:14.0.4" +"@next/swc-win32-ia32-msvc@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-win32-ia32-msvc@npm:14.2.6" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@next/swc-win32-x64-msvc@npm:14.0.4": - version: 14.0.4 - resolution: "@next/swc-win32-x64-msvc@npm:14.0.4" +"@next/swc-win32-x64-msvc@npm:14.2.6": + version: 14.2.6 + resolution: "@next/swc-win32-x64-msvc@npm:14.2.6" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4236,12 +4236,20 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:0.5.2": - version: 0.5.2 - resolution: "@swc/helpers@npm:0.5.2" +"@swc/counter@npm:^0.1.3": + version: 0.1.3 + resolution: "@swc/counter@npm:0.1.3" + checksum: 8424f60f6bf8694cfd2a9bca45845bce29f26105cda8cf19cdb9fd3e78dc6338699e4db77a89ae449260bafa1cc6bec307e81e7fb96dbf7dcfce0eea55151356 + languageName: node + linkType: hard + +"@swc/helpers@npm:0.5.5": + version: 0.5.5 + resolution: "@swc/helpers@npm:0.5.5" dependencies: + "@swc/counter": "npm:^0.1.3" tslib: "npm:^2.4.0" - checksum: b6fa49bcf6c00571d0eb7837b163f8609960d4d77538160585e27ed167361e9776bd6e5eb9646ffac2fb4d43c58df9ca50dab9d96ab097e6591bc82a75fd1164 + checksum: 21a9b9cfe7e00865f9c9f3eb4c1cc5b397143464f7abee76a2c5366e591e06b0155b5aac93fe8269ef8d548df253f6fd931e9ddfc0fd12efd405f90f45506e7d languageName: node linkType: hard @@ -4957,7 +4965,25 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0, @typescript-eslint/parser@npm:^6.2.1": +"@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0": + version: 7.2.0 + resolution: "@typescript-eslint/parser@npm:7.2.0" + dependencies: + "@typescript-eslint/scope-manager": "npm:7.2.0" + "@typescript-eslint/types": "npm:7.2.0" + "@typescript-eslint/typescript-estree": "npm:7.2.0" + "@typescript-eslint/visitor-keys": "npm:7.2.0" + debug: "npm:^4.3.4" + peerDependencies: + eslint: ^8.56.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 11ce36c68212fdbf98fc6fd32ba0977d46b645fd669a3f4fdb8be2036225f86ad005b31a66f97097e90517c44c92cf9cc5fb1d6e9647ee2fa125c4af21cdb477 + languageName: node + linkType: hard + +"@typescript-eslint/parser@npm:^6.2.1": version: 6.14.0 resolution: "@typescript-eslint/parser@npm:6.14.0" dependencies: @@ -4995,6 +5021,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:7.2.0": + version: 7.2.0 + resolution: "@typescript-eslint/scope-manager@npm:7.2.0" + dependencies: + "@typescript-eslint/types": "npm:7.2.0" + "@typescript-eslint/visitor-keys": "npm:7.2.0" + checksum: 4d088c127e6ba1a7de8567f70684779083be24b48746c3b4a86a0ec7062bca58693ee08482349ad6572a17ada8aa6f26b74d1c7139c8fcf7101fa09a572e0ea6 + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:6.14.0": version: 6.14.0 resolution: "@typescript-eslint/type-utils@npm:6.14.0" @@ -5026,6 +5062,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:7.2.0": + version: 7.2.0 + resolution: "@typescript-eslint/types@npm:7.2.0" + checksum: 135aae061720185855bea61ea6cfd33f4801d2de57f65e50079bbdb505100f844632aa4e4bdeec9e9e79d29aaddad949178d0e918e41867da6ab4b1390820e33 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" @@ -5062,6 +5105,25 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:7.2.0": + version: 7.2.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.2.0" + dependencies: + "@typescript-eslint/types": "npm:7.2.0" + "@typescript-eslint/visitor-keys": "npm:7.2.0" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + minimatch: "npm:9.0.3" + semver: "npm:^7.5.4" + ts-api-utils: "npm:^1.0.1" + peerDependenciesMeta: + typescript: + optional: true + checksum: 2730bb17730e6f3ca4061f00688a70386a808f5d174fdeb757c3cfa92c455373f69080df33237c1a8970e818af0cea0ae5a083970ed8ba493f3b04458c6f9271 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:6.14.0": version: 6.14.0 resolution: "@typescript-eslint/utils@npm:6.14.0" @@ -5117,6 +5179,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:7.2.0": + version: 7.2.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.2.0" + dependencies: + "@typescript-eslint/types": "npm:7.2.0" + eslint-visitor-keys: "npm:^3.4.1" + checksum: 2d7467495b2b76f3edb1b3047e97076c2242e7eca6d50bbbdd88219f9ff754dbcb9334a0568fe0ceb4c562823980938bd278aa2ba53da6343e7d99a167924f24 + languageName: node + linkType: hard + "@vitest/expect@npm:^0.34.2": version: 0.34.7 resolution: "@vitest/expect@npm:0.34.7" @@ -6580,17 +6652,24 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001406, caniuse-lite@npm:^1.0.30001565": +"caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001587": + version: 1.0.30001591 + resolution: "caniuse-lite@npm:1.0.30001591" + checksum: 21937d341c3d75994504db21340f65573a1e847a8ab33ee4964ed493994d6552864c494ba144485459abd9c711c75c0708bc9fa19f2bff525bff75ffb0a42c3b + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001565": version: 1.0.30001570 resolution: "caniuse-lite@npm:1.0.30001570" checksum: e47230d2016edea56e002fa462a5289f697b48dcfbf703fb01aecc6c98ad4ecaf945ab23c253cb7af056c2d05f266e4e4cbebf45132100e2c9367439cb95b95b languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001587": - version: 1.0.30001591 - resolution: "caniuse-lite@npm:1.0.30001591" - checksum: 21937d341c3d75994504db21340f65573a1e847a8ab33ee4964ed493994d6552864c494ba144485459abd9c711c75c0708bc9fa19f2bff525bff75ffb0a42c3b +"caniuse-lite@npm:^1.0.30001579": + version: 1.0.30001651 + resolution: "caniuse-lite@npm:1.0.30001651" + checksum: 7821278952a6dbd17358e5d08083d258f092e2a530f5bc1840657cb140fbbc5ec44293bc888258c44a18a9570cde149ed05819ac8320b9710cf22f699891e6ad languageName: node linkType: hard @@ -6709,7 +6788,7 @@ __metadata: date-fns: "npm:^3.6.0" date-fns-tz: "npm:^3.1.3" eslint: "npm:8.46.0" - eslint-config-next: "npm:^14.0.3" + eslint-config-next: "npm:^14.2.6" eslint-config-prettier: "npm:^8.10.0" eslint-import-resolver-typescript: "npm:^3.5.5" eslint-plugin-import: "npm:^2.28.0" @@ -6721,14 +6800,14 @@ __metadata: jest: "npm:^29.6.2" jest-environment-jsdom: "npm:^29.6.2" lottie-react: "npm:^2.4.0" - next: "npm:^14.0.3" + next: "npm:^14.2.6" next-themes: "npm:^0.2.1" postcss: "npm:8.4.27" prettier: "npm:^3.0.1" prettier-plugin-tailwindcss: "npm:^0.6.1" - react: "npm:^18.2.0" + react: "npm:^18.3.1" react-datepicker: "npm:^6.1.0" - react-dom: "npm:^18.2.0" + react-dom: "npm:^18.3.1" react-hook-form: "npm:^7.46.2" react-redux: "npm:^8.1.2" redux-persist: "npm:^6.0.0" @@ -8474,13 +8553,13 @@ __metadata: languageName: node linkType: hard -"eslint-config-next@npm:^14.0.3": - version: 14.0.4 - resolution: "eslint-config-next@npm:14.0.4" +"eslint-config-next@npm:^14.2.6": + version: 14.2.6 + resolution: "eslint-config-next@npm:14.2.6" dependencies: - "@next/eslint-plugin-next": "npm:14.0.4" + "@next/eslint-plugin-next": "npm:14.2.6" "@rushstack/eslint-patch": "npm:^1.3.3" - "@typescript-eslint/parser": "npm:^5.4.2 || ^6.0.0" + "@typescript-eslint/parser": "npm:^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0" eslint-import-resolver-node: "npm:^0.3.6" eslint-import-resolver-typescript: "npm:^3.5.2" eslint-plugin-import: "npm:^2.28.1" @@ -8493,7 +8572,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 39cc217b52288583cbb1b894e12a3e69a689b4b697609863b35937c381a5b2873cfa14a48a68d9fd3cb3b236e5f6f8ac16ecaeb3499fa1c3b4e12d2a62cb3c4e + checksum: 3a1b46696fa70a6a8b0dfdbb528ac30f324ad548d36736ebb08b2dd96d085224c59dafcac35dbcb0148173b8cd7519126abcacfbee1ad829184581ffb20b1b8d languageName: node linkType: hard @@ -9683,6 +9762,21 @@ __metadata: languageName: node linkType: hard +"glob@npm:10.3.10, glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.3.10 + resolution: "glob@npm:10.3.10" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.3.5" + minimatch: "npm:^9.0.1" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry: "npm:^1.10.1" + bin: + glob: dist/esm/bin.mjs + checksum: 13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d + languageName: node + linkType: hard + "glob@npm:7.1.6": version: 7.1.6 resolution: "glob@npm:7.1.6" @@ -9711,21 +9805,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.3.10 - resolution: "glob@npm:10.3.10" - dependencies: - foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.5" - minimatch: "npm:^9.0.1" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry: "npm:^1.10.1" - bin: - glob: dist/esm/bin.mjs - checksum: 13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d - languageName: node - linkType: hard - "glob@npm:^7.1.3, glob@npm:^7.1.4": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -12162,6 +12241,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:9.0.3, minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac + languageName: node + linkType: hard + "minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -12180,15 +12268,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac - languageName: node - linkType: hard - "minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" @@ -12394,29 +12473,29 @@ __metadata: languageName: node linkType: hard -"next@npm:^14.0.3": - version: 14.0.4 - resolution: "next@npm:14.0.4" +"next@npm:^14.2.6": + version: 14.2.6 + resolution: "next@npm:14.2.6" dependencies: - "@next/env": "npm:14.0.4" - "@next/swc-darwin-arm64": "npm:14.0.4" - "@next/swc-darwin-x64": "npm:14.0.4" - "@next/swc-linux-arm64-gnu": "npm:14.0.4" - "@next/swc-linux-arm64-musl": "npm:14.0.4" - "@next/swc-linux-x64-gnu": "npm:14.0.4" - "@next/swc-linux-x64-musl": "npm:14.0.4" - "@next/swc-win32-arm64-msvc": "npm:14.0.4" - "@next/swc-win32-ia32-msvc": "npm:14.0.4" - "@next/swc-win32-x64-msvc": "npm:14.0.4" - "@swc/helpers": "npm:0.5.2" + "@next/env": "npm:14.2.6" + "@next/swc-darwin-arm64": "npm:14.2.6" + "@next/swc-darwin-x64": "npm:14.2.6" + "@next/swc-linux-arm64-gnu": "npm:14.2.6" + "@next/swc-linux-arm64-musl": "npm:14.2.6" + "@next/swc-linux-x64-gnu": "npm:14.2.6" + "@next/swc-linux-x64-musl": "npm:14.2.6" + "@next/swc-win32-arm64-msvc": "npm:14.2.6" + "@next/swc-win32-ia32-msvc": "npm:14.2.6" + "@next/swc-win32-x64-msvc": "npm:14.2.6" + "@swc/helpers": "npm:0.5.5" busboy: "npm:1.6.0" - caniuse-lite: "npm:^1.0.30001406" + caniuse-lite: "npm:^1.0.30001579" graceful-fs: "npm:^4.2.11" postcss: "npm:8.4.31" styled-jsx: "npm:5.1.1" - watchpack: "npm:2.4.0" peerDependencies: "@opentelemetry/api": ^1.1.0 + "@playwright/test": ^1.41.2 react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 @@ -12442,11 +12521,13 @@ __metadata: peerDependenciesMeta: "@opentelemetry/api": optional: true + "@playwright/test": + optional: true sass: optional: true bin: next: dist/bin/next - checksum: e6c829fd473d8c3605b2b62d15e1bf41e9d90cf59a2c213b4adeadff2846999bc9a653ffef18f6aa13cc9f5d6de02469c222acf5a4184901a4690a4504bd468f + checksum: 262cf21a179f394aedfae36724d3ece46f717d618beebfbb75986be7f4d6093a6cf183c36871462c16d1ec490fd0a765d1944d04d30e282b4cca41b71aaf8eea languageName: node linkType: hard @@ -13920,15 +14001,15 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.2.0": - version: 18.2.0 - resolution: "react-dom@npm:18.2.0" +"react-dom@npm:^18.3.1": + version: 18.3.1 + resolution: "react-dom@npm:18.3.1" dependencies: loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.0" + scheduler: "npm:^0.23.2" peerDependencies: - react: ^18.2.0 - checksum: 66dfc5f93e13d0674e78ef41f92ed21dfb80f9c4ac4ac25a4b51046d41d4d2186abc915b897f69d3d0ebbffe6184e7c5876f2af26bfa956f179225d921be713a + react: ^18.3.1 + checksum: a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 languageName: node linkType: hard @@ -14084,12 +14165,12 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.2.0": - version: 18.2.0 - resolution: "react@npm:18.2.0" +"react@npm:^18.3.1": + version: 18.3.1 + resolution: "react@npm:18.3.1" dependencies: loose-envify: "npm:^1.1.0" - checksum: b562d9b569b0cb315e44b48099f7712283d93df36b19a39a67c254c6686479d3980b7f013dc931f4a5a3ae7645eae6386b4aa5eea933baa54ecd0f9acb0902b8 + checksum: 283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 languageName: node linkType: hard @@ -14685,12 +14766,12 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.0": - version: 0.23.0 - resolution: "scheduler@npm:0.23.0" +"scheduler@npm:^0.23.2": + version: 0.23.2 + resolution: "scheduler@npm:0.23.2" dependencies: loose-envify: "npm:^1.1.0" - checksum: b777f7ca0115e6d93e126ac490dbd82642d14983b3079f58f35519d992fa46260be7d6e6cede433a92db70306310c6f5f06e144f0e40c484199e09c1f7be53dd + checksum: 26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 languageName: node linkType: hard @@ -16524,7 +16605,7 @@ __metadata: languageName: node linkType: hard -"watchpack@npm:2.4.0, watchpack@npm:^2.2.0, watchpack@npm:^2.4.0": +"watchpack@npm:^2.2.0, watchpack@npm:^2.4.0": version: 2.4.0 resolution: "watchpack@npm:2.4.0" dependencies: From 7335d481114fb701b3a62c4af96ea55c98f0fd51 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Wed, 2 Oct 2024 00:58:34 -0400 Subject: [PATCH 04/18] test axios post request --- src/app/(auth)/login.ts | 21 +++++++++++++ .../components/SignInFormContainer.tsx | 30 ++++++++++--------- 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/app/(auth)/login.ts diff --git a/src/app/(auth)/login.ts b/src/app/(auth)/login.ts new file mode 100644 index 00000000..d67ad3e9 --- /dev/null +++ b/src/app/(auth)/login.ts @@ -0,0 +1,21 @@ +import axios from "axios"; + +export async function login(email: string, password: string) { + try { + const response = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/api/v1/auth/login`, + { email, password }, + { + headers: { + "Content-Type": "application/json", + }, + withCredentials: true, + }, + ); + + console.log(response); + // return response.data; + } catch (error) { + console.log(error); + } +} diff --git a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx index 19140242..5651f8f2 100644 --- a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx +++ b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx @@ -15,6 +15,7 @@ import routePaths from "@/utils/routePaths"; import useServerAction from "@/hooks/useServerAction"; import Spinner from "@/components/Spinner"; +import { login } from "../../login"; const validationSchema = z.object({ email: validateTextInput({ @@ -59,25 +60,26 @@ function SignInFormContainer({ const onSubmit: SubmitHandler = async (data) => { const { email, password } = data; - const [res, error] = await serverSignInAction({ email, password }); + await login(email, password); + // const [res, error] = await serverSignInAction({ email, password }); - if (res) { - dispatch(clientSignIn()); - router.replace(routePaths.dashboardPage()); - } + // if (res) { + // dispatch(clientSignIn()); + // router.replace(routePaths.dashboardPage()); + // } - if (error) { - dispatch( - onOpenModal({ type: "error", content: { message: error.message } }), - ); - setServerSignInLoading(false); - } + // if (error) { + // dispatch( + // onOpenModal({ type: "error", content: { message: error.message } }), + // ); + // setServerSignInLoading(false); + // } }; function renderButtonContent() { - if (serverSignInLoading) { - return ; - } + // if (serverSignInLoading) { + // return ; + // } return "Sign In"; } From 17c5e87640b48f9a50036e447a45e62e06bbab89 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Wed, 2 Oct 2024 01:00:07 -0400 Subject: [PATCH 05/18] comment out code temp --- src/app/(auth)/login.ts | 2 ++ .../components/SignInFormContainer.tsx | 20 +++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/app/(auth)/login.ts b/src/app/(auth)/login.ts index d67ad3e9..a81b6738 100644 --- a/src/app/(auth)/login.ts +++ b/src/app/(auth)/login.ts @@ -13,9 +13,11 @@ export async function login(email: string, password: string) { }, ); + // eslint-disable-next-line no-console console.log(response); // return response.data; } catch (error) { + // eslint-disable-next-line no-console console.log(error); } } diff --git a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx index 5651f8f2..af8f2fe0 100644 --- a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx +++ b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx @@ -1,6 +1,6 @@ import * as z from "zod"; import Link from "next/link"; -import { useRouter } from "next/navigation"; +// import { useRouter } from "next/navigation"; import { type SubmitHandler, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { serverSignIn } from "@/app/(auth)/authService"; @@ -8,14 +8,14 @@ import { serverSignIn } from "@/app/(auth)/authService"; import Button from "@/components/Button"; import TextInput from "@/components/inputs/TextInput"; import { validateTextInput } from "@/utils/form/validateInput"; -import { clientSignIn } from "@/store/features/auth/authSlice"; -import { onOpenModal } from "@/store/features/modal/modalSlice"; -import { useAppDispatch } from "@/store/hooks"; +// import { clientSignIn } from "@/store/features/auth/authSlice"; +// import { onOpenModal } from "@/store/features/modal/modalSlice"; +// import { useAppDispatch } from "@/store/hooks"; import routePaths from "@/utils/routePaths"; import useServerAction from "@/hooks/useServerAction"; -import Spinner from "@/components/Spinner"; -import { login } from "../../login"; +// import Spinner from "@/components/Spinner"; +import { login } from "@/app/(auth)/login"; const validationSchema = z.object({ email: validateTextInput({ @@ -40,13 +40,13 @@ interface SignInFormContainerProps { function SignInFormContainer({ handleResetPassword, }: SignInFormContainerProps) { - const router = useRouter(); - const dispatch = useAppDispatch(); + // const router = useRouter(); + // const dispatch = useAppDispatch(); const { - runAction: serverSignInAction, + // runAction: serverSignInAction, isLoading: serverSignInLoading, - setIsLoading: setServerSignInLoading, + // setIsLoading: setServerSignInLoading, } = useServerAction(serverSignIn); const { From 855f5d34bd078a380f31c73f696cf300a38274eb Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Wed, 2 Oct 2024 01:07:12 -0400 Subject: [PATCH 06/18] install axios --- package.json | 1 + yarn.lock | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d9a0440c..5634eb8f 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@heroicons/react": "^2.0.18", "@hookform/resolvers": "^3.3.1", "@reduxjs/toolkit": "^1.9.5", + "axios": "^1.7.7", "class-variance-authority": "^0.7.0", "date-fns": "^3.6.0", "date-fns-tz": "^3.1.3", diff --git a/yarn.lock b/yarn.lock index 5560cb17..2ca948f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6046,6 +6046,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.7.7": + version: 1.7.7 + resolution: "axios@npm:1.7.7" + dependencies: + follow-redirects: "npm:^1.15.6" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 4499efc89e86b0b49ffddc018798de05fab26e3bf57913818266be73279a6418c3ce8f9e934c7d2d707ab8c095e837fc6c90608fb7715b94d357720b5f568af7 + languageName: node + linkType: hard + "axobject-query@npm:^3.2.1": version: 3.2.1 resolution: "axobject-query@npm:3.2.1" @@ -6783,6 +6794,7 @@ __metadata: "@typescript-eslint/eslint-plugin": "npm:^6.2.1" "@typescript-eslint/parser": "npm:^6.2.1" autoprefixer: "npm:10.4.14" + axios: "npm:^1.7.7" class-variance-authority: "npm:^0.7.0" cypress: "npm:^12.17.3" date-fns: "npm:^3.6.0" @@ -9336,6 +9348,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.15.6": + version: 1.15.9 + resolution: "follow-redirects@npm:1.15.9" + peerDependenciesMeta: + debug: + optional: true + checksum: 5829165bd112c3c0e82be6c15b1a58fa9dcfaede3b3c54697a82fe4a62dd5ae5e8222956b448d2f98e331525f05d00404aba7d696de9e761ef6e42fdc780244f + languageName: node + linkType: hard + "for-each@npm:^0.3.3": version: 0.3.3 resolution: "for-each@npm:0.3.3" @@ -13709,7 +13731,7 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:^1.0.0": +"proxy-from-env@npm:^1.0.0, proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" checksum: fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b From d498e948ae88bbdeb2c8c785230cb22f0eef8d91 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 3 Oct 2024 22:48:16 -0400 Subject: [PATCH 07/18] setup login, fetching user, and fetching directory with axios and client components --- src/app/(auth)/login.ts | 7 +- .../components/SignInFormContainer.tsx | 23 +- src/app/(main)/layout.tsx | 18 +- .../components/DirectoryComponentWrapper.tsx | 210 +++++++++++------- src/components/sidebar/Sidebar.tsx | 2 +- src/utils/getUser.ts | 25 ++- 6 files changed, 181 insertions(+), 104 deletions(-) diff --git a/src/app/(auth)/login.ts b/src/app/(auth)/login.ts index a81b6738..37b19494 100644 --- a/src/app/(auth)/login.ts +++ b/src/app/(auth)/login.ts @@ -13,11 +13,8 @@ export async function login(email: string, password: string) { }, ); - // eslint-disable-next-line no-console - console.log(response); - // return response.data; + return response.data; } catch (error) { - // eslint-disable-next-line no-console - console.log(error); + throw Error(error); } } diff --git a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx index af8f2fe0..eeb72c3e 100644 --- a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx +++ b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx @@ -1,6 +1,6 @@ import * as z from "zod"; import Link from "next/link"; -// import { useRouter } from "next/navigation"; +import { useRouter } from "next/navigation"; import { type SubmitHandler, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { serverSignIn } from "@/app/(auth)/authService"; @@ -8,9 +8,9 @@ import { serverSignIn } from "@/app/(auth)/authService"; import Button from "@/components/Button"; import TextInput from "@/components/inputs/TextInput"; import { validateTextInput } from "@/utils/form/validateInput"; -// import { clientSignIn } from "@/store/features/auth/authSlice"; -// import { onOpenModal } from "@/store/features/modal/modalSlice"; -// import { useAppDispatch } from "@/store/hooks"; +import { clientSignIn } from "@/store/features/auth/authSlice"; +import { onOpenModal } from "@/store/features/modal/modalSlice"; +import { useAppDispatch } from "@/store/hooks"; import routePaths from "@/utils/routePaths"; import useServerAction from "@/hooks/useServerAction"; @@ -40,8 +40,8 @@ interface SignInFormContainerProps { function SignInFormContainer({ handleResetPassword, }: SignInFormContainerProps) { - // const router = useRouter(); - // const dispatch = useAppDispatch(); + const router = useRouter(); + const dispatch = useAppDispatch(); const { // runAction: serverSignInAction, @@ -60,7 +60,16 @@ function SignInFormContainer({ const onSubmit: SubmitHandler = async (data) => { const { email, password } = data; - await login(email, password); + + try { + await login(email, password); + dispatch(clientSignIn()); + router.replace(routePaths.dashboardPage()); + } catch (error) { + dispatch( + onOpenModal({ type: "error", content: { message: error.message } }), + ); + } // const [res, error] = await serverSignInAction({ email, password }); // if (res) { diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index f7a34315..70bcf1a5 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -1,16 +1,30 @@ +"use client"; + import Sidebar from "@/components/sidebar/Sidebar"; import Navbar from "@/components/navbar/Navbar"; import ModeToggle from "@/components/ModeToggle"; import AuthHeader from "@/components/navbar/AuthHeader"; import { getUser } from "@/utils/getUser"; import AuthProvider from "@/app/(auth)/AuthProvider"; +import { useEffect, useState } from "react"; interface LayoutProps { children: React.ReactNode; } -export default async function Layout({ children }: LayoutProps) { - const [user, error] = await getUser(); +export default function Layout({ children }: LayoutProps) { + const [user, setUser] = useState(); + const [error, setError] = useState(); + + useEffect(() => { + const fetchUser = async () => await getUser(); + + fetchUser() + .then((data) => setUser(data)) + .catch((err) => { + setError(err); + }); + }, []); return (
diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx index 59a863f6..8727298d 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx @@ -1,3 +1,5 @@ +"use client"; + import { redirect } from "next/navigation"; import DirectoryProvider from "./DirectoryProvider"; @@ -18,56 +20,58 @@ import { getTimezone } from "@/utils/getTimezone"; import VoyagePageBannerContainer from "@/components/banner/VoyagePageBannerContainer"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import { ErrorType } from "@/utils/error"; +import { useEffect, useState } from "react"; +import axios from "axios"; interface FetchTeamDirectoryProps { teamId: number; user: User | null; } -export async function fetchTeamDirectory({ - teamId, - user, -}: FetchTeamDirectoryProps): Promise> { - const token = getAccessToken(); - - const fetchTeamDirectoryAsync = () => - GET( - `api/v1/teams/${teamId}`, - token, - "force-cache", - CacheTag.directory, - ); - - const [res, error] = await handleAsync(fetchTeamDirectoryAsync); - - if (res) { - updateDirectoryWithCurrentTime(res); - const teamMember = res.voyageTeamMembers; - const elementToSort = teamMember.find( - (element) => element.member.discordId === user?.discordId, - ); - moveElementToFirst(teamMember, elementToSort); - } - - return [res, error]; -} - -function updateDirectoryWithCurrentTime(data: TeamDirectory) { - return data.voyageTeamMembers.forEach((teamMember) => { - const { timezone } = teamMember.member; - const currentTime = getTimezone(timezone); - teamMember.member.currentTime = currentTime; - }); -} - -function moveElementToFirst(arr: T[], element: T): T[] { - const index = arr.indexOf(element); - if (index === -1) { - return arr; - } - [arr[index], arr[0]] = [arr[0], arr[index]]; - return arr; -} +// export async function fetchTeamDirectory({ +// teamId, +// user, +// }: FetchTeamDirectoryProps): Promise> { +// const token = getAccessToken(); + +// const fetchTeamDirectoryAsync = () => +// GET( +// `api/v1/teams/${teamId}`, +// token, +// "force-cache", +// CacheTag.directory, +// ); + +// const [res, error] = await handleAsync(fetchTeamDirectoryAsync); + +// if (res) { +// updateDirectoryWithCurrentTime(res); +// const teamMember = res.voyageTeamMembers; +// const elementToSort = teamMember.find( +// (element) => element.member.discordId === user?.discordId, +// ); +// moveElementToFirst(teamMember, elementToSort); +// } + +// return [res, error]; +// } + +// function updateDirectoryWithCurrentTime(data: TeamDirectory) { +// return data.voyageTeamMembers.forEach((teamMember) => { +// const { timezone } = teamMember.member; +// const currentTime = getTimezone(timezone); +// teamMember.member.currentTime = currentTime; +// }); +// } + +// function moveElementToFirst(arr: T[], element: T): T[] { +// const index = arr.indexOf(element); +// if (index === -1) { +// return arr; +// } +// [arr[index], arr[0]] = [arr[0], arr[index]]; +// return arr; +// } interface TeamDirectoryProps { params: { @@ -75,47 +79,85 @@ interface TeamDirectoryProps { }; } -export default async function DirectoryComponentWrapper({ +export default function DirectoryComponentWrapper({ params, }: TeamDirectoryProps) { - let teamDirectory: TeamDirectory; + // let teamDirectory: TeamDirectory; const teamId = Number(params.teamId); - - const [user, error] = await getUser(); - - const { errorResponse, data } = await getCurrentVoyageData({ - user, - error, - teamId, - args: { teamId, user }, - func: fetchTeamDirectory, - }); - - if (errorResponse) { - return ( - - ); - } - - if (data) { - const [res, error] = data; - - if (error) { - return ( - - ); - } - - teamDirectory = res!; - } else { - redirect("/"); - } + const [teamDirectory, setTeamDirectory] = useState(); + + // const [user, setUser] = useState(); + + // useEffect(() => { + // const fetchUser = async () => { + // const user = await getUser(); + // setUser(user); + // }; + + // fetchUser().catch(console.error); + // }, []); + + useEffect(() => { + const fetchDirectory = async () => { + try { + const response = await axios.get( + `${process.env.NEXT_PUBLIC_API_URL}/api/v1/teams/${teamId}`, + { + headers: { + "Content-Type": "application/json", + }, + withCredentials: true, + }, + ); + + return response.data; + } catch (error) { + throw Error(error); + } + }; + + fetchDirectory() + .then((data) => setTeamDirectory(data)) + .catch((err) => { + throw Error(err); + }); + }, [teamId]); + + console.log(teamDirectory); + + // const { errorResponse, data } = await getCurrentVoyageData({ + // user, + // error, + // teamId, + // args: { teamId, user }, + // func: fetchTeamDirectory, + // }); + + // if (errorResponse) { + // return ( + // + // ); + // } + + // if (data) { + // const [res, error] = data; + + // if (error) { + // return ( + // + // ); + // } + + // teamDirectory = res!; + // } else { + // redirect("/"); + // } return ( <> @@ -131,7 +173,7 @@ export default async function DirectoryComponentWrapper({ width="w-[276px]" /> - + {/* */} {/* For screens > 1920px */}
{/* header - table only */} @@ -143,7 +185,7 @@ export default async function DirectoryComponentWrapper({

Average Hour/Sprint

{/* data */} - {teamDirectory.voyageTeamMembers.map((teamMember) => ( + {teamDirectory?.voyageTeamMembers.map((teamMember) => ( ))}
diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index a74b76d3..92bf3ca0 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -179,7 +179,7 @@ export default function Sidebar() { onClick={handlePageClick} hoveredButton={hoveredButton} selectedButton={selectedButton} - isVoyageStarted={isVoyageStarted} + isVoyageStarted={true} setHoveredButton={setHoveredButton} /> ))} diff --git a/src/utils/getUser.ts b/src/utils/getUser.ts index b5c8efe7..98fb1457 100644 --- a/src/utils/getUser.ts +++ b/src/utils/getUser.ts @@ -1,13 +1,28 @@ +import axios from "axios"; import { getAccessToken } from "./getCookie"; import { type AsyncActionResponse, handleAsync } from "./handleAsync"; import { GET } from "./requests"; import { type User } from "@/store/features/user/userSlice"; -export function getUser(): Promise> { - const token = getAccessToken(); +export async function getUser() { + try { + const response = await axios.get( + `${process.env.NEXT_PUBLIC_API_URL}/api/v1/users/me`, + { + headers: { + "Content-Type": "application/json", + }, + withCredentials: true, + }, + ); - const getUserAsync = () => - GET("api/v1/users/me", token, "force-cache", "me"); + return response.data; + } catch (error) { + throw Error(error); + } - return handleAsync(getUserAsync); + // const getUserAsync = () => + // GET("api/v1/users/me", token, "force-cache", "me"); + + // return handleAsync(getUserAsync); } From 8ce2762494d9ad6e601b529ea50fb088c09300ad Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 3 Oct 2024 22:59:10 -0400 Subject: [PATCH 08/18] fetch features client side --- .../components/DirectoryComponentWrapper.tsx | 2 - .../components/FeaturesComponentWrapper.tsx | 153 +++++++++++------- 2 files changed, 95 insertions(+), 60 deletions(-) diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx index 8727298d..f93cd5aa 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx @@ -123,8 +123,6 @@ export default function DirectoryComponentWrapper({ }); }, [teamId]); - console.log(teamDirectory); - // const { errorResponse, data } = await getCurrentVoyageData({ // user, // error, diff --git a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx index 008df74e..161c6acf 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx @@ -1,3 +1,5 @@ +"use client"; + import { redirect } from "next/navigation"; import FeaturesProvider from "./FeaturesProvider"; @@ -18,6 +20,9 @@ import { GET } from "@/utils/requests"; import { CacheTag } from "@/utils/cacheTag"; import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { ErrorType } from "@/utils/error"; +import { useEffect, useState } from "react"; +import axios from "axios"; +import { features } from "process"; function transformData(features: Features[]): FeaturesList[] { const transformedData: FeaturesList[] = [ @@ -75,28 +80,28 @@ interface FetchFeaturesProps { teamId: number; } -export async function fetchFeatures({ - teamId, -}: FetchFeaturesProps): Promise> { - let data: FeaturesList[] | null = []; - const token = getAccessToken(); - - const fetchFeaturesAsync = () => - GET( - `api/v1/voyages/teams/${teamId}/features`, - token, - "force-cache", - CacheTag.features, - ); +// export async function fetchFeatures({ +// teamId, +// }: FetchFeaturesProps): Promise> { +// let data: FeaturesList[] | null = []; +// const token = getAccessToken(); - const [res, error] = await handleAsync(fetchFeaturesAsync); +// const fetchFeaturesAsync = () => +// GET( +// `api/v1/voyages/teams/${teamId}/features`, +// token, +// "force-cache", +// CacheTag.features, +// ); - if (res) { - data = transformData(res); - } +// const [res, error] = await handleAsync(fetchFeaturesAsync); - return [data, error]; -} +// if (res) { +// data = transformData(res); +// } + +// return [data, error]; +// } interface FeaturesComponentWrapperProps { params: { @@ -104,48 +109,80 @@ interface FeaturesComponentWrapperProps { }; } -export default async function FeaturesComponentWrapper({ +export default function FeaturesComponentWrapper({ params, }: FeaturesComponentWrapperProps) { - let features = []; + // let features = []; const teamId = Number(params.teamId); - - const [user, error] = await getUser(); - - const { errorResponse, data } = await getCurrentVoyageData({ - user, - error, - teamId, - args: { teamId }, - func: fetchFeatures, - }); - - if (errorResponse) { - return ( - - ); - } - - if (data) { - const [res, error] = data; - - if (error) { - return ( - - ); - } - - features = res!; - } else { - redirect("/"); - } + const [features, setFeatures] = useState([]); + + useEffect(() => { + const fetchFeatures = async () => { + try { + const response = await axios.get( + `${process.env.NEXT_PUBLIC_API_URL}/api/v1/voyages/teams/${teamId}/features`, + { + headers: { + "Content-Type": "application/json", + }, + withCredentials: true, + }, + ); + + return response.data; + } catch (error) { + throw Error(error); + } + }; + + fetchFeatures() + .then((data) => { + const features = transformData(data); + setFeatures(features); + }) + .catch((err) => { + throw Error(err); + }); + }, [teamId]); + + console.log(features); + + // const [user, error] = await getUser(); + + // const { errorResponse, data } = await getCurrentVoyageData({ + // user, + // error, + // teamId, + // args: { teamId }, + // func: fetchFeatures, + // }); + + // if (errorResponse) { + // return ( + // + // ); + // } + + // if (data) { + // const [res, error] = data; + + // if (error) { + // return ( + // + // ); + // } + + // features = res!; + // } else { + // redirect("/"); + // } return ( <> @@ -161,7 +198,7 @@ export default async function FeaturesComponentWrapper({ width="w-[276px]" /> - + {/* */} ); From 5a45ce7feac880a3125c6f4b3bda9dd5dc0d06a3 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 3 Oct 2024 23:14:04 -0400 Subject: [PATCH 09/18] create axios instance --- src/app/(auth)/login.ts | 15 +++++---------- .../components/DirectoryComponentWrapper.tsx | 11 ++--------- .../components/FeaturesComponentWrapper.tsx | 11 +++-------- src/utils/axiosInstance.ts | 9 +++++++++ src/utils/getUser.ts | 11 ++--------- 5 files changed, 21 insertions(+), 36 deletions(-) create mode 100644 src/utils/axiosInstance.ts diff --git a/src/app/(auth)/login.ts b/src/app/(auth)/login.ts index 37b19494..b7b9112b 100644 --- a/src/app/(auth)/login.ts +++ b/src/app/(auth)/login.ts @@ -1,17 +1,12 @@ +import { axiosInstance } from "@/utils/axiosInstance"; import axios from "axios"; export async function login(email: string, password: string) { try { - const response = await axios.post( - `${process.env.NEXT_PUBLIC_API_URL}/api/v1/auth/login`, - { email, password }, - { - headers: { - "Content-Type": "application/json", - }, - withCredentials: true, - }, - ); + const response = await axiosInstance.post("/api/v1/auth/login", { + email, + password, + }); return response.data; } catch (error) { diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx index f93cd5aa..abadf347 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx @@ -22,6 +22,7 @@ import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import { ErrorType } from "@/utils/error"; import { useEffect, useState } from "react"; import axios from "axios"; +import { axiosInstance } from "@/utils/axiosInstance"; interface FetchTeamDirectoryProps { teamId: number; @@ -100,15 +101,7 @@ export default function DirectoryComponentWrapper({ useEffect(() => { const fetchDirectory = async () => { try { - const response = await axios.get( - `${process.env.NEXT_PUBLIC_API_URL}/api/v1/teams/${teamId}`, - { - headers: { - "Content-Type": "application/json", - }, - withCredentials: true, - }, - ); + const response = await axiosInstance.get(`/api/v1/teams/${teamId}`); return response.data; } catch (error) { diff --git a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx index 161c6acf..82cb10ed 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx @@ -23,6 +23,7 @@ import { ErrorType } from "@/utils/error"; import { useEffect, useState } from "react"; import axios from "axios"; import { features } from "process"; +import { axiosInstance } from "@/utils/axiosInstance"; function transformData(features: Features[]): FeaturesList[] { const transformedData: FeaturesList[] = [ @@ -120,14 +121,8 @@ export default function FeaturesComponentWrapper({ useEffect(() => { const fetchFeatures = async () => { try { - const response = await axios.get( - `${process.env.NEXT_PUBLIC_API_URL}/api/v1/voyages/teams/${teamId}/features`, - { - headers: { - "Content-Type": "application/json", - }, - withCredentials: true, - }, + const response = await axiosInstance.get( + `/api/v1/voyages/teams/${teamId}/features`, ); return response.data; diff --git a/src/utils/axiosInstance.ts b/src/utils/axiosInstance.ts new file mode 100644 index 00000000..5a7716a1 --- /dev/null +++ b/src/utils/axiosInstance.ts @@ -0,0 +1,9 @@ +import axios from "axios"; + +export const axiosInstance = axios.create({ + baseURL: `${process.env.NEXT_PUBLIC_API_URL}`, + headers: { + "Content-Type": "application/json", + }, + withCredentials: true, +}); diff --git a/src/utils/getUser.ts b/src/utils/getUser.ts index 98fb1457..b72b9231 100644 --- a/src/utils/getUser.ts +++ b/src/utils/getUser.ts @@ -3,18 +3,11 @@ import { getAccessToken } from "./getCookie"; import { type AsyncActionResponse, handleAsync } from "./handleAsync"; import { GET } from "./requests"; import { type User } from "@/store/features/user/userSlice"; +import { axiosInstance } from "./axiosInstance"; export async function getUser() { try { - const response = await axios.get( - `${process.env.NEXT_PUBLIC_API_URL}/api/v1/users/me`, - { - headers: { - "Content-Type": "application/json", - }, - withCredentials: true, - }, - ); + const response = await axiosInstance.get("/api/v1/users/me"); return response.data; } catch (error) { From 29a8e9f0c77ab9fcf776f76f9ae98c4e844699b5 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Fri, 4 Oct 2024 00:09:03 -0400 Subject: [PATCH 10/18] setup axios interceptors to get new token --- .../directory/components/EditHours.tsx | 23 ++-- .../components/FeaturesComponentWrapper.tsx | 2 - src/middleware.ts | 111 +++++++++--------- src/utils/axiosInstance.ts | 67 ++++++++++- 4 files changed, 133 insertions(+), 70 deletions(-) diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx index aaf8e2fc..cbf23099 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx @@ -12,6 +12,7 @@ import { onOpenModal } from "@/store/features/modal/modalSlice"; import useServerAction from "@/hooks/useServerAction"; import Spinner from "@/components/Spinner"; import Button from "@/components/Button"; +import { axiosInstance } from "@/utils/axiosInstance"; interface EditHoursProps { hrPerSprint: number; @@ -59,19 +60,23 @@ export default function EditHours({ const onSubmit: SubmitHandler = async (data) => { const { avgHours } = data; - const [, error] = await editHoursAction({ - teamId, + + return await axiosInstance.patch(`api/v1/teams/${teamId}/members`, { hrPerSprint: Number(avgHours), }); + // const [, error] = await editHoursAction({ + // teamId, + // hrPerSprint: Number(avgHours), + // }); - if (error) { - dispatch( - onOpenModal({ type: "error", content: { message: error.message } }), - ); - } + // if (error) { + // dispatch( + // onOpenModal({ type: "error", content: { message: error.message } }), + // ); + // } - setEditHoursLoading(false); - setIsEditing(false); + // setEditHoursLoading(false); + // setIsEditing(false); }; function handleClearInputAction() { diff --git a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx index 82cb10ed..e3b6965b 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx @@ -141,8 +141,6 @@ export default function FeaturesComponentWrapper({ }); }, [teamId]); - console.log(features); - // const [user, error] = await getUser(); // const { errorResponse, data } = await getCurrentVoyageData({ diff --git a/src/middleware.ts b/src/middleware.ts index 1d18ce64..a63745c4 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -2,62 +2,57 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; import { getRefreshToken } from "./utils/getCookie"; -export async function middleware(request: NextRequest) { - if (request.cookies.has("refresh_token")) { - if (request.cookies.has("access_token")) { - return NextResponse.next(); - } - const token = getRefreshToken()!; - const res = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/api/v1/auth/refresh`, - { - method: "POST", - headers: { - Cookie: token, - }, - credentials: "include", - cache: "no-store", - }, - ); - - if (!res.ok) { - throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); - } - - const accessToken = res.headers.getSetCookie()[0].split("access_token=")[1]; - const refreshToken = res.headers - .getSetCookie()[0] - .split(";") - .slice(5) - .join("") - .split(",") - .slice(1) - .join(""); - const accessTokenValue = accessToken.split("; ")[0]; - const accessTokenMaxAge = accessToken.split("; ")[1].split("=")[1]; - const refreshTokenValue = refreshToken.match(/refresh_token=([^ ]+)/)![1]; - const refreshTokenMaxAge = refreshToken.match(/Max-Age=(\d+)/)![1]; - - const response = NextResponse.next(); - - response.cookies.set({ - name: "access_token", - value: accessTokenValue, - httpOnly: true, - maxAge: +accessTokenMaxAge, - path: "/", - secure: true, - }); - - response.cookies.set({ - name: "refresh_token", - value: refreshTokenValue, - httpOnly: true, - maxAge: +refreshTokenMaxAge, - path: "/", - secure: true, - }); - return response; - } - return NextResponse.next(); +export async function middleware() { + // if (request.cookies.has("refresh_token")) { + // if (request.cookies.has("access_token")) { + // return NextResponse.next(); + // } + // const token = getRefreshToken()!; + // const res = await fetch( + // `${process.env.NEXT_PUBLIC_API_URL}/api/v1/auth/refresh`, + // { + // method: "POST", + // headers: { + // Cookie: token, + // }, + // credentials: "include", + // cache: "no-store", + // }, + // ); + // if (!res.ok) { + // throw new Error(`Status code: ${res.status}, Message: ${res.statusText}`); + // } + // const accessToken = res.headers.getSetCookie()[0].split("access_token=")[1]; + // const refreshToken = res.headers + // .getSetCookie()[0] + // .split(";") + // .slice(5) + // .join("") + // .split(",") + // .slice(1) + // .join(""); + // const accessTokenValue = accessToken.split("; ")[0]; + // const accessTokenMaxAge = accessToken.split("; ")[1].split("=")[1]; + // const refreshTokenValue = refreshToken.match(/refresh_token=([^ ]+)/)![1]; + // const refreshTokenMaxAge = refreshToken.match(/Max-Age=(\d+)/)![1]; + // const response = NextResponse.next(); + // response.cookies.set({ + // name: "access_token", + // value: accessTokenValue, + // httpOnly: true, + // maxAge: +accessTokenMaxAge, + // path: "/", + // secure: true, + // }); + // response.cookies.set({ + // name: "refresh_token", + // value: refreshTokenValue, + // httpOnly: true, + // maxAge: +refreshTokenMaxAge, + // path: "/", + // secure: true, + // }); + // return response; + // } + // return NextResponse.next(); } diff --git a/src/utils/axiosInstance.ts b/src/utils/axiosInstance.ts index 5a7716a1..4e375626 100644 --- a/src/utils/axiosInstance.ts +++ b/src/utils/axiosInstance.ts @@ -1,4 +1,8 @@ -import axios from "axios"; +import axios, { + type AxiosError, + type AxiosRequestConfig, + type AxiosResponse, +} from "axios"; export const axiosInstance = axios.create({ baseURL: `${process.env.NEXT_PUBLIC_API_URL}`, @@ -7,3 +11,64 @@ export const axiosInstance = axios.create({ }, withCredentials: true, }); + +let isRefreshing = false; +let failedRequestsQueue: Array<{ + resolve: (config: AxiosRequestConfig) => void; + reject: (error: AxiosError) => void; +}> = []; + +const processQueue = ( + error: AxiosError | null, + config: AxiosRequestConfig | null = null, +) => { + failedRequestsQueue.forEach((prom) => { + if (error) { + prom.reject(error); + } else if (config) { + prom.resolve(config); + } + }); + failedRequestsQueue = []; +}; + +axiosInstance.interceptors.response.use( + (response: AxiosResponse) => response, + async (error: AxiosError) => { + const originalRequest = error.config as AxiosRequestConfig & { + _retry?: boolean; + }; + + if (error.response?.status === 401 && !originalRequest._retry) { + if (isRefreshing) { + return new Promise((resolve, reject) => { + failedRequestsQueue.push({ resolve, reject }); + }) + .then(() => axiosInstance(originalRequest)) + .catch((err) => Promise.reject(err)); + } + + originalRequest._retry = true; + isRefreshing = true; + + try { + await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/api/v1/auth/refresh`, + {}, + { withCredentials: true }, + ); + + processQueue(null); + isRefreshing = false; + + return axiosInstance(originalRequest); + } catch (err) { + processQueue(err as AxiosError, null); + isRefreshing = false; + return Promise.reject(err); + } + } + + return Promise.reject(error); + }, +); From 890c890985387de28c5115acbc20f0679c762a5d Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Fri, 4 Oct 2024 03:42:43 -0400 Subject: [PATCH 11/18] lint --- src/app/(auth)/login.ts | 6 +- .../components/SignInFormContainer.tsx | 5 +- src/app/(main)/dashboard/[teamId]/page.tsx | 1 + .../voyage-dashboard/VoyageDashboard.tsx | 177 ++++++++---------- .../voyage-dashboard/getDashboardData.ts | 20 +- src/app/(main)/dashboard/page.tsx | 8 +- src/app/(main)/layout.tsx | 6 +- .../components/DirectoryComponentWrapper.tsx | 33 +--- .../directory/components/EditHours.tsx | 12 +- .../components/FeaturesComponentWrapper.tsx | 28 +-- .../components/WeeklyCheckInWrapper.tsx | 77 ++++---- .../components/forms/WeeklyCheckInForm.tsx | 2 +- .../components/ResourcesComponentWrapper.tsx | 1 + src/components/sidebar/Sidebar.tsx | 24 +-- src/middleware.ts | 4 - src/utils/getUser.ts | 11 +- 16 files changed, 193 insertions(+), 222 deletions(-) diff --git a/src/app/(auth)/login.ts b/src/app/(auth)/login.ts index b7b9112b..bcbfd1d0 100644 --- a/src/app/(auth)/login.ts +++ b/src/app/(auth)/login.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { axiosInstance } from "@/utils/axiosInstance"; -import axios from "axios"; export async function login(email: string, password: string) { try { @@ -9,7 +11,7 @@ export async function login(email: string, password: string) { }); return response.data; - } catch (error) { + } catch (error: any) { throw Error(error); } } diff --git a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx index eeb72c3e..653e628b 100644 --- a/src/app/(auth)/sign-in/components/SignInFormContainer.tsx +++ b/src/app/(auth)/sign-in/components/SignInFormContainer.tsx @@ -1,3 +1,6 @@ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import * as z from "zod"; import Link from "next/link"; import { useRouter } from "next/navigation"; @@ -65,7 +68,7 @@ function SignInFormContainer({ await login(email, password); dispatch(clientSignIn()); router.replace(routePaths.dashboardPage()); - } catch (error) { + } catch (error: any) { dispatch( onOpenModal({ type: "error", content: { message: error.message } }), ); diff --git a/src/app/(main)/dashboard/[teamId]/page.tsx b/src/app/(main)/dashboard/[teamId]/page.tsx index a5fe5ba1..6cf0ff06 100644 --- a/src/app/(main)/dashboard/[teamId]/page.tsx +++ b/src/app/(main)/dashboard/[teamId]/page.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { redirect } from "next/navigation"; import VoyageDashboardPage from "@/app/(main)/dashboard/components/voyage-dashboard/VoyageDashboardPage"; import PreVoyageDashboard from "@/app/(main)/dashboard/components/pre-voyage-dashboard/PreVoyageDashboard"; diff --git a/src/app/(main)/dashboard/components/voyage-dashboard/VoyageDashboard.tsx b/src/app/(main)/dashboard/components/voyage-dashboard/VoyageDashboard.tsx index 8bbb3007..f72a735c 100644 --- a/src/app/(main)/dashboard/components/voyage-dashboard/VoyageDashboard.tsx +++ b/src/app/(main)/dashboard/components/voyage-dashboard/VoyageDashboard.tsx @@ -1,32 +1,15 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ import React from "react"; -import { - ComputerDesktopIcon, - SwatchIcon, - CodeBracketSquareIcon, - ChartPieIcon, - CloudIcon, - ServerStackIcon, -} from "@heroicons/react/24/solid"; +// import { +// ComputerDesktopIcon, +// SwatchIcon, +// CodeBracketSquareIcon, +// ChartPieIcon, +// CloudIcon, +// ServerStackIcon, +// } from "@heroicons/react/24/solid"; import DashboardWidget from "./DashboardWidget"; -import CheckInWidget from "./CheckInWidget"; -import CalendarWidget from "./CalendarWidget"; -import IdeationStateContent from "./IdeationStateContent"; -import FeaturesStateContent from "./FeaturesStateContent"; -import TechStackStateContent from "./TechStackStateContent"; -import ResourcesStateContent from "./ResourcesStateContent"; -import { type Event, getDashboardData } from "./getDashboardData"; import VoyageSupport from "@/app/(main)/dashboard/components/shared/VoyageSupport"; -import EmptySprintProvider from "@/app/(main)/my-voyage/[teamId]/sprints/providers/EmptySprintProvider"; -import { getUser } from "@/utils/getUser"; -import type { Sprint, Voyage } from "@/store/features/sprint/sprintSlice"; -import { type FeaturesList } from "@/store/features/features/featuresSlice"; -import { type IdeationData } from "@/store/features/ideation/ideationSlice"; -import { type TechStackData } from "@/store/features/techStack/techStackSlice"; -import { type ResourceData } from "@/store/features/resources/resourcesSlice"; -import ResourcesProvider from "@/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesProvider"; -import FeaturesProvider from "@/app/(main)/my-voyage/[teamId]/features/components/FeaturesProvider"; -import IdeationProvider from "@/app/(main)/my-voyage/[teamId]/ideation/components/IdeationProvider"; -import TechStackProvider from "@/app/(main)/my-voyage/[teamId]/tech-stack/components/TechStackProvider"; import routePaths from "@/utils/routePaths"; import { type ErrorType } from "@/utils/error"; import ErrorComponent from "@/components/Error"; @@ -34,92 +17,92 @@ import ErrorComponent from "@/components/Error"; interface VoyageDashboardProps { teamId?: string; } -async function VoyageDashboard({ teamId }: VoyageDashboardProps) { - const [user, error] = await getUser(); +function VoyageDashboard({ teamId }: VoyageDashboardProps) { + // const [user, error] = await getUser(); - let currentSprintNumber: number | null = null; - let sprintsData: Sprint[] = []; - let meetingsData: Event[] = []; - let voyageNumber: number | null = null; - let voyageData: Voyage = {} as Voyage; - let features: FeaturesList[] = []; - let projectIdeas: IdeationData[] = []; - let techStackDatas: TechStackData[] = []; - let projectResources: ResourceData[] = []; + // let currentSprintNumber: number | null = null; + // let sprintsData: Sprint[] = []; + // let meetingsData: Event[] = []; + // let voyageNumber: number | null = null; + // let voyageData: Voyage = {} as Voyage; + // let features: FeaturesList[] = []; + // let projectIdeas: IdeationData[] = []; + // let techStackDatas: TechStackData[] = []; + // let projectResources: ResourceData[] = []; let errorMessage: string | undefined; let errorType: ErrorType | undefined; - if (teamId !== undefined) { - const data = await getDashboardData(user, error, Number(teamId)); - currentSprintNumber = data.currentSprintNumber; - sprintsData = data.sprintsData; - meetingsData = data.meetingsData; - voyageNumber = data.voyageNumber; - voyageData = data.voyageData; - features = data.features; - projectIdeas = data.projectIdeas.filter((idea) => idea.isSelected); - techStackDatas = data.techStackData.filter((tech) => tech.isSelected); - projectResources = data.projectResources; - errorMessage = data.errorMessage; - errorType = data.errorType; - } + // if (teamId !== undefined) { + // const data = await getDashboardData(user, error, Number(teamId)); + // currentSprintNumber = data.currentSprintNumber; + // sprintsData = data.sprintsData; + // meetingsData = data.meetingsData; + // voyageNumber = data.voyageNumber; + // voyageData = data.voyageData; + // features = data.features; + // projectIdeas = data.projectIdeas.filter((idea) => idea.isSelected); + // techStackDatas = data.techStackData.filter((tech) => tech.isSelected); + // projectResources = data.projectResources; + // errorMessage = data.errorMessage; + // errorType = data.errorType; + // } if (errorMessage && errorType) { return ; } - const featureList = features - .filter((item) => item.categoryName === "must have") - .flatMap((category) => - category.features.map((feature) => feature.description), - ); + // const featureList = features + // .filter((item) => item.categoryName === "must have") + // .flatMap((category) => + // category.features.map((feature) => feature.description), + // ); - const resourceList = projectResources.map((resource) => ({ - id: resource.id, - title: resource.title, - resourceUrl: resource.url, - userName: `${resource.addedBy.member.firstName} ${resource.addedBy.member.lastName}`, - userAvatarUrl: resource.addedBy.member.avatar, - })); + // const resourceList = projectResources.map((resource) => ({ + // id: resource.id, + // title: resource.title, + // resourceUrl: resource.url, + // userName: `${resource.addedBy.member.firstName} ${resource.addedBy.member.lastName}`, + // userAvatarUrl: resource.addedBy.member.avatar, + // })); - const iconMapping = { - Frontend: ComputerDesktopIcon, - "CSS Library": SwatchIcon, - Backend: CodeBracketSquareIcon, - "Project Management": ChartPieIcon, - "Cloud Provider": CloudIcon, - Hosting: ServerStackIcon, - }; + // const iconMapping = { + // Frontend: ComputerDesktopIcon, + // "CSS Library": SwatchIcon, + // Backend: CodeBracketSquareIcon, + // "Project Management": ChartPieIcon, + // "Cloud Provider": CloudIcon, + // Hosting: ServerStackIcon, + // }; - type TechStackName = - | "Frontend" - | "CSS Library" - | "Backend" - | "Project Management" - | "Cloud Provider" - | "Hosting"; + // type TechStackName = + // | "Frontend" + // | "CSS Library" + // | "Backend" + // | "Project Management" + // | "Cloud Provider" + // | "Hosting"; - const techStackList = techStackDatas.map((techStackData) => ({ - title: techStackData.name, - icon: iconMapping[techStackData.name as TechStackName], - value: techStackData.teamTechStackItems.map((item) => item.name).join(", "), - })); + // const techStackList = techStackDatas.map((techStackData) => ({ + // title: techStackData.name, + // icon: iconMapping[techStackData.name as TechStackName], + // value: techStackData.teamTechStackItems.map((item) => item.name).join(", "), + // })); return (
- - */} + {/* + /> */}
@@ -136,9 +119,9 @@ async function VoyageDashboard({ teamId }: VoyageDashboardProps) { buttonTitle="Go to Ideation" description="Share your ideas on what the team Voyage should be. Describe your vision and finalize your choice to capture what the benefit it will bring to users." > - {projectIdeas.length > 0 ? ( + {/* {projectIdeas.length > 0 ? ( - ) : null} + ) : null} */}
@@ -149,9 +132,9 @@ async function VoyageDashboard({ teamId }: VoyageDashboardProps) { buttonTitle="Go to Features" description="Brainstorm and prioritize the features that will be included in the scope of your project." > - {featureList.length > 0 ? ( + {/* {featureList.length > 0 ? ( - ) : null} + ) : null} */}
@@ -162,9 +145,9 @@ async function VoyageDashboard({ teamId }: VoyageDashboardProps) { buttonTitle="Go to Tech Stack" description="The final choices for the programming languages, frameworks, and tools that will serve as the foundation of your project will appear here." > - {techStackList.some((item) => item.value) ? ( + {/* {techStackList.some((item) => item.value) ? ( - ) : null} + ) : null} */}
@@ -177,17 +160,17 @@ async function VoyageDashboard({ teamId }: VoyageDashboardProps) { buttonTitle="Go to Resources" description="Share links of helpful resources to your team for the Voyage. Contribute to the collective knowledgebase to empower your team." > - {resourceList.length > 0 ? ( + {/* {resourceList.length > 0 ? ( - ) : null} + ) : null} */}
- + {/* - + */} ); } diff --git a/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts b/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts index 4e235a30..aee5baf9 100644 --- a/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts +++ b/src/app/(main)/dashboard/components/voyage-dashboard/getDashboardData.ts @@ -8,7 +8,7 @@ import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import { fetchResources } from "@/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesComponentWrapper"; import { fetchTechStack } from "@/app/(main)/my-voyage/[teamId]/tech-stack/components/TechStackComponentWrapper"; import { fetchProjectIdeas } from "@/app/(main)/my-voyage/[teamId]/ideation/components/IdeationComponentWrapper"; -import { fetchFeatures } from "@/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper"; +// import { fetchFeatures } from "@/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper"; import { type FeaturesList } from "@/store/features/features/featuresSlice"; import { type IdeationData } from "@/store/features/ideation/ideationSlice"; import { type TechStackData } from "@/store/features/techStack/techStackSlice"; @@ -23,7 +23,7 @@ interface GetDashboardDataResponse { meetingsData: Event[]; voyageNumber: number | null; voyageData: Voyage; - features: FeaturesList[]; + features?: FeaturesList[]; projectIdeas: IdeationData[]; techStackData: TechStackData[]; projectResources: ResourceData[]; @@ -147,13 +147,13 @@ export const getDashboardData = async ( let errorMessage: string | undefined; let errorType: ErrorType | undefined; const sprintsResult = await getSprintsData(user, error, teamId); - const featuresResult = await fetchData( - fetchFeatures, - user, - error, - teamId, - { teamId }, - ); + // const featuresResult = await fetchData( + // fetchFeatures, + // user, + // error, + // teamId, + // { teamId }, + // ); const projectIdeasResult = await fetchData< IdeationData[], { teamId: number } @@ -231,7 +231,7 @@ export const getDashboardData = async ( meetingsData, voyageNumber: sprintsResult.voyageNumber, voyageData: sprintsResult.voyageData, - features: featuresResult.data!, + // features: featuresResult.data!, projectIdeas: projectIdeasResult.data!, techStackData: techStackResult.data!, projectResources: resourcesResult.data!, diff --git a/src/app/(main)/dashboard/page.tsx b/src/app/(main)/dashboard/page.tsx index b13f10da..4f6c476a 100644 --- a/src/app/(main)/dashboard/page.tsx +++ b/src/app/(main)/dashboard/page.tsx @@ -1,3 +1,9 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ + import { redirect } from "next/navigation"; import { getUser } from "@/utils/getUser"; import routePaths from "@/utils/routePaths"; @@ -6,7 +12,7 @@ async function DashboardPage() { const [user] = await getUser(); const teamMember = user?.voyageTeamMembers.find( - (voyage) => voyage.voyageTeam.voyage.status.name === "Active", + (voyage: any) => voyage.voyageTeam.voyage.status.name === "Active", ); if (teamMember) { diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 70bcf1a5..2e750635 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -1,12 +1,14 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ "use client"; +import { useEffect, useState } from "react"; import Sidebar from "@/components/sidebar/Sidebar"; import Navbar from "@/components/navbar/Navbar"; import ModeToggle from "@/components/ModeToggle"; import AuthHeader from "@/components/navbar/AuthHeader"; import { getUser } from "@/utils/getUser"; import AuthProvider from "@/app/(auth)/AuthProvider"; -import { useEffect, useState } from "react"; interface LayoutProps { children: React.ReactNode; @@ -28,7 +30,7 @@ export default function Layout({ children }: LayoutProps) { return (
- + <> diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx index abadf347..d502c9f3 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/DirectoryComponentWrapper.tsx @@ -1,33 +1,20 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ "use client"; -import { redirect } from "next/navigation"; - -import DirectoryProvider from "./DirectoryProvider"; +import { useEffect, useState } from "react"; import TeamMember from "./TeamMember"; - import Banner from "@/components/banner/Banner"; -import ErrorComponent from "@/components/Error"; - import { type TeamDirectory } from "@/store/features/directory/directorySlice"; - -import { getAccessToken } from "@/utils/getCookie"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; -import { GET } from "@/utils/requests"; -import { CacheTag } from "@/utils/cacheTag"; -import { type User } from "@/store/features/user/userSlice"; -import { getUser } from "@/utils/getUser"; -import { getTimezone } from "@/utils/getTimezone"; +// import { type User } from "@/store/features/user/userSlice"; import VoyagePageBannerContainer from "@/components/banner/VoyagePageBannerContainer"; -import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; -import { ErrorType } from "@/utils/error"; -import { useEffect, useState } from "react"; -import axios from "axios"; import { axiosInstance } from "@/utils/axiosInstance"; -interface FetchTeamDirectoryProps { - teamId: number; - user: User | null; -} +// interface FetchTeamDirectoryProps { +// teamId: number; +// user: User | null; +// } // export async function fetchTeamDirectory({ // teamId, @@ -104,7 +91,7 @@ export default function DirectoryComponentWrapper({ const response = await axiosInstance.get(`/api/v1/teams/${teamId}`); return response.data; - } catch (error) { + } catch (error: any) { throw Error(error); } }; diff --git a/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx b/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx index cbf23099..3bbf50ca 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/components/EditHours.tsx @@ -6,9 +6,9 @@ import { PencilSquareIcon } from "@heroicons/react/24/outline"; import { type SetStateAction, useEffect } from "react"; import TextInput from "@/components/inputs/TextInput"; import { validateTextInput } from "@/utils/form/validateInput"; -import { useAppDispatch } from "@/store/hooks"; +// import { useAppDispatch } from "@/store/hooks"; import { editHours } from "@/app/(main)/my-voyage/[teamId]/directory/directoryService"; -import { onOpenModal } from "@/store/features/modal/modalSlice"; +// import { onOpenModal } from "@/store/features/modal/modalSlice"; import useServerAction from "@/hooks/useServerAction"; import Spinner from "@/components/Spinner"; import Button from "@/components/Button"; @@ -34,17 +34,17 @@ type ValidationSchema = z.infer; export default function EditHours({ hrPerSprint, isEditing, - setIsEditing, + // setIsEditing, handleClick, }: EditHoursProps) { const params = useParams<{ teamId: string }>(); const teamId = Number(params.teamId); - const dispatch = useAppDispatch(); + // const dispatch = useAppDispatch(); const { - runAction: editHoursAction, + // runAction: editHoursAction, isLoading: editHoursLoading, - setIsLoading: setEditHoursLoading, + // setIsLoading: setEditHoursLoading, } = useServerAction(editHours); const { diff --git a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx index e3b6965b..f1544888 100644 --- a/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/features/components/FeaturesComponentWrapper.tsx @@ -1,28 +1,16 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ "use client"; -import { redirect } from "next/navigation"; - -import FeaturesProvider from "./FeaturesProvider"; +import { useEffect, useState } from "react"; import FeaturesContainer from "./FeaturesContainer"; import VoyagePageBannerContainer from "@/components/banner/VoyagePageBannerContainer"; import Banner from "@/components/banner/Banner"; -import ErrorComponent from "@/components/Error"; - import { type Features, type FeaturesList, } from "@/store/features/features/featuresSlice"; - -import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; -import { getUser } from "@/utils/getUser"; -import { getAccessToken } from "@/utils/getCookie"; -import { GET } from "@/utils/requests"; -import { CacheTag } from "@/utils/cacheTag"; -import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; -import { ErrorType } from "@/utils/error"; -import { useEffect, useState } from "react"; -import axios from "axios"; -import { features } from "process"; import { axiosInstance } from "@/utils/axiosInstance"; function transformData(features: Features[]): FeaturesList[] { @@ -77,9 +65,9 @@ function transformData(features: Features[]): FeaturesList[] { return transformedData; } -interface FetchFeaturesProps { - teamId: number; -} +// interface FetchFeaturesProps { +// teamId: number; +// } // export async function fetchFeatures({ // teamId, @@ -126,7 +114,7 @@ export default function FeaturesComponentWrapper({ ); return response.data; - } catch (error) { + } catch (error: any) { throw Error(error); } }; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx index fc21649b..b4296357 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/WeeklyCheckInWrapper.tsx @@ -1,9 +1,14 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { redirect } from "next/navigation"; import { fetchSprints } from "./RedirectToCurrentSprintWrapper"; import WeeklyCheckInForm from "./forms/WeeklyCheckInForm"; -import { fetchTeamDirectory } from "@/myVoyage/directory/components/DirectoryComponentWrapper"; +// import { fetchTeamDirectory } from "@/myVoyage/directory/components/DirectoryComponentWrapper"; import { type Sprint, type Voyage } from "@/store/features/sprint/sprintSlice"; import { getAccessToken } from "@/utils/getCookie"; import { getUser } from "@/utils/getUser"; @@ -13,10 +18,9 @@ import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync"; import { getCurrentVoyageData } from "@/utils/getCurrentVoyageData"; import routePaths from "@/utils/routePaths"; import { Forms } from "@/utils/form/formsEnums"; -import { type Question, type TeamMemberForCheckbox } from "@/utils/form/types"; +import { type Question } from "@/utils/form/types"; import { getSprintCheckinIsStatus } from "@/utils/getFormStatus"; import { getCurrentSprint } from "@/utils/getCurrentSprint"; -import { getCurrentVoyageTeam } from "@/utils/getCurrentVoyageTeam"; import { ErrorType } from "@/utils/error"; import ErrorComponent from "@/components/Error"; @@ -70,7 +74,7 @@ export default async function WeeklyCheckInWrapper({ const teamId = Number(params.teamId); let voyageData: Voyage; - let teamMembers = [] as TeamMemberForCheckbox[]; + // let teamMembers = [] as TeamMemberForCheckbox[]; let description = ""; let questions = [] as Question[]; @@ -130,38 +134,38 @@ export default async function WeeklyCheckInWrapper({ } // Fetch teamDirectory - const [res, error] = await fetchTeamDirectory({ teamId, user }); - if (res) { - let voyageTeamMemberId: number | undefined; - if (user && user.voyageTeamMembers) { - voyageTeamMemberId = getCurrentVoyageTeam({ - teamId, - user, - error, - }).voyageTeamMemberId; - } - - // Get all teamMembers except for the current user - if (voyageTeamMemberId) { - teamMembers = res.voyageTeamMembers - .map((member) => ({ - id: member.id, - avatar: member.member.avatar, - firstName: member.member.firstName, - lastName: member.member.lastName, - })) - .filter((member) => member.id !== voyageTeamMemberId); - } - } - - if (error) { - return ( - - ); - } + // const [res, error] = await fetchTeamDirectory({ teamId, user }); + // if (res) { + // let voyageTeamMemberId: number | undefined; + // if (user && user.voyageTeamMembers) { + // voyageTeamMemberId = getCurrentVoyageTeam({ + // teamId, + // user, + // error, + // }).voyageTeamMemberId; + // } + + // // Get all teamMembers except for the current user + // if (voyageTeamMemberId) { + // teamMembers = res.voyageTeamMembers + // .map((member: any) => ({ + // id: member.id, + // avatar: member.member.avatar, + // firstName: member.member.firstName, + // lastName: member.member.lastName, + // })) + // .filter((member: any) => member.id !== voyageTeamMemberId); + // } + // } + + // if (error) { + // return ( + // + // ); + // } // Fetch form const [formRes, formError] = await fetchFormQuestions({ @@ -188,7 +192,6 @@ export default async function WeeklyCheckInWrapper({ params={params} description={description} questions={questions} - teamMembers={teamMembers} /> ); } diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/forms/WeeklyCheckInForm.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/forms/WeeklyCheckInForm.tsx index 3eed30fb..c305a557 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/forms/WeeklyCheckInForm.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/forms/WeeklyCheckInForm.tsx @@ -28,7 +28,7 @@ interface WeeklyCheckingFormProps { }; description: string; questions: Question[]; - teamMembers: TeamMemberForCheckbox[]; + teamMembers?: TeamMemberForCheckbox[]; } export default function WeeklyCheckingForm({ diff --git a/src/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesComponentWrapper.tsx index 96c4b06a..ea74209a 100644 --- a/src/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/voyage-resources/components/ResourcesComponentWrapper.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { redirect } from "next/navigation"; import ResourcesContainer from "./ResourcesContainer"; import ResourcesProvider from "./ResourcesProvider"; diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index 92bf3ca0..9481498c 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -1,6 +1,6 @@ "use client"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { usePathname } from "next/navigation"; import { RectangleGroupIcon, @@ -11,7 +11,7 @@ import { import PageButton from "./PageButton"; import VoyagePageButton from "./VoyagePageButton"; import ExpandButton from "./ExpandButton"; -import { useAuth, useUser } from "@/store/hooks"; +import { useUser } from "@/store/hooks"; import routePaths from "@/utils/routePaths"; export enum MainPages { @@ -81,19 +81,19 @@ export default function Sidebar() { const [selectedButton, setSelectedButton] = useState(currentPath); const [hoveredButton, setHoveredButton] = useState(null); - const { isAuthenticated } = useAuth(); + // const { isAuthenticated } = useAuth(); const { voyageTeamMembers } = useUser(); - const isActive = useMemo(() => { - if (voyageTeamMembers.length === 0) { - return false; - } - return voyageTeamMembers.some( - (member) => member.voyageTeam.voyage.status.name === "Active", - ); - }, [voyageTeamMembers]); + // const isActive = useMemo(() => { + // if (voyageTeamMembers.length === 0) { + // return false; + // } + // return voyageTeamMembers.some( + // (member) => member.voyageTeam.voyage.status.name === "Active", + // ); + // }, [voyageTeamMembers]); - const isVoyageStarted: boolean = isAuthenticated && isActive; + // const isVoyageStarted: boolean = isAuthenticated && isActive; const currentVoyageTeam = voyageTeamMembers.find( (voyage) => voyage.voyageTeam.voyage.status.name === "Active", diff --git a/src/middleware.ts b/src/middleware.ts index a63745c4..5dde193d 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,7 +1,3 @@ -import { NextResponse } from "next/server"; -import type { NextRequest } from "next/server"; -import { getRefreshToken } from "./utils/getCookie"; - export async function middleware() { // if (request.cookies.has("refresh_token")) { // if (request.cookies.has("access_token")) { diff --git a/src/utils/getUser.ts b/src/utils/getUser.ts index b72b9231..9d657a7f 100644 --- a/src/utils/getUser.ts +++ b/src/utils/getUser.ts @@ -1,8 +1,7 @@ -import axios from "axios"; -import { getAccessToken } from "./getCookie"; -import { type AsyncActionResponse, handleAsync } from "./handleAsync"; -import { GET } from "./requests"; -import { type User } from "@/store/features/user/userSlice"; +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { axiosInstance } from "./axiosInstance"; export async function getUser() { @@ -10,7 +9,7 @@ export async function getUser() { const response = await axiosInstance.get("/api/v1/users/me"); return response.data; - } catch (error) { + } catch (error: any) { throw Error(error); } From 011d00f37f0f7288c85596fa22c92a0ba15e9124 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Fri, 4 Oct 2024 03:45:17 -0400 Subject: [PATCH 12/18] fix issue with dashboard page --- src/app/(main)/dashboard/page.tsx | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/app/(main)/dashboard/page.tsx b/src/app/(main)/dashboard/page.tsx index 4f6c476a..dd57002e 100644 --- a/src/app/(main)/dashboard/page.tsx +++ b/src/app/(main)/dashboard/page.tsx @@ -4,22 +4,18 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { redirect } from "next/navigation"; -import { getUser } from "@/utils/getUser"; -import routePaths from "@/utils/routePaths"; +function DashboardPage() { + // const [user] = await getUser(); -async function DashboardPage() { - const [user] = await getUser(); + // const teamMember = user?.voyageTeamMembers.find( + // (voyage: any) => voyage.voyageTeam.voyage.status.name === "Active", + // ); - const teamMember = user?.voyageTeamMembers.find( - (voyage: any) => voyage.voyageTeam.voyage.status.name === "Active", - ); - - if (teamMember) { - redirect( - routePaths.VoyageMemberDashboardPage(teamMember?.voyageTeamId.toString()), - ); - } + // if (teamMember) { + // redirect( + // routePaths.VoyageMemberDashboardPage(teamMember?.voyageTeamId.toString()), + // ); + // } return
Default Dashboard
; } From d142164d1458cefefc7ce8f516e58ea0d103456e Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Fri, 4 Oct 2024 03:53:28 -0400 Subject: [PATCH 13/18] fix build errors --- .../my-voyage/[teamId]/sprints/components/SprintWrapper.tsx | 2 ++ .../[teamId]/sprints/components/SubmitProjectWrapper.tsx | 1 + .../tech-stack/components/TechStackComponentWrapper.tsx | 1 + src/app/(main)/my-voyage/[teamId]/tech-stack/finalize/page.tsx | 1 + 4 files changed, 5 insertions(+) diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx index 4f9e7a93..ed1f05a3 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/SprintWrapper.tsx @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { redirect } from "next/navigation"; import ProgressStepper from "./ProgressStepper"; diff --git a/src/app/(main)/my-voyage/[teamId]/sprints/components/SubmitProjectWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/sprints/components/SubmitProjectWrapper.tsx index 8f69b247..fd8effdc 100644 --- a/src/app/(main)/my-voyage/[teamId]/sprints/components/SubmitProjectWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/sprints/components/SubmitProjectWrapper.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { redirect } from "next/navigation"; import { fetchFormQuestions } from "./WeeklyCheckInWrapper"; diff --git a/src/app/(main)/my-voyage/[teamId]/tech-stack/components/TechStackComponentWrapper.tsx b/src/app/(main)/my-voyage/[teamId]/tech-stack/components/TechStackComponentWrapper.tsx index de8d107b..b022a18d 100644 --- a/src/app/(main)/my-voyage/[teamId]/tech-stack/components/TechStackComponentWrapper.tsx +++ b/src/app/(main)/my-voyage/[teamId]/tech-stack/components/TechStackComponentWrapper.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { redirect } from "next/navigation"; import TechStackContainer from "./TechStackContainer"; import TechStackProvider from "./TechStackProvider"; diff --git a/src/app/(main)/my-voyage/[teamId]/tech-stack/finalize/page.tsx b/src/app/(main)/my-voyage/[teamId]/tech-stack/finalize/page.tsx index c9c86362..67fc1cf8 100644 --- a/src/app/(main)/my-voyage/[teamId]/tech-stack/finalize/page.tsx +++ b/src/app/(main)/my-voyage/[teamId]/tech-stack/finalize/page.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { redirect } from "next/navigation"; import FinalizeTechBanner from "./FinalizeTechBanner"; import FinalizeTechList from "./FinalizeTechList"; From 0ba63b6c2136c0fb21491c02a27deaa396a84bf5 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Fri, 4 Oct 2024 03:59:28 -0400 Subject: [PATCH 14/18] turn off ts eslint temp --- .eslintrc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 1c82a974..dee535cb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,12 +8,12 @@ "ecmaVersion": "latest", "sourceType": "module" }, - "plugins": ["@typescript-eslint", "import", "no-relative-import-paths"], + "plugins": [/*"@typescript-eslint" */ "import", "no-relative-import-paths"], "extends": [ "plugin:import/recommended", "plugin:import/typescript", "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", + // "plugin:@typescript-eslint/recommended-requiring-type-checking", "next/core-web-vitals", "prettier", "plugin:tailwindcss/recommended", From 8090e988383de6e2699576591b2c95c58817a6b0 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 17 Oct 2024 12:40:16 -0400 Subject: [PATCH 15/18] fix issue with auth not working properly when refreshing page --- src/app/(auth)/AuthProvider.tsx | 4 +- src/app/(main)/layout.tsx | 37 +++++++++++++++---- .../my-voyage/[teamId]/directory/page.tsx | 8 +--- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/app/(auth)/AuthProvider.tsx b/src/app/(auth)/AuthProvider.tsx index f5b51f2a..7c2c6bd3 100644 --- a/src/app/(auth)/AuthProvider.tsx +++ b/src/app/(auth)/AuthProvider.tsx @@ -9,8 +9,8 @@ import { type AppError } from "@/types/types"; import { currentDate } from "@/utils/getCurrentSprint"; interface AuthProviderProps { - user: User | null; - error: AppError | null; + user?: User | null; + error?: AppError | null; } export default function AuthProvider({ user, error }: AuthProviderProps) { diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 2e750635..74c098a9 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -3,34 +3,55 @@ "use client"; import { useEffect, useState } from "react"; +import { formatInTimeZone } from "date-fns-tz"; import Sidebar from "@/components/sidebar/Sidebar"; import Navbar from "@/components/navbar/Navbar"; import ModeToggle from "@/components/ModeToggle"; import AuthHeader from "@/components/navbar/AuthHeader"; import { getUser } from "@/utils/getUser"; import AuthProvider from "@/app/(auth)/AuthProvider"; +import { useAppDispatch, useAuth, useUser } from "@/store/hooks"; +import { clientSignIn } from "@/store/features/auth/authSlice"; +import { currentDate } from "@/utils/getCurrentSprint"; +import { getUserState } from "@/store/features/user/userSlice"; interface LayoutProps { children: React.ReactNode; } export default function Layout({ children }: LayoutProps) { - const [user, setUser] = useState(); - const [error, setError] = useState(); + const dispatch = useAppDispatch(); + const { isAuthenticated } = useAuth(); useEffect(() => { const fetchUser = async () => await getUser(); fetchUser() - .then((data) => setUser(data)) + .then((data) => { + dispatch(clientSignIn()); + // Add the currentDate field to the user object + const currentDateInUserTimezone = formatInTimeZone( + currentDate, + data.timezone, + "yyyy-MM-dd HH:mm:ss", + ); + + const userWithDate = { + ...data, + currentDate: new Date(currentDateInUserTimezone), + }; + // Dispatch the getUserState action with the user object + dispatch(getUserState(userWithDate)); + }) .catch((err) => { - setError(err); + // eslint-disable-next-line no-console + console.log(err); }); - }, []); + }, [dispatch]); - return ( + return isAuthenticated ? (
- + {/* */} <> @@ -48,5 +69,5 @@ export default function Layout({ children }: LayoutProps) {
- ); + ) : null; } diff --git a/src/app/(main)/my-voyage/[teamId]/directory/page.tsx b/src/app/(main)/my-voyage/[teamId]/directory/page.tsx index 9c57d3bc..af967abe 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/page.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/page.tsx @@ -9,11 +9,5 @@ interface DirectoryPageProps { } export default function DirectoryPage({ params }: DirectoryPageProps) { - return ( - <> - }> - - - - ); + return ; } From 323ba678950a928852b1665f55f2c6ae42bb695f Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 17 Oct 2024 12:43:53 -0400 Subject: [PATCH 16/18] fix lint errors --- src/app/(main)/layout.tsx | 5 ++--- src/app/(main)/my-voyage/[teamId]/directory/page.tsx | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 74c098a9..14f953be 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -2,15 +2,14 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ "use client"; -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import { formatInTimeZone } from "date-fns-tz"; import Sidebar from "@/components/sidebar/Sidebar"; import Navbar from "@/components/navbar/Navbar"; import ModeToggle from "@/components/ModeToggle"; import AuthHeader from "@/components/navbar/AuthHeader"; import { getUser } from "@/utils/getUser"; -import AuthProvider from "@/app/(auth)/AuthProvider"; -import { useAppDispatch, useAuth, useUser } from "@/store/hooks"; +import { useAppDispatch, useAuth } from "@/store/hooks"; import { clientSignIn } from "@/store/features/auth/authSlice"; import { currentDate } from "@/utils/getCurrentSprint"; import { getUserState } from "@/store/features/user/userSlice"; diff --git a/src/app/(main)/my-voyage/[teamId]/directory/page.tsx b/src/app/(main)/my-voyage/[teamId]/directory/page.tsx index af967abe..77094378 100644 --- a/src/app/(main)/my-voyage/[teamId]/directory/page.tsx +++ b/src/app/(main)/my-voyage/[teamId]/directory/page.tsx @@ -1,6 +1,4 @@ -import { Suspense } from "react"; import DirectoryComponentWrapper from "./components/DirectoryComponentWrapper"; -import Spinner from "@/components/Spinner"; interface DirectoryPageProps { params: { From 76607c6a5e4a7a322b58b09dbefbc82db5e2a210 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 17 Oct 2024 12:50:44 -0400 Subject: [PATCH 17/18] redirect users to login page if no token exists --- src/app/(main)/layout.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 14f953be..4af4db7f 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -4,6 +4,7 @@ import { useEffect } from "react"; import { formatInTimeZone } from "date-fns-tz"; +import { useRouter } from "next/navigation"; import Sidebar from "@/components/sidebar/Sidebar"; import Navbar from "@/components/navbar/Navbar"; import ModeToggle from "@/components/ModeToggle"; @@ -13,6 +14,7 @@ import { useAppDispatch, useAuth } from "@/store/hooks"; import { clientSignIn } from "@/store/features/auth/authSlice"; import { currentDate } from "@/utils/getCurrentSprint"; import { getUserState } from "@/store/features/user/userSlice"; +import routePaths from "@/utils/routePaths"; interface LayoutProps { children: React.ReactNode; @@ -21,6 +23,7 @@ interface LayoutProps { export default function Layout({ children }: LayoutProps) { const dispatch = useAppDispatch(); const { isAuthenticated } = useAuth(); + const router = useRouter(); useEffect(() => { const fetchUser = async () => await getUser(); @@ -44,9 +47,9 @@ export default function Layout({ children }: LayoutProps) { }) .catch((err) => { // eslint-disable-next-line no-console - console.log(err); + router.push(routePaths.signIn()); }); - }, [dispatch]); + }, [dispatch, router]); return isAuthenticated ? (
From 03b331e46b37fdc2db154929962b430e893ffc09 Mon Sep 17 00:00:00 2001 From: Dan Ko Date: Thu, 17 Oct 2024 12:50:59 -0400 Subject: [PATCH 18/18] fix lint errors --- src/app/(main)/layout.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 4af4db7f..a245a32f 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -45,8 +45,7 @@ export default function Layout({ children }: LayoutProps) { // Dispatch the getUserState action with the user object dispatch(getUserState(userWithDate)); }) - .catch((err) => { - // eslint-disable-next-line no-console + .catch(() => { router.push(routePaths.signIn()); }); }, [dispatch, router]);