diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 71bac8b..d58808f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@emotion/styled': specifier: 11.11.0 version: 11.11.0(@emotion/react@11.11.3(@types/react@18.3.12)(react@18.2.0))(@types/react@18.3.12)(react@18.2.0) + axios: + specifier: ^1.7.7 + version: 1.7.7 framer-motion: specifier: 11.0.3 version: 11.0.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -38,6 +41,9 @@ importers: react-router-dom: specifier: ^6.21.1 version: 6.21.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-spinners: + specifier: ^0.14.1 + version: 0.14.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) vite-plugin-svgr: specifier: ^4.3.0 version: 4.3.0(rollup@4.25.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.9.0)(terser@5.36.0)) @@ -1247,6 +1253,12 @@ packages: resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} engines: {node: '>=10'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} @@ -1297,6 +1309,10 @@ packages: color2k@2.0.3: resolution: {integrity: sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1350,6 +1366,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} @@ -1477,6 +1497,19 @@ packages: resolution: {integrity: sha512-QFaHbhv9WPUeLYBDe/PAuLKJ4Dd9OPvKs9xZBr3yLXnUrDNaVXKu2baDBXe3naPY30hgHYSsf2JW4jzas2mDEQ==} engines: {node: '>=10'} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + framer-motion@11.0.3: resolution: {integrity: sha512-6x2poQpIWBdbZwLd73w6cKZ1I9IEPIU94C6/Swp1Zt3LJ+sB5bPe1E2wC6EH5hSISXNkMJ4afH7AdwS7MrtkWw==} peerDependencies: @@ -1650,6 +1683,14 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1740,6 +1781,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1809,6 +1853,12 @@ packages: peerDependencies: react: '>=16.8' + react-spinners@0.14.1: + resolution: {integrity: sha512-2Izq+qgQ08HTofCVEdcAQCXFEYfqTDdfeDQJeo/HHQiQJD4imOicNLhkfN2eh1NYEWVOX4D9ok2lhuDB0z3Aag==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-style-singleton@2.2.1: resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} @@ -3420,6 +3470,16 @@ snapshots: dependencies: tslib: 2.8.1 + asynckit@0.4.0: {} + + axios@1.7.7: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + babel-plugin-macros@3.1.0: dependencies: '@babel/runtime': 7.26.0 @@ -3469,6 +3529,10 @@ snapshots: color2k@2.0.3: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@2.20.3: {} compute-scroll-into-view@3.0.3: {} @@ -3518,6 +3582,8 @@ snapshots: deep-is@0.1.4: {} + delayed-stream@1.0.0: {} + detect-node-es@1.1.0: {} dot-case@3.0.4: @@ -3684,6 +3750,14 @@ snapshots: dependencies: tslib: 2.8.1 + follow-redirects@1.15.9: {} + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + framer-motion@11.0.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: tslib: 2.8.1 @@ -3820,6 +3894,12 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -3901,6 +3981,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proxy-from-env@1.1.0: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -3965,6 +4047,11 @@ snapshots: '@remix-run/router': 1.14.1 react: 18.2.0 + react-spinners@0.14.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-style-singleton@2.2.1(@types/react@18.3.12)(react@18.2.0): dependencies: get-nonce: 1.0.1 diff --git a/src/components/CheckDuplicateEmail.tsx b/src/components/CheckDuplicateEmail.tsx index 8fb51e9..f852da7 100644 --- a/src/components/CheckDuplicateEmail.tsx +++ b/src/components/CheckDuplicateEmail.tsx @@ -1,83 +1,88 @@ -import {ReactNode, useState } from "react"; import { Input, Text, Button, useToast } from "@chakra-ui/react"; import styled from "@emotion/styled"; import axios from "axios"; -import { API_BASE_URL } from "../api/constant"; interface CheckDEProps { - value: string; - text: string; - handleChange: (e: React.ChangeEvent) => void; - placeholder: string; + value: string; + text: string; + handleChange: (e: React.ChangeEvent) => void; + placeholder: string; } -const CheckDuplicateEmail: React.FC = ({ value, text, handleChange, placeholder }) => { - const toast = useToast(); +const CheckDuplicateEmail: React.FC = ({ + value, + text, + handleChange, + placeholder, +}) => { + const toast = useToast(); - const checkEmail = async () => { - try { - const response = await axios.get(`/api/v1/user/email/${value}`); - if (response.data) { - toast({ - title: "가입 가능한 이메일입니다.", - status: "success", - duration: 3000, - isClosable: true, - }); - } else { - toast({ - title: "이미 가입된 이메일입니다.", - status: "error", - duration: 3000, - isClosable: true, - }); - } - } catch (error) { - toast({ - title: "오류가 발생했습니다.", - status: "error", - duration: 3000, - isClosable: true, - }); - } - }; + const checkEmail = async () => { + try { + const response = await axios.get(`/api/v1/user/email/${value}`); + if (response.data) { + toast({ + title: "가입 가능한 이메일입니다.", + status: "success", + duration: 3000, + isClosable: true, + }); + } else { + toast({ + title: "이미 가입된 이메일입니다.", + status: "error", + duration: 3000, + isClosable: true, + }); + } + } catch { + toast({ + title: "오류가 발생했습니다.", + status: "error", + duration: 3000, + isClosable: true, + }); + } + }; - return ( - <> - {text} - - - - - - ); + return ( + <> + + {text} + + + + + + + ); }; export default CheckDuplicateEmail; const Wrapper = styled.div` - display: flex; - width: calc(100% - 96px); - gap: 8px; - align-items: baseline; + display: flex; + width: calc(100% - 96px); + gap: 8px; + align-items: baseline; `; diff --git a/src/components/LoadingSpinner.tsx b/src/components/LoadingSpinner.tsx index 0db9d84..0eb8904 100644 --- a/src/components/LoadingSpinner.tsx +++ b/src/components/LoadingSpinner.tsx @@ -1,9 +1,9 @@ import fishIcon from "../assets/fishIcon.svg"; -import {SyncLoader} from "react-spinners"; -import {useEffect, useState} from "react"; +import { SyncLoader } from "react-spinners"; +import { useEffect, useState } from "react"; import styled from "@emotion/styled"; import { Text } from "@chakra-ui/react"; -export default function LoadingSpinner({timeout = 200}) { +export default function LoadingSpinner({ timeout = 200 }) { const [showSpinner, setShowSpinner] = useState(false); /** @@ -15,17 +15,18 @@ export default function LoadingSpinner({timeout = 200}) { }, timeout); return () => clearTimeout(timer); // 메모리 누수 방지 - }, []); - + }); return ( - + {showSpinner && ( <> - -
- - 물고기 박사님이 확인 중이에요~ + +
+ + + 물고기 박사님이 확인 중이에요~ + )} @@ -33,10 +34,10 @@ export default function LoadingSpinner({timeout = 200}) { } const Wrapper = styled.div` - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -`; \ No newline at end of file + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +`; diff --git a/src/components/PasswordInput.tsx b/src/components/PasswordInput.tsx index 3592220..10ce7a3 100644 --- a/src/components/PasswordInput.tsx +++ b/src/components/PasswordInput.tsx @@ -1,27 +1,30 @@ -import { ReactNode } from "react"; -import { - Input, Text - } from "@chakra-ui/react"; - +import { Input, Text } from "@chakra-ui/react"; interface PasswordInputProps { - value: string; - text: string; - handleChange: (e: React.ChangeEvent) => void; - placeholder: string; + value: string; + text: string; + handleChange: (e: React.ChangeEvent) => void; + placeholder: string; } -const PasswordInput: React.FC = ({ value, text, handleChange, placeholder }) => { +const PasswordInput: React.FC = ({ + value, + text, + handleChange, + placeholder, +}) => { return ( <> - {text} + + {text} + { null ); - //const mockData = { - // pokemonStatus: { - // gardenEel: "new", - // clownfish: "old", - // piranha: "old", - // californiaSeaLion: "old", - // }, - //}; - const getStatusColor = (status: string) => { switch (status) { case "CR": @@ -274,7 +265,7 @@ const AnalysisPage = () => { mt={20} >