diff --git a/next.config.js b/next.config.js index a843cbe..fc94a5f 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,14 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, + async rewrites() { + return [ + { + source: '/api/:path*', + destination: `${process.env.API_BASE_URL}/api/:path*`, + }, + ] + }, } module.exports = nextConfig diff --git a/package.json b/package.json index 2105e79..570f3bb 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@mui/icons-material": "^5.11.9", "@mui/material": "^5.11.9", "@next/font": "13.1.6", + "axios": "^1.3.3", "formik": "^2.2.9", "next": "13.1.6", "react": "18.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7634f1b..5162406 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,7 @@ specifiers: '@types/node': 18.13.0 '@types/react': 18.0.28 '@types/react-dom': 18.0.11 + axios: ^1.3.3 eslint: ^8.34.0 eslint-config-next: ^13.1.6 eslint-config-prettier: ^8.6.0 @@ -30,6 +31,7 @@ dependencies: '@mui/icons-material': 5.11.9_ofpk46txu7v2f5mzrtv4xsczka '@mui/material': 5.11.9_xqeqsl5kvjjtyxwyi3jhw3yuli '@next/font': 13.1.6 + axios: 1.3.3 formik: 2.2.9_react@18.2.0 next: 13.1.6_biqbaboplfbrettd7655fr4n2y react: 18.2.0 @@ -849,6 +851,10 @@ packages: engines: {node: '>=8'} dev: true + /asynckit/0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + /available-typed-arrays/1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -859,6 +865,16 @@ packages: engines: {node: '>=4'} dev: true + /axios/1.3.3: + resolution: {integrity: sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + /axobject-query/3.1.1: resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} dependencies: @@ -986,6 +1002,13 @@ packages: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} dev: true + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + /commander/9.5.0: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} @@ -1093,6 +1116,11 @@ packages: object-keys: 1.1.1 dev: true + /delayed-stream/1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + /dir-glob/3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1609,12 +1637,31 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true + /follow-redirects/1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + /for-each/0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: is-callable: 1.2.7 dev: true + /form-data/4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /formik/2.2.9_react@18.2.0: resolution: {integrity: sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==} peerDependencies: @@ -2227,6 +2274,18 @@ packages: picomatch: 2.3.1 dev: true + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + /mimic-fn/2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -2536,6 +2595,10 @@ packages: resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==} dev: false + /proxy-from-env/1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + /punycode/2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} diff --git a/src/api/auth.ts b/src/api/auth.ts new file mode 100644 index 0000000..5c82025 --- /dev/null +++ b/src/api/auth.ts @@ -0,0 +1,16 @@ +import axios from '@/utils/axios' + +export interface LoginInputDto { + email: string + /** @minLength 8 */ + password: string +} + +export interface Token { + accessToken: string + refreshToken: string +} + +export async function login(data: LoginInputDto) { + return axios.post('/api/auth/login', data) +} diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..02e3b86 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1 @@ +export * as auth from './auth' diff --git a/src/pages/login.tsx b/src/pages/login.tsx index 7be079a..819fdd1 100644 --- a/src/pages/login.tsx +++ b/src/pages/login.tsx @@ -8,9 +8,13 @@ import LockOutlinedIcon from '@mui/icons-material/LockOutlined' import Typography from '@mui/material/Typography' import Container from '@mui/material/Container' import { useFormik } from 'formik' +import { useRouter } from 'next/router' import * as yup from '@/utils/validation' +import * as api from '@/api' export default function SignIn() { + const router = useRouter() + const formik = useFormik({ initialValues: { email: '', @@ -21,8 +25,11 @@ export default function SignIn() { email: yup.emailSchema, password: yup.passwordSchema, }), - onSubmit: (values) => { - console.log(JSON.stringify(values, null, 2)) + onSubmit: async (values) => { + const res = await api.auth.login(values) + localStorage.setItem('accessToken', res.data.accessToken) + localStorage.setItem('refreshToken', res.data.refreshToken) + router.push('/') }, }) diff --git a/src/utils/axios.ts b/src/utils/axios.ts new file mode 100644 index 0000000..e56ac48 --- /dev/null +++ b/src/utils/axios.ts @@ -0,0 +1,5 @@ +import axios from 'axios' + +const instance = axios.create({}) + +export default instance