diff --git a/.eslintrc.json b/.eslintrc.json
index bffb357a7..10a3fc345 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,3 +1,19 @@
{
- "extends": "next/core-web-vitals"
+ "env": {
+ "browser": true,
+ "es2021": true
+ },
+ "extends": [
+ "google",
+ "plugin:react/recommended"
+ ],
+ "parserOptions": {
+ "ecmaVersion": "latest",
+ "sourceType": "module"
+ },
+ "plugins": [
+ "react"
+ ],
+ "rules": {
+ }
}
diff --git a/components/Input/Input.jsx b/components/Input/Input.jsx
index fa126e2a6..1265e4a65 100644
--- a/components/Input/Input.jsx
+++ b/components/Input/Input.jsx
@@ -1,30 +1,55 @@
-// Input.jsx
-
-import React, { forwardRef } from "react";
import classNames from "classnames";
import styles from "./Input.module.css";
+import Image from "next/image";
-const Input = forwardRef(
- ({ state, type = "text", placeholder, errorMessage, ...props }, ref) => {
- const combinedStyles = classNames(styles["input-base"], {
- [styles["input-state"]]: state === "error",
- });
-
- return (
- <>
+const Input = ({
+ label,
+ type,
+ error,
+ placeholder,
+ id,
+ value,
+ onKeyPress,
+ onChangeType,
+ onChange,
+ defaultValue,
+ registerConfig,
+}) => {
+ return (
+ <>
+
+
-
-
-
-
+
+
+
+
+
+ {userProfile ? (
-
+
-
codiet@email.com
+
{userProfile.email}
-
+ ) : (
+
+
로그인
+
+ )}
- >
+
);
}
diff --git a/components/SearchBar/SearchBar.jsx b/components/SearchBar/SearchBar.jsx
index 952086b0b..667b221d7 100644
--- a/components/SearchBar/SearchBar.jsx
+++ b/components/SearchBar/SearchBar.jsx
@@ -13,7 +13,7 @@ export const SearchBar = ({ value, onChange, onCloseClick }) => {
diff --git a/lib/axios.js b/lib/axios.js
new file mode 100644
index 000000000..3e6feb6a5
--- /dev/null
+++ b/lib/axios.js
@@ -0,0 +1 @@
+export const BASE_URL = " https://bootcamp-api.codeit.kr/api/linkbrary/v1";
diff --git a/lib/axious.js b/lib/axious.js
deleted file mode 100644
index 814bd9490..000000000
--- a/lib/axious.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import axios from "axios";
-
-const instance = axios.create({
- baseURL: "https://bootcamp-api.codeit.kr/api/",
-});
-
-export default instance;
diff --git a/package-lock.json b/package-lock.json
index fe0000046..5688b8f4e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,20 +9,27 @@
"version": "0.1.0",
"dependencies": {
"@hookform/resolvers": "^3.3.4",
+ "@tanstack/react-query": "^5.22.2",
+ "@tanstack/react-query-devtools": "^5.24.0",
"axios": "^1.6.5",
"classnames": "^2.5.1",
"next": "13.5.6",
+ "nookies": "^2.5.2",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.49.3",
+ "react-query": "^3.39.3",
+ "react-router-dom": "^6.22.1",
"yup": "^1.3.3"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
- "eslint": "^8",
+ "eslint": "^8.56.0",
+ "eslint-config-google": "^0.14.0",
"eslint-config-next": "13.5.6",
+ "eslint-plugin-react": "^7.33.2",
"typescript": "^5"
}
},
@@ -36,10 +43,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz",
- "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==",
- "dev": true,
+ "version": "7.23.9",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
+ "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -72,9 +78,9 @@
}
},
"node_modules/@eslint/eslintrc": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz",
- "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
@@ -95,9 +101,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz",
- "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==",
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
+ "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -328,6 +334,14 @@
"node": ">= 8"
}
},
+ "node_modules/@remix-run/router": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz",
+ "integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@rushstack/eslint-patch": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz",
@@ -342,6 +356,55 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@tanstack/query-core": {
+ "version": "5.22.2",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.22.2.tgz",
+ "integrity": "sha512-z3PwKFUFACMUqe1eyesCIKg3Jv1mysSrYfrEW5ww5DCDUD4zlpTKBvUDaEjsfZzL3ULrFLDM9yVUxI/fega1Qg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/query-devtools": {
+ "version": "5.24.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.24.0.tgz",
+ "integrity": "sha512-pThim455t69zrZaQKa7IRkEIK8UBTS+gHVAdNfhO72Xh4rWpMc63ovRje5/n6iw63+d6QiJzVadsJVdPoodSeQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.22.2",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.22.2.tgz",
+ "integrity": "sha512-TaxJDRzJ8/NWRT4lY2jguKCrNI6MRN+67dELzPjNUlvqzTxGANlMp68l7aC7hG8Bd1uHNxHl7ihv7MT50i/43A==",
+ "dependencies": {
+ "@tanstack/query-core": "5.22.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0"
+ }
+ },
+ "node_modules/@tanstack/react-query-devtools": {
+ "version": "5.24.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.24.0.tgz",
+ "integrity": "sha512-ae3TSg9hKSicLP6TZMj4hglLsLBaS8O3ex/mgHZNQ8yKCDLnVoLO1a9EqYWPzw2k+uaK5uMCKBAVbLVBLx93oA==",
+ "dependencies": {
+ "@tanstack/query-devtools": "5.24.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "@tanstack/react-query": "^5.22.2",
+ "react": "^18.0.0"
+ }
+ },
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -498,9 +561,9 @@
"dev": true
},
"node_modules/acorn": {
- "version": "8.11.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
- "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==",
+ "version": "8.11.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+ "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -766,14 +829,20 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/big-integer": {
+ "version": "1.6.52",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
+ "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
+ "engines": {
+ "node": ">=0.6"
+ }
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -791,6 +860,21 @@
"node": ">=8"
}
},
+ "node_modules/broadcast-channel": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
+ "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
+ "dependencies": {
+ "@babel/runtime": "^7.7.2",
+ "detect-node": "^2.1.0",
+ "js-sha3": "0.8.0",
+ "microseconds": "0.2.0",
+ "nano-time": "1.0.0",
+ "oblivious-set": "1.0.0",
+ "rimraf": "3.0.2",
+ "unload": "2.2.0"
+ }
+ },
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -902,8 +986,15 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "node_modules/cookie": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
+ "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
},
"node_modules/cross-spawn": {
"version": "7.0.3",
@@ -1002,6 +1093,11 @@
"node": ">=6"
}
},
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
+ },
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -1173,15 +1269,15 @@
}
},
"node_modules/eslint": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz",
- "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==",
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
+ "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.3",
- "@eslint/js": "8.54.0",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.56.0",
"@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -1227,6 +1323,18 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint-config-google": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz",
+ "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=5.16.0"
+ }
+ },
"node_modules/eslint-config-next": {
"version": "13.5.6",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.5.6.tgz",
@@ -1741,8 +1849,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/function-bind": {
"version": "1.1.2",
@@ -1827,7 +1934,6 @@
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
- "dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -1861,9 +1967,9 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
},
"node_modules/globals": {
- "version": "13.23.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
- "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
@@ -2052,7 +2158,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -2061,8 +2166,7 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/internal-slot": {
"version": "1.0.6",
@@ -2417,6 +2521,11 @@
"set-function-name": "^2.0.1"
}
},
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2563,6 +2672,15 @@
"node": ">=10"
}
},
+ "node_modules/match-sorter": {
+ "version": "6.3.4",
+ "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz",
+ "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.8",
+ "remove-accents": "0.5.0"
+ }
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -2585,6 +2703,11 @@
"node": ">=8.6"
}
},
+ "node_modules/microseconds": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
+ "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -2608,7 +2731,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -2631,6 +2753,14 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
+ "node_modules/nano-time": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
+ "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==",
+ "dependencies": {
+ "big-integer": "^1.6.16"
+ }
+ },
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -2699,6 +2829,15 @@
}
}
},
+ "node_modules/nookies": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/nookies/-/nookies-2.5.2.tgz",
+ "integrity": "sha512-x0TRSaosAEonNKyCrShoUaJ5rrT5KHRNZ5DwPCuizjgrnkpE5DRf3VL7AyyQin4htict92X1EQ7ejDbaHDVdYA==",
+ "dependencies": {
+ "cookie": "^0.4.1",
+ "set-cookie-parser": "^2.4.6"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -2817,11 +2956,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/oblivious-set": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
+ "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
"dependencies": {
"wrappy": "1"
}
@@ -2898,7 +3041,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3075,6 +3217,61 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true
},
+ "node_modules/react-query": {
+ "version": "3.39.3",
+ "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
+ "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "broadcast-channel": "^3.4.1",
+ "match-sorter": "^6.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router": {
+ "version": "6.22.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz",
+ "integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==",
+ "dependencies": {
+ "@remix-run/router": "1.15.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.22.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz",
+ "integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==",
+ "dependencies": {
+ "@remix-run/router": "1.15.1",
+ "react-router": "6.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
@@ -3098,8 +3295,7 @@
"node_modules/regenerator-runtime": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
- "dev": true
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.1",
@@ -3118,6 +3314,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/remove-accents": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
+ "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="
+ },
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@@ -3167,7 +3368,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@@ -3256,6 +3456,11 @@
"node": ">=10"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
+ "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ=="
+ },
"node_modules/set-function-length": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
@@ -3678,6 +3883,15 @@
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
},
+ "node_modules/unload": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
+ "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
+ "dependencies": {
+ "@babel/runtime": "^7.6.2",
+ "detect-node": "^2.0.4"
+ }
+ },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -3793,8 +4007,7 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/yallist": {
"version": "4.0.0",
diff --git a/package.json b/package.json
index dd44e6b8f..75dbb5f6d 100644
--- a/package.json
+++ b/package.json
@@ -10,20 +10,27 @@
},
"dependencies": {
"@hookform/resolvers": "^3.3.4",
+ "@tanstack/react-query": "^5.22.2",
+ "@tanstack/react-query-devtools": "^5.24.0",
"axios": "^1.6.5",
"classnames": "^2.5.1",
"next": "13.5.6",
+ "nookies": "^2.5.2",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.49.3",
+ "react-query": "^3.39.3",
+ "react-router-dom": "^6.22.1",
"yup": "^1.3.3"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
- "eslint": "^8",
+ "eslint": "^8.56.0",
+ "eslint-config-google": "^0.14.0",
"eslint-config-next": "13.5.6",
+ "eslint-plugin-react": "^7.33.2",
"typescript": "^5"
}
}
diff --git a/pages/_app.jsx b/pages/_app.jsx
index b97e52fc9..68c993cd8 100644
--- a/pages/_app.jsx
+++ b/pages/_app.jsx
@@ -1,5 +1,14 @@
-import "@/styles/globals.css";
+import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+
+const queryClient = new QueryClient();
export default function App({ Component, pageProps }) {
- return
;
+ return (
+
+
+
+
+
+ );
}
diff --git a/pages/api/auth/folder-api.jsx b/pages/api/auth/folder-api.jsx
new file mode 100644
index 000000000..1cd997b23
--- /dev/null
+++ b/pages/api/auth/folder-api.jsx
@@ -0,0 +1,35 @@
+import axios from "axios";
+import { BASE_URL } from "../../../lib/axios";
+import { parseCookies } from "nookies";
+
+export async function fetchUserProfile() {
+ // const { accessToken } = parseCookies();
+ const { accessToken } =
+ "eyJhbGciOiJIUzI1NiIsImtpZCI6IktLNE05TGFmMXkzWEI0M0kiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzA5NDU5MTc1LCJpYXQiOjE3MDg4NTQzNzUsImlzcyI6Imh0dHBzOi8vanB2ZG9weWdibHJlZnpvbmV2ZnEuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImRmNmZhYWEzLWI4MjItNDU2YS1iYzM4LTUzNDQ1ZDczODI1MyIsImVtYWlsIjoianNvNDA5M0BuYXZlci5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcwODg1NDM3NX1dLCJzZXNzaW9uX2lkIjoiNTgyNTE1NjMtN2EzNi00MmY2LWFiZDktZjljOGVmNGFmYzY4In0.SRLLJtMF9RZPUyWnlmdc30mdvBGz0MpptG5ABLw70SI";
+ console.log("accessToken:", accessToken); // accessToken 확인
+
+ try {
+ if (!accessToken) {
+ throw new Error("인증 토큰이 없습니다.");
+ }
+
+ const config = {
+ headers: {
+ Authorization: `Bearer ${accessToken}`,
+ },
+ };
+
+ console.log("config:", config); // config 확인
+
+ const response = await axios.get(`${BASE_URL}/users/{userId}`, config);
+ console.log("response:", response); // response 확인
+
+ return response.data;
+ } catch (error) {
+ console.error("fetchUserProfile 오류:", error); // 오류 확인
+ throw new Error(
+ error.response?.data?.message ||
+ "사용자 프로필을 가져오는 중 오류가 발생했습니다."
+ );
+ }
+}
diff --git a/pages/api/auth/signin-api.jsx b/pages/api/auth/signin-api.jsx
new file mode 100644
index 000000000..444674d7f
--- /dev/null
+++ b/pages/api/auth/signin-api.jsx
@@ -0,0 +1,22 @@
+import { BASE_URL } from "../../../lib/axios";
+import axios from "axios";
+export async function loginUser(email, password) {
+ try {
+ const response = await axios.post(`${BASE_URL}/auth/sign-in`, {
+ email,
+ password,
+ });
+
+ // 응답 객체가 존재하고, data 속성이 있는지 확인
+ if (response && response.data) {
+ return response.data;
+ } else {
+ throw new Error("응답 데이터가 유효하지 않습니다.");
+ }
+ } catch (error) {
+ // 응답이 오류인 경우
+ throw new Error(
+ error.response?.data?.message || "로그인 중 오류가 발생했습니다."
+ );
+ }
+}
diff --git a/pages/api/auth/signup-api.jsx b/pages/api/auth/signup-api.jsx
new file mode 100644
index 000000000..0e3221819
--- /dev/null
+++ b/pages/api/auth/signup-api.jsx
@@ -0,0 +1,25 @@
+import { BASE_URL } from "../../../lib/axios";
+import axios from "axios";
+
+export async function registerUser(email, password) {
+ try {
+ const response = await axios.post(`${BASE_URL}/auth/sign-up`, {
+ email,
+ password,
+ });
+ return response.data;
+ } catch (error) {
+ throw new Error(error.response.data.message);
+ }
+}
+
+export async function AvailableEmail(email) {
+ try {
+ const response = await axios.post(`${BASE_URL}/users/check-email`, {
+ email,
+ });
+ return response; // 응답 전체를 반환하도록 수정
+ } catch (error) {
+ throw new Error(error.response.data.message);
+ }
+}
diff --git a/pages/api/sigin-api.jsx b/pages/api/sigin-api.jsx
deleted file mode 100644
index f8bca0259..000000000
--- a/pages/api/sigin-api.jsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import axiosInstance from "../../lib/axious";
-
-export async function signin(userData) {
- const res = await axiosInstance.post(`/sign-in`, userData);
- return res;
-}
diff --git a/pages/example2.jsx b/pages/example2.jsx
deleted file mode 100644
index 4234e7701..000000000
--- a/pages/example2.jsx
+++ /dev/null
@@ -1,154 +0,0 @@
-import { useForm } from "react-hook-form";
-import Input from "../components/Input/Input";
-import { useState, useEffect } from "react";
-import { useRouter } from "next/router";
-import Image from "next/image";
-import styles from "../styles/example2.module.css";
-import LoginTitle from "../components/LoginTitle/LoginTitle";
-import ShareBox from "../components/ShareBox/shareBox";
-import signin from "./api/sigin-api";
-
-function Example2() {
- const { register, handleSubmit, watch } = useForm();
-
- const onSubmit = (data) => {
- const userData = {
- email: data.email,
- password: data.password,
- };
- handleSignin(userData);
- };
- const emailVal = watch("email");
- const passwordVal = watch("password");
- const [errorMessage, setErrorMessage] = useState("");
- const [emailError, setEmailError] = useState("");
- const [isPasswordVisible, setIsPasswordVisible] = useState(false);
- //비밀번호 눈 버튼
- const togglePasswordVisibility = () => {
- setIsPasswordVisible((prevState) => !prevState);
- };
- const router = useRouter();
- const hasError = !!errorMessage;
- const hasEmailError = !!emailError;
-
- const handleBlurSignin = (e) => {
- console.log("asd");
- const isValidEmail = (email) => {
- const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
- return emailRegex.test(email);
- };
-
- let newErrorMessage = errorMessage; // 이전 오류 메시지를 유지합니다.
- let emailErrorMessage = emailError; // 이전 이메일 오류 메시지를 유지합니다.
-
- if (e.target.name === "email") {
- if (!emailVal) {
- emailErrorMessage = "이메일을 입력해 주세요.";
- } else if (!isValidEmail(emailVal)) {
- emailErrorMessage = "올바른 이메일 주소가 아닙니다.";
- } else {
- emailErrorMessage = ""; // 입력이 유효한 경우 이메일 오류 메시지를 초기화합니다.
- }
- } else if (e.target.name === "password") {
- if (!passwordVal) {
- newErrorMessage = "비밀번호를 입력해 주세요";
- } else if (
- passwordVal.length < 8 ||
- !/\d/.test(passwordVal) ||
- !/[a-zA-Z]/.test(passwordVal)
- ) {
- newErrorMessage = "비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요.";
- } else {
- newErrorMessage = ""; // 입력이 비어 있지 않은 경우 오류 메시지를 초기화합니다.
- }
- }
- setEmailError(emailErrorMessage);
- setErrorMessage(newErrorMessage);
- console.log(errorMessage);
- };
-
- const handleSignin = async (userData) => {
- try {
- const response = await signin(userData);
- if (response) {
- localStorage.setItem("sign", response.data.data.accessToken);
- router.push("/folder");
- console.log("POST 요청이 성공했습니다.");
- }
- } catch (error) {
- console.error("로그인 실패", error);
- setErrorMessage("아이디 혹은 비밀번호가 잘못되었습니다.");
- setEmailError("아이디 혹은 비밀번호가 잘못되었습니다.");
- }
- };
-
- useEffect(() => {
- const LocalStorage = localStorage.getItem("sign");
- if (LocalStorage !== null) {
- router.push("/folder");
- }
- }, []);
-
- return (
- <>
-
- >
- );
-}
-export default Example2;
diff --git a/pages/folder.jsx b/pages/folder.jsx
deleted file mode 100644
index d95566333..000000000
--- a/pages/folder.jsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import Header from "../components/Header/Header";
-import Nav from "../components/Nav/Nav";
-import { SearchBar } from "../components/SearchBar/SearchBar";
-import { Input } from "../components/Input/EmailInput";
-// const cx = classNames.bind(styles);
-export default function Folder() {
- return (
- <>
-
-
-
-
- >
- );
-}
diff --git a/pages/folder/[id].jsx b/pages/folder/[id].jsx
new file mode 100644
index 000000000..e69de29bb
diff --git a/pages/folder/index.jsx b/pages/folder/index.jsx
new file mode 100644
index 000000000..8527bf075
--- /dev/null
+++ b/pages/folder/index.jsx
@@ -0,0 +1,37 @@
+import Nav from "../../components/Nav/Nav";
+import Header from "../../components/Header/Header";
+import { SearchBar } from "../../components/SearchBar/SearchBar";
+import { useState, useEffect } from "react";
+import { fetchUserProfile } from "../api/auth/folder-api";
+
+export default function Folder() {
+ const [userProfile, setUserProfile] = useState(null); // userProfile 상태를 null로 초기화
+
+ useEffect(() => {
+ // 사용자 프로필을 가져오는 비동기 함수 호출
+ async function getUserProfile() {
+ try {
+ const userProfile = await fetchUserProfile();
+
+ console.log("사용자 프로필 데이터:", userProfile);
+ } catch (error) {
+ console.error(
+ "사용자 프로필을 가져오는 동안 오류가 발생했습니다:",
+ error
+ );
+ }
+ }
+
+ getUserProfile(); // 함수 호출
+ }, []);
+
+ return (
+ <>
+ {/* Nav 컴포넌트에 userProfile prop 전달 */}
+
+
+
+
+ >
+ );
+}
diff --git a/pages/signin.jsx b/pages/signin.jsx
index 60d28e3a0..33826df0a 100644
--- a/pages/signin.jsx
+++ b/pages/signin.jsx
@@ -1,23 +1,109 @@
-import EmailInput from "../components/Input/EmailInput";
-import PasswordInput from "../components/Input/PasswordInput";
+import {
+ QueryClient,
+ QueryClientProvider,
+ useMutation,
+} from "@tanstack/react-query";
+import { loginUser } from "./api/auth/signin-api";
+import { useState } from "react";
+import { useRouter } from "next/router";
+import { useForm } from "react-hook-form";
import LoginTitle from "../components/LoginTitle/LoginTitle";
import { Button } from "../components/Button/Button";
import ShareBox from "../components/ShareBox/shareBox";
import styles from "../styles/signin.module.css";
import Input from "../components/Input/Input";
+
function Signin() {
+ const [passwordInputType, setPasswordInputType] = useState("password");
+ const regEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ const regPassword = /^(?=.*[a-zA-Z])(?=.*\d)[A-Za-z\d@$!%*?&]{8,}$/;
+ const {
+ register,
+ handleSubmit,
+ watch,
+ formState: { isSubmitting, errors },
+ } = useForm({ mode: "onBlur" });
+ const watchEmail = watch("email", "");
+ const watchPassword = watch("password", "");
+ const togglePasswordVisibility = (e) => {
+ e.preventDefault();
+ setPasswordInputType((prev) => (prev === "password" ? "text" : "password"));
+ };
+ const queryClient = new QueryClient();
+ // useQuery 훅 사용
+ const router = useRouter();
+
+ // 로그인 성공 시 페이지 이동
+ const onSuccess = () => {
+ router.push("/folder"); // 성공 페이지 경로로 이동
+ };
+ const handleSignin = useMutation({
+ mutationFn: (formData) => loginUser(formData.email, formData.password),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["post"] });
+ console.log("로그인 되었습니다.");
+ onSuccess();
+ },
+ onError: (error) => {
+ console.error("로그인 오류:", error);
+ // 오류에 따른 적절한 처리를 추가하세요.
+ },
+ });
+
+ const onSubmit = (formData) => {
+ handleSignin.mutate(formData);
+ };
+
return (
- <>
-