From e6e1be4207b060b8828bb5ed3e08d8ad0309e713 Mon Sep 17 00:00:00 2001 From: NamgungJongMin Date: Fri, 5 Jan 2024 15:33:34 +0900 Subject: [PATCH 1/5] Feat: create login page - markup page - apply styles --- package-lock.json | 703 +----------------- package.json | 3 +- src/assets/icons/removeBtn.svg | 3 + src/assets/kakao/kakao_login_large_narrow.png | Bin 0 -> 6596 bytes src/assets/kakao/kakao_login_large_wide.png | Bin 0 -> 7213 bytes .../kakao/kakao_login_medium_narrow.png | Bin 0 -> 2946 bytes src/assets/kakao/kakao_login_medium_wide.png | Bin 0 -> 3307 bytes src/assets/kakao/kakao_path.svg | 3 + src/assets/logo.svg | 14 + src/pages/Auth/Login.module.scss | 173 +++++ src/pages/Auth/Login.tsx | 165 ++++ src/routes/MainRouter/MainRouter.tsx | 3 + src/sass/abstracts/_variables.scss | 1 + 13 files changed, 393 insertions(+), 675 deletions(-) create mode 100644 src/assets/icons/removeBtn.svg create mode 100644 src/assets/kakao/kakao_login_large_narrow.png create mode 100644 src/assets/kakao/kakao_login_large_wide.png create mode 100644 src/assets/kakao/kakao_login_medium_narrow.png create mode 100644 src/assets/kakao/kakao_login_medium_wide.png create mode 100644 src/assets/kakao/kakao_path.svg create mode 100644 src/assets/logo.svg create mode 100644 src/pages/Auth/Login.module.scss create mode 100644 src/pages/Auth/Login.tsx diff --git a/package-lock.json b/package-lock.json index 81a8d042..372780ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "framer-motion": "^10.16.16", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-hook-form": "^7.49.2", "react-icons": "^4.12.0", "react-router-dom": "^6.21.1", "recoil": "^0.7.7" @@ -2084,358 +2085,6 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", - "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", - "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", - "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", - "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", - "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", - "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", - "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", - "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", - "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", - "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", - "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", - "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", - "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", - "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", - "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", - "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", - "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", - "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", - "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", - "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", - "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", - "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/win32-x64": { "version": "0.19.10", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", @@ -3147,162 +2796,6 @@ } } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.1.tgz", - "integrity": "sha512-6vMdBZqtq1dVQ4CWdhFwhKZL6E4L1dV6jUjuBvsavvNJSppzi6dLBbuV+3+IyUREaj9ZFvQefnQm28v4OCXlig==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.1.tgz", - "integrity": "sha512-Jto9Fl3YQ9OLsTDWtLFPtaIMSL2kwGyGoVCmPC8Gxvym9TCZm4Sie+cVeblPO66YZsYH8MhBKDMGZ2NDxuk/XQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.1.tgz", - "integrity": "sha512-LtYcLNM+bhsaKAIGwVkh5IOWhaZhjTfNOkGzGqdHvhiCUVuJDalvDxEdSnhFzAn+g23wgsycmZk1vbnaibZwwA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.1.tgz", - "integrity": "sha512-KyP/byeXu9V+etKO6Lw3E4tW4QdcnzDG/ake031mg42lob5tN+5qfr+lkcT/SGZaH2PdW4Z1NX9GHEkZ8xV7og==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.1.tgz", - "integrity": "sha512-Yqz/Doumf3QTKplwGNrCHe/B2p9xqDghBZSlAY0/hU6ikuDVQuOUIpDP/YcmoT+447tsZTmirmjgG3znvSCR0Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.1.tgz", - "integrity": "sha512-u3XkZVvxcvlAOlQJ3UsD1rFvLWqu4Ef/Ggl40WAVCuogf4S1nJPHh5RTgqYFpCOvuGJ7H5yGHabjFKEZGExk5Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.1.tgz", - "integrity": "sha512-0XSYN/rfWShW+i+qjZ0phc6vZ7UWI8XWNz4E/l+6edFt+FxoEghrJHjX1EY/kcUGCnZzYYRCl31SNdfOi450Aw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.1.tgz", - "integrity": "sha512-LmYIO65oZVfFt9t6cpYkbC4d5lKHLYv5B4CSHRpnANq0VZUQXGcCPXHzbCXCz4RQnx7jvlYB1ISVNCE/omz5cw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.1.tgz", - "integrity": "sha512-kr8rEPQ6ns/Lmr/hiw8sEVj9aa07gh1/tQF2Y5HrNCCEPiCBGnBUt9tVusrcBBiJfIt1yNaXN6r1CCmpbFEDpg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.1.tgz", - "integrity": "sha512-t4QSR7gN+OEZLG0MiCgPqMWZGwmeHhsM4AkegJ0Kiy6TnJ9vZ8dEIwHw1LcZKhbHxTY32hp9eVCMdR3/I8MGRw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.1.tgz", - "integrity": "sha512-7XI4ZCBN34cb+BH557FJPmh0kmNz2c25SCQeT9OiFWEgf8+dL6ZwJ8f9RnUIit+j01u07Yvrsuu1rZGxJCc51g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.1.tgz", - "integrity": "sha512-yE5c2j1lSWOH5jp+Q0qNL3Mdhr8WuqCNVjc6BxbVfS5cAS6zRmdiw7ktb8GNpDCEUJphILY6KACoFoRtKoqNQg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.1.tgz", @@ -3629,150 +3122,6 @@ } } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.101.tgz", - "integrity": "sha512-mNFK+uHNPRXSnfTOG34zJOeMl2waM4hF4a2NY7dkMXrPqw9CoJn4MwTXJcyMiSz1/BnNjjTCHF3Yhj0jPxmkzQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.101.tgz", - "integrity": "sha512-B085j8XOx73Fg15KsHvzYWG262bRweGr3JooO1aW5ec5pYbz5Ew9VS5JKYS03w2UBSxf2maWdbPz2UFAxg0whw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.101.tgz", - "integrity": "sha512-9xLKRb6zSzRGPqdz52Hy5GuB1lSjmLqa0lST6MTFads3apmx4Vgs8Y5NuGhx/h2I8QM4jXdLbpqQlifpzTlSSw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.101.tgz", - "integrity": "sha512-oE+r1lo7g/vs96Weh2R5l971dt+ZLuhaUX+n3BfDdPxNHfObXgKMjO7E+QS5RbGjv/AwiPCxQmbdCp/xN5ICJA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.101.tgz", - "integrity": "sha512-OGjYG3H4BMOTnJWJyBIovCez6KiHF30zMIu4+lGJTCrxRI2fAjGLml3PEXj8tC3FMcud7U2WUn6TdG0/te2k6g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.101.tgz", - "integrity": "sha512-/kBMcoF12PRO/lwa8Z7w4YyiKDcXQEiLvM+S3G9EvkoKYGgkkz4Q6PSNhF5rwg/E3+Hq5/9D2R+6nrkF287ihg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.101.tgz", - "integrity": "sha512-kDN8lm4Eew0u1p+h1l3JzoeGgZPQ05qDE0czngnjmfpsH2sOZxVj1hdiCwS5lArpy7ktaLu5JdRnx70MkUzhXw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.101.tgz", - "integrity": "sha512-9Wn8TTLWwJKw63K/S+jjrZb9yoJfJwCE2RV5vPCCWmlMf3U1AXj5XuWOLUX+Rp2sGKau7wZKsvywhheWm+qndQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.3.101", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.101.tgz", - "integrity": "sha512-onO5KvICRVlu2xmr4//V2je9O2XgS1SGKpbX206KmmjcJhXN5EYLSxW9qgg+kgV5mip+sKTHTAu7IkzkAtElYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/core-win32-x64-msvc": { "version": "1.3.101", "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.101.tgz", @@ -4179,6 +3528,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -5725,6 +5076,16 @@ "node": ">=12" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", @@ -5734,14 +5095,6 @@ }, "funding": { "url": "https://github.com/motdotla/dotenv?sponsor=1" - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" } }, "node_modules/electron-to-chromium": { @@ -6501,20 +5854,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -9199,6 +8538,22 @@ } } }, + "node_modules/react-hook-form": { + "version": "7.49.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.49.2.tgz", + "integrity": "sha512-TZcnSc17+LPPVpMRIDNVITY6w20deMdNi6iehTFLV1x8SqThXGwu93HjlUVU09pzFgZH7qZOvLMM7UYf2ShAHA==", + "engines": { + "node": ">=18", + "pnpm": "8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-icons": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", diff --git a/package.json b/package.json index 62353a45..30d2604d 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "framer-motion": "^10.16.16", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-hook-form": "^7.49.2", "react-icons": "^4.12.0", "react-router-dom": "^6.21.1", "recoil": "^0.7.7" @@ -54,7 +55,7 @@ "vite": "^5.0.8", "vite-plugin-svgr": "^4.2.0" }, - "msw": { + "msw": { "workerDirectory": "public" } } diff --git a/src/assets/icons/removeBtn.svg b/src/assets/icons/removeBtn.svg new file mode 100644 index 00000000..7ec6ea61 --- /dev/null +++ b/src/assets/icons/removeBtn.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/kakao/kakao_login_large_narrow.png b/src/assets/kakao/kakao_login_large_narrow.png new file mode 100644 index 0000000000000000000000000000000000000000..894c2232c2eb47cecac2c45f9f9c0daef6bdd089 GIT binary patch literal 6596 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 literal 0 HcmV?d00001 diff --git a/src/assets/kakao/kakao_login_large_wide.png b/src/assets/kakao/kakao_login_large_wide.png new file mode 100644 index 0000000000000000000000000000000000000000..c0c1856129a03c5e5812854c7b7a1a6134f0f5c0 GIT binary patch literal 7213 zcmY+J1z3~c+s7FU>5!6UNJ)36bO=ay4WtDLNd-oUG>mQp$pJ$_8U~1Tw{(L@cfa%h zdw+l5_qxutoo9Q__tbNL@6XOYzSK~{!=}VWK|#S&QI^+6K|wV{){QYAp`ZYWg~;uZ z7XS}!C0UfpA?h6z6sj#1`RBSmfW2%iAKl5>?gxIOUhGgAWze%=Y*|(^X@%!PuO6d! z?K#EN%T#dcc748{d|#^Xr25M3`E&H6QDggj%t&nGmog>TNtn9v?=>;$ZRpbnyoa*q z)5ZBOhURBkdLJZ)2U{*+2UiRHu8aQPoFH$`L(*(q5xBnU#hQr3$RV=eu@41XP7X5! zP39F zx6sun3x8F+MLjRW^eum6n>UM*$u;8MZ0W#Hu2{5|UK z_Y+8K3xjqJ|9JnSDUqr>vw4vsRbkbdfB?r80UBK*<{{o2ii~*9{ZEAYC~=`x;>=b? zILq7R>rpi-;Aq>(AbUN$TRVGfQU-L@pa&c@rXQC@m}xGCdf;1^@52xrML>C*P_i&X zttD!}1F0YWhW{7G$PI*C+0OK2;+K@LUPuX~ zEG5xc@$DBtQL*5&x>WP+9=ijG{KTXv7`IvINjaIwwSSXWY4_emtsb;7dy6DhkR5MB zU)0UI(MqsOaoxyhQ7JB{G@Mk@%~0Eep72Y|q^S&?c7+LH6?u4U;}Qc*3TLX?yQx-( z&5LH*D1!`9!O!f{)5v_oUbt4%b&xmVMFkH=?LRK0K|0m1$gI;Id!0g9q*Hc*ZGoU9B&5(wfpN|Mc)6$uzRF_ z+97zPT#VXPwc{h?#x1&}D%P-na>TlyoM7d?1nMRtHZV+$I?nQ_6Z3*w%?&XcSgs|T zvX?b}ac6gFovJ3$9_kuvJfotS8L2w8z? z|7^in#f=cflk>Oaza7n0W%w`GbgWCybYf1=)F7zdP5LooHp8toFALe3`lrNN9#!GF zs!j(`O*tHe{QSasY+@n6WS=xC4QRvb4jw5ZYv=ZzE*v7vm>?z!bp7hGr)mO~!m|C5r7DQ$GD2)>T=*gwE%nA9)I)&E zAX+Tta@BjZq%W-4QS6A-BVH|LA`pNR;81N+4>ykroo19lJ$ezuFmiP3`HTuHK8Ol{ zzg54ojE5C3BSD(^3oX31=)$s4fhYfi=gzc#nD9rO)(h3*+5N@*TxNdT! z6yvfAXkEj*!9c(Es>-q{`Qd8md+U;2gYOYDDsb_-+-aKX^?BXm@(f(wwc3TpVWOEu zYJ{v`zp+(32}A~|@_8U{%pSeWrx*M*)UY)oL1U3>P#i1t$`yCA_%@UjBhIIa&!BTd zlzTc{sDfrmQu_`g+KKyovm3f^kT0KOZV;lux;I|d}m@OEJLeUITsY`bJnmnv?sEjLesBb1U{4Pp1z;()c$7X zgip_^5=cibNIP83M3~rt{b8FxLOqNWKUUE zL)lS3#vCw|x&g4pp{dUhiw;dNZ0WsfJ56f0xVzHhW zysi@axv&zf!qAoE&z)TY|J1KQlYhrmjoV}g{+ybabnmyn(GW}Ub~j9=O=-W32Yc-7 zAfTu`A(mV>gsx32g3gO+<*uuOWcT+ssfaH(5fE%&H4a5ihWv-qHX#}lGbpqiXL8MNR;z*aYA%x2_9J~j*+cM++p zW~4BPo;HBnp4@c*)?O$HsdV}fR+TE|tu+xNKU~j1=w94pTo4A{>ggpY_rBipXacBh zqB>NZcJ5G7q1s-jNHCqe;NP)Ynp!Bx z3p8|YvREo$fA`kfLDrQ)tyq|AeYUmhmbtYkWNy|0UKa1Bqs9_Yumt!~ zWu+H5rQ{Q~g?5L`BQ;98IJBlAUgGbn;_Pi@3~7*EUebd|#=Q)A2ge@s*J_KBrre>h zg(mh*JUY(!(-T-7kr-5+BEga3{tR2~8GGhSeQMt5GpN-SGC~`Hx}RT>_WgRx#%`u~ z$_OBeAV&3~B2&?-7hut##q0tBhz`{e;4T|Bj-_aFRpg{tfHq1Jr21JBxRKA10iKH@ z{_~C>jEfwH2)#@gDGNa`I35M-l0_zLBlod2vicnhxeOw{gd|7L-PI@#XZ(bt1G+jf2wY>puz*9Uz1j~m-;L0u2B@`;*c-yd2@SSQ4DbXLp&7u1@v}>ws?QP|YbmxA@^`!g8!cySIuruCamUJ3dH5*hN>cNSc$j zk?sQ8FP^tp^xMaV{HskDeI5MZA#>fU%6q)PKRffH+oEvw{D#`1OoOB?=u9mZcuQ|o zhwDo$h)T~2YoA8vwtI{B@|Nw*Qg-`Rd(u6Y?sP;|v~B}CWXskDyvGWNjoObK{7an$G6v*=)pM!O58c|5eSI436wKZ=kXjU3K7@x1 zJ>zap{D_1zxZMIhBjZfS#y3p$X>Frib5MOv!V8+}zr%CB3#+{stb zze?B5GqP8ht&3yN43F-4|4>)cR6R-N@CyoZe$?me9HK*gE4wx9F&q}c`e$#O&C52jJoIUPMJpH-98qHcgY^yPX$&J#zj(i!HGZI$co38csRrmzDWvqIvrLk?CspAP{ZuVIT`kZS1z}{KPOr*bw zde@M+_tEG29vhc#oh!FWptS>^ddgskX%0Ga;+z`pXKPG0wEf#J>@1n36Rd{NB<3S? zSq?)Kmq&L}5YYi^?u50UmLhB=Jm%HwGmLS*MbK6M3RW3!&BoJixC6W6FJ^0%*?!Kd zyN?g$t&6(n9Ie|Jeq}qO@L=H6DpF@%=Y6txxbpavYJs*Oe8O@j$auh4nnqj8Z)!F- z3pWlAaKPfI9b2l2(()la+L@5EBKbK=3xjOl4MHNiZKz3;y)6V!b0JW+Za`-2UE48X z&ZWn<%rIvD*U8wo@N2lpje&fi$xrMh7dKW-&HR9$U-1ph_4jrv{M)J-vFyCx9+dAs z`^A<#j-fUN-^{d;xZH)-J6rm2h?&uEQ|Kf22A1_rCYGFn>+ORbP5hgs_e3u}74abm z-_GMVqgTa8^K#dbD%`u4V-ju$SUuL(DtwjXxy11s$F~RU^Vf;{@7bt^Z!1w9N-Gl- z9D38==6-xETQEAZTLlZ2*v=q>U&Dwlo3yi0v0*E=f(O3D{2aJ&rbZS9Jqf>GoWUJ}dQUjd@4*%}F#j z3y;>(3tzN&$>L`fY$cfu6D1Ic&UQ zUwYwuU9L1CqC{8Ax6KM;)vTRT)T+EWEA6!IT4abb!`bCMJ959ZefQabk|C}}f0Oi^ z7VT-ABn1A9W7sikfz+NO?#6o$2G9*m_HC3c9gav;z6okW1toFGwL__EV8<7e&fOD8w}mHWn; z-wEt^KX%*fmqjWqYJO90&GKc-y* zANUG>flL?Ve|Yi;&GHB-xrrIE;C^)^=utu*g%rZagngMI$TNQ@r(rjpCqfwa6q!fj zWf%ZzY+@z}p|V8u0HlBqGsql6)7Tw8?AY4{aP#n%z)|}Hr^Z}>{9Hv!h)BjaN3L@9a%08P!(s+yQr0VzQ?NH<2t1t6>gQ8XbB&~mnA22Du zlO)TE^v5IzrGa0>w$k74Adg=ajUg_^E)l_?@(~DMi6}RohW~{_Md_oi-HGRuIDBFD@jh22YD3{4)}j! zl!onY)@*;<@i5Au^%LTu{qLInff*500eJA*58c1*ER{i{Jd8h(Ck>A_n=#%sVwY4A zyhxMRD(`=UTKB-svmA)3)<5(2enK{YT4%tF+#nBF?LEWcirq@jpm^M9XOOf6 zu*P+ZMv;!lz8A=*Y2>zAh~BFr;}XjWe)dUE<2&0(Fn?wF*Jb5WYeWI4>Un%bR3H`S zr z(evrLET_^vbjcqC@W*Ea58nfkNmDD$RW4OSXx$r5&ztaYIw;Y&wxRDlmmbRJw(q4V z*+@2Z^Xg)7)5i3zNo?ZX)Gz@9zZ|8JCvtkNnBScv;Fb9G?hAoRlP;2Vt-=?x~=&t@oE@3b@#X#*ASETpyK(Kv*1K@VY*4ERjoDI#pOJ1I1aI#nJng z5Oy|Id_9fnP25u<56}@;4srd#zfo^%Q|qGT)r3BMSH{Uazw`)=TO#JdHs#lk0+#=n z6R(lN<(v}O$+Xm`5W?~*p8>L|VY%`}UzJn|uT(+NZ#~?*Lo1d#Ht|QYDeO2`lOSEF z(gywJ0Y2|<4z8vsVz#>ZGK3*%_PKhys~CW-3=Dlkku#$8d^CVQEhLvl>=<+=n*w4E~9>Al20D~nE`-2 zF_3wI3llivGo#JQA*lE!R(f*cDY2t~sve5a^vfcHwm{?Oz5(`kx7AH#%$M?b^b_XH1%~7e|P9u zx^tyF*3;|*~}^BDvk*tm_qZ; z`QGRX{eD}nJBt5vE!i%PJ&Iz&^O)lU#?n0qkDzUtd@M`n9d*Umvy<_nH9_Q#x}x&( z!uOw{<~%#+G^~+zZJ{@2s-`Bwl!mn5InfhH)*YAYk}Pbbd7oVftBw{l9Z<}*>OWR2 zr>><{+oJ8k0zgBvlbAL{$UrvK#!QEB;1$b-a$E--UbD+bJt{&J( zy{6ceOHUE^o0S+Vjh>JnZMR#J&{f@5KH8MJ;jzPLZ9;#pC{%_6^Y?sqL^ZK{(yL2r zr3uTTw0VxLnb0|fMrwzN*H^#epMIM+wk$|{!suU17BGQrQRzMKIMJhTJ+enUO5@{V zx;r^ua+vmoIIS~hVn2h3_gb3c?N#+*)%GmBw|&`;8CPW%ht)v8F9ez5L1I8K*s`}w z^1^>PygX=kKWKX>PUF?2_WImm@N~nIl)jLyBF((k#ZSLqogJH2k7mAka$eEdG#&>O z{LuR(#y)wCRgS9qGh+E(Fh&WL1y~9LE9HAJxJWNk1?! zhnUZnEhP?rCsJFfBnN9irlyQ}wy#Z@2Au*q2<(r75+eeUNd)yNa&^>HXX}LF)_8}* z8;B$p5OdNaMt?-YhQ?%73uw~^7hi;xI9`UD2yQvgJr^k|6q^%mzBPqW^BHo5jSP|# zB3@?rnTIvn%Q(%D?e9sQrDK!ZacsLxI=4dyW*-)uXg1vB4CG$mf&jv(yn=9Dl}bwd zo`UDi5gOU(ByC0Ep#ejEp)&*+@h7cBrXI3#!)c=NG6Ps5o6|j$?)ffdJ56k(tXr$) zbJiEFh=4-L4_=3ye%2-Ph8|b%9&W-E)WR+Mc=fa%_d1&mZf-@`8GIYWlhG!G1Y%@oan2tcWt+e;(gzfGt6t6al~N`|utUtdd& zgfOwYNQd&;BbLJQyL^o}OPS!6{{^^?*iEG14HTc uSe^6HI>>&~#}Xt&E2L2W<}bT=Kx?NRKO!XuXd?grLs3!Ckgt@r4E`T&MN-ZH literal 0 HcmV?d00001 diff --git a/src/assets/kakao/kakao_login_medium_narrow.png b/src/assets/kakao/kakao_login_medium_narrow.png new file mode 100644 index 0000000000000000000000000000000000000000..09bb358843a08576d0029ff8427120c9f5f5c36d GIT binary patch literal 2946 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 pfG!z#l@SOs1cZ>002ovPDHLkV1oS~Dl`B9 literal 0 HcmV?d00001 diff --git a/src/assets/kakao/kakao_path.svg b/src/assets/kakao/kakao_path.svg new file mode 100644 index 00000000..cc5eb65a --- /dev/null +++ b/src/assets/kakao/kakao_path.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/logo.svg b/src/assets/logo.svg new file mode 100644 index 00000000..0f2c4b52 --- /dev/null +++ b/src/assets/logo.svg @@ -0,0 +1,14 @@ + + + diff --git a/src/pages/Auth/Login.module.scss b/src/pages/Auth/Login.module.scss new file mode 100644 index 00000000..4f7188ba --- /dev/null +++ b/src/pages/Auth/Login.module.scss @@ -0,0 +1,173 @@ +@use "@/sass" as *; + +.container { + padding: 0 20px; + + h1 { + margin: 48px 0 64px 0; + width: 100%; + display: flex; + justify-content: center; + } + + .loginForm { + position: relative; + + label { + display: block; + + @include typography(tabLabel); + color: $neutral900; + } + + input { + width: 100%; + margin-top: 6px; + padding: 16px; + border: 1px solid $neutral200; + border-radius: 8px; + + @include typography(bodyLarge); + color: $neutral900; + + &::placeholder { + color: $neutral400; + } + &:focus { + outline: none; + border-width: 1px; + border-color: $primary300; + + + .removeBtn { + cursor: pointer; + + .svg { + visibility: visible; + } + } + } + } + + small { + width: 100%; + position: absolute; + bottom: 65px; + left: 0; + text-align: center; + + @include typography(captionSmall); + color: $danger300; + } + + &__email, + &__password { + position: relative; + + .removeBtn { + position: absolute; + top: 47px; + right: 14px; + cursor: default; + + .svg { + visibility: hidden; + } + } + } + + &__password { + margin-top: 24px; + } + + &__submitBtn { + width: 100%; + padding: 13px 0; + background: $primary300; + margin-top: 56px; + border-radius: 16px; + + @include typography(button); + color: $neutral0; + + &:hover { + background: $primary400; + } + } + } + + .aboutAuth { + display: flex; + justify-content: center; + gap: 16px; + width: 100%; + margin-top: 24px; + + @include typography(captionSmall); + color: $neutral400; + + a:hover { + font-weight: bold; + } + } + + .snsLogin { + margin: 128px 0 24px 0; + + &__head { + display: flex; + justify-content: space-between; + align-items: center; + gap: 12px; + + @include typography(captionSmall); + color: $neutral400; + } + + &__btn { + display: flex; + justify-content: space-between; + align-items: center; + padding: 11.5px 28px; + margin-top: 16px; + background: $etc1; + width: 100%; + border-radius: 6px; + + @include typography(button); + + .kakao_text { + flex-grow: 1; + } + + .kakao_space { + width: 18px; + } + } + } + + .bottom { + text-align: center; + margin-bottom: 55px; + + &__toHome { + @include typography(tabLabel); + color: $neutral800; + text-decoration-line: underline; + text-underline-position: under; + + &:hover { + font-weight: bold; + } + } + } + + .col_bar { + border-left: 1px solid $neutral300; + margin: 4px 0; + } + .row_bar { + flex-grow: 1; + background: $neutral200; + height: 1px; + } +} diff --git a/src/pages/Auth/Login.tsx b/src/pages/Auth/Login.tsx new file mode 100644 index 00000000..36f15d90 --- /dev/null +++ b/src/pages/Auth/Login.tsx @@ -0,0 +1,165 @@ +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { Link } from "react-router-dom"; + +import styles from "./Login.module.scss"; + +import RemoveBtn from "@/assets/icons/removeBtn.svg?react"; +import KakaoIcon from "@/assets/kakao/kakao_path.svg?react"; +import Logo from "@/assets/logo.svg?react"; + +interface Form { + email: string; + password: string; +} + +interface SubmitResult { + try: boolean; + isPassed: boolean; +} + +function Login() { + const { + register, + getValues, + reset, + formState: { errors, dirtyFields }, + } = useForm
({ + mode: "onChange", + defaultValues: { + email: "", + password: "", + }, + }); + + const [submitResult, setSubmitResult] = useState({ + try: false, + isPassed: false, + }); + + const login = () => { + setSubmitResult({ ...submitResult, try: true }); + + const isError = Object.keys(errors).length > 0; + if (isError) { + setSubmitResult({ try: true, isPassed: false }); + return; + } + + setSubmitResult({ try: true, isPassed: true }); + + console.log(submitResult, "isError", isError, errors); + }; + + const resetEmail = () => { + reset({ ...getValues(), email: "" }); + }; + + const resetPassword = () => { + reset({ ...getValues(), password: "" }); + }; + return ( +
+

+ +

+ + +
+ + + + + {dirtyFields.email && ( + + )} +
+ +
+ + + + + {dirtyFields.password && ( + + )} +
+ + {submitResult.try && !submitResult.isPassed ? ( + 이메일 또는 비밀번호를 확인해주세요. + ) : null} + + + + +
+ 비밀번호를 잊으셨나요? +
+ 회원가입 +
+ +
+

+
+

SNS 계정으로 로그인

+
+

+ + +
+ +
+ + 로그인 전 둘러보기 + +
+
+ ); +} + +export default Login; diff --git a/src/routes/MainRouter/MainRouter.tsx b/src/routes/MainRouter/MainRouter.tsx index f003ad09..921d0254 100644 --- a/src/routes/MainRouter/MainRouter.tsx +++ b/src/routes/MainRouter/MainRouter.tsx @@ -1,5 +1,7 @@ import { Route, Routes } from "react-router-dom"; +import Login from "@/pages/Auth/Login"; + import Dashboard from "../Dashboard/Dashboard"; import Home from "../../pages/Home/Home"; @@ -12,6 +14,7 @@ function MainRouter() { } /> } /> + } /> ); } diff --git a/src/sass/abstracts/_variables.scss b/src/sass/abstracts/_variables.scss index 5ff3cea8..d7b618d7 100644 --- a/src/sass/abstracts/_variables.scss +++ b/src/sass/abstracts/_variables.scss @@ -31,6 +31,7 @@ $neutral900: #1d2433; $neutral1000: #0a0d14; $etc0: #fed600; +$etc1: #fee500; //shadow $shadow100: 0px 0px 8px 0px rgba(20, 20, 20, 0.08), From fe8b9dad9c86a907b93d03775077cc1a10b64110 Mon Sep 17 00:00:00 2001 From: NamgungJongMin Date: Sat, 6 Jan 2024 13:33:27 +0900 Subject: [PATCH 2/5] Hotfix: change login component's logic - way to reset input area - way to show remove input value button - way to write form area's markup div to section --- src/pages/{Auth => Login}/Login.module.scss | 30 +++++++++------------ src/pages/{Auth => Login}/Login.tsx | 21 +++++++-------- src/routes/MainRouter/MainRouter.tsx | 2 +- 3 files changed, 24 insertions(+), 29 deletions(-) rename src/pages/{Auth => Login}/Login.module.scss (89%) rename src/pages/{Auth => Login}/Login.tsx (91%) diff --git a/src/pages/Auth/Login.module.scss b/src/pages/Login/Login.module.scss similarity index 89% rename from src/pages/Auth/Login.module.scss rename to src/pages/Login/Login.module.scss index 4f7188ba..88ff23c4 100644 --- a/src/pages/Auth/Login.module.scss +++ b/src/pages/Login/Login.module.scss @@ -33,19 +33,6 @@ &::placeholder { color: $neutral400; } - &:focus { - outline: none; - border-width: 1px; - border-color: $primary300; - - + .removeBtn { - cursor: pointer; - - .svg { - visibility: visible; - } - } - } } small { @@ -64,13 +51,22 @@ position: relative; .removeBtn { + display: none; position: absolute; top: 47px; right: 14px; cursor: default; + } + + &:focus-within { + input { + outline: none; + border-width: 1px; + border-color: $primary300; + } - .svg { - visibility: hidden; + .removeBtn { + display: block; } } } @@ -145,11 +141,11 @@ } } - .bottom { + .toHome { text-align: center; margin-bottom: 55px; - &__toHome { + &__link { @include typography(tabLabel); color: $neutral800; text-decoration-line: underline; diff --git a/src/pages/Auth/Login.tsx b/src/pages/Login/Login.tsx similarity index 91% rename from src/pages/Auth/Login.tsx rename to src/pages/Login/Login.tsx index 36f15d90..ad67bcbc 100644 --- a/src/pages/Auth/Login.tsx +++ b/src/pages/Login/Login.tsx @@ -21,8 +21,7 @@ interface SubmitResult { function Login() { const { register, - getValues, - reset, + resetField, formState: { errors, dirtyFields }, } = useForm
({ mode: "onChange", @@ -52,11 +51,11 @@ function Login() { }; const resetEmail = () => { - reset({ ...getValues(), email: "" }); + resetField("email"); }; const resetPassword = () => { - reset({ ...getValues(), password: "" }); + resetField("password"); }; return (
@@ -65,7 +64,7 @@ function Login() { -
+
)} -
+ -
+
)} -
+ {submitResult.try && !submitResult.isPassed ? ( 이메일 또는 비밀번호를 확인해주세요. @@ -153,11 +152,11 @@ function Login() { -
- +
+ 로그인 전 둘러보기 -
+
); } diff --git a/src/routes/MainRouter/MainRouter.tsx b/src/routes/MainRouter/MainRouter.tsx index 921d0254..ce980d38 100644 --- a/src/routes/MainRouter/MainRouter.tsx +++ b/src/routes/MainRouter/MainRouter.tsx @@ -1,6 +1,6 @@ import { Route, Routes } from "react-router-dom"; -import Login from "@/pages/Auth/Login"; +import Login from "@/pages/Login/Login"; import Dashboard from "../Dashboard/Dashboard"; import Home from "../../pages/Home/Home"; From a52309f4a30f698c33c92e6452fba4b433759657 Mon Sep 17 00:00:00 2001 From: NamgungJongMin Date: Sun, 7 Jan 2024 18:39:32 +0900 Subject: [PATCH 3/5] Design: change input placeholder & body padding --- src/pages/Login/Login.module.scss | 2 +- src/pages/Login/Login.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/Login/Login.module.scss b/src/pages/Login/Login.module.scss index 88ff23c4..2a96ec13 100644 --- a/src/pages/Login/Login.module.scss +++ b/src/pages/Login/Login.module.scss @@ -1,7 +1,7 @@ @use "@/sass" as *; .container { - padding: 0 20px; + padding: 0 24px; h1 { margin: 48px 0 64px 0; diff --git a/src/pages/Login/Login.tsx b/src/pages/Login/Login.tsx index ad67bcbc..e618b7bc 100644 --- a/src/pages/Login/Login.tsx +++ b/src/pages/Login/Login.tsx @@ -70,7 +70,7 @@ function Login() {
- + 로그인 전 둘러보기
From 24188be36cd9184675af3c0bb5e5ef33aea7f2d5 Mon Sep 17 00:00:00 2001 From: NamgungJongMin Date: Mon, 8 Jan 2024 13:09:35 +0900 Subject: [PATCH 4/5] Refactor: seperate component's in Login.tsx --- src/assets/logo.svg | 16 +-- src/components/Auth/Input/Input.module.scss | 47 +++++++ src/components/Auth/Input/InputEmail.tsx | 61 +++++++++ src/components/Auth/Input/InputPassword.tsx | 60 +++++++++ .../Auth/Login/LoginForm.module.scss | 31 +++++ src/components/Auth/Login/LoginForm.tsx | 84 ++++++++++++ src/pages/Login/Login.module.scss | 81 ------------ src/pages/Login/Login.tsx | 122 +----------------- 8 files changed, 294 insertions(+), 208 deletions(-) create mode 100644 src/components/Auth/Input/Input.module.scss create mode 100644 src/components/Auth/Input/InputEmail.tsx create mode 100644 src/components/Auth/Input/InputPassword.tsx create mode 100644 src/components/Auth/Login/LoginForm.module.scss create mode 100644 src/components/Auth/Login/LoginForm.tsx diff --git a/src/assets/logo.svg b/src/assets/logo.svg index 0f2c4b52..16f794a7 100644 --- a/src/assets/logo.svg +++ b/src/assets/logo.svg @@ -1,14 +1,14 @@ diff --git a/src/components/Auth/Input/Input.module.scss b/src/components/Auth/Input/Input.module.scss new file mode 100644 index 00000000..019b6fd9 --- /dev/null +++ b/src/components/Auth/Input/Input.module.scss @@ -0,0 +1,47 @@ +@use "@/sass" as *; +.container { + position: relative; + + label { + display: block; + + @include typography(tabLabel); + color: $neutral900; + } + + &:focus-within { + input { + outline: none; + border-width: 1px; + border-color: $primary300; + } + + .removeBtn { + display: block; + } + } + + .input { + width: 100%; + margin-top: 6px; + margin-bottom: 24px; + padding: 16px; + border: 1px solid $neutral200; + border-radius: 8px; + + @include typography(bodyLarge); + color: $neutral900; + + &::placeholder { + color: $neutral400; + } + } + + .removeBtn { + display: none; + position: absolute; + top: 47px; + right: 14px; + cursor: default; + } +} diff --git a/src/components/Auth/Input/InputEmail.tsx b/src/components/Auth/Input/InputEmail.tsx new file mode 100644 index 00000000..bde227e6 --- /dev/null +++ b/src/components/Auth/Input/InputEmail.tsx @@ -0,0 +1,61 @@ +import { UseFormRegister, UseFormResetField } from "react-hook-form"; + +import styles from "./Input.module.scss"; + +import RemoveBtn from "@/assets/icons/removeBtn.svg?react"; + +interface LoginForm { + email: string; + password: string; +} + +interface LoginDirtyFields { + email?: boolean; + password?: boolean; +} + +interface Props { + label: string; + dirtyFields: LoginDirtyFields; + register: UseFormRegister; + resetField: UseFormResetField; +} + +function InputEmail({ label, register, dirtyFields, resetField }: Props) { + const resetEmail = () => { + resetField("email"); + }; + + return ( +
+ + + + + {dirtyFields.email && ( + + )} +
+ ); +} + +export default InputEmail; diff --git a/src/components/Auth/Input/InputPassword.tsx b/src/components/Auth/Input/InputPassword.tsx new file mode 100644 index 00000000..a3b3506a --- /dev/null +++ b/src/components/Auth/Input/InputPassword.tsx @@ -0,0 +1,60 @@ +import { UseFormRegister, UseFormResetField } from "react-hook-form"; + +import styles from "./Input.module.scss"; + +import RemoveBtn from "@/assets/icons/removeBtn.svg?react"; + +interface LoginForm { + email: string; + password: string; +} + +interface LoginDirtyFields { + email?: boolean; + password?: boolean; +} + +interface Props { + label: string; + dirtyFields: LoginDirtyFields; + register: UseFormRegister; + resetField: UseFormResetField; +} + +function InputPassword({ label, register, dirtyFields, resetField }: Props) { + const resetPassword = () => { + resetField("password"); + }; + + return ( +
+ + + + + {dirtyFields.password && ( + + )} +
+ ); +} + +export default InputPassword; diff --git a/src/components/Auth/Login/LoginForm.module.scss b/src/components/Auth/Login/LoginForm.module.scss new file mode 100644 index 00000000..d0679794 --- /dev/null +++ b/src/components/Auth/Login/LoginForm.module.scss @@ -0,0 +1,31 @@ +@use "@/sass" as *; + +.container { + position: relative; + + small { + width: 100%; + position: absolute; + bottom: 65px; + left: 0; + text-align: center; + + @include typography(captionSmall); + color: $danger300; + } + + .submitBtn { + width: 100%; + padding: 13px 0; + background: $primary300; + margin-top: 32px; + border-radius: 16px; + + @include typography(button); + color: $neutral0; + + &:hover { + background: $primary400; + } + } +} diff --git a/src/components/Auth/Login/LoginForm.tsx b/src/components/Auth/Login/LoginForm.tsx new file mode 100644 index 00000000..57a6736c --- /dev/null +++ b/src/components/Auth/Login/LoginForm.tsx @@ -0,0 +1,84 @@ +import { useState } from "react"; +import { useForm } from "react-hook-form"; + +import styles from "./LoginForm.module.scss"; + +import InputEmail from "../Input/InputEmail"; +import InputPassword from "../Input/InputPassword"; + +interface Form { + email: string; + password: string; +} + +interface SubmitResult { + try: boolean; + isPassed: boolean; +} + +function LoginForm() { + const { + register, + resetField, + formState: { errors, dirtyFields }, + } = useForm({ + mode: "onChange", + defaultValues: { + email: "", + password: "", + }, + }); + + const [submitResult, setSubmitResult] = useState({ + try: false, + isPassed: false, + }); + + const clickLogin = () => { + setSubmitResult({ ...submitResult, try: true }); + + const isError = Object.keys(errors).length > 0; + if (isError) { + setSubmitResult({ try: true, isPassed: false }); + return; + } + + setSubmitResult({ try: true, isPassed: true }); + + // 이메일 비밀번호 validation 성공 + // 로그인 api 요청 + /* + * + * + * + */ + }; + + return ( + + + + + + {submitResult.try && !submitResult.isPassed ? ( + 이메일 또는 비밀번호를 확인해주세요. + ) : null} + + + + ); +} + +export default LoginForm; diff --git a/src/pages/Login/Login.module.scss b/src/pages/Login/Login.module.scss index 2a96ec13..2c2a4d3b 100644 --- a/src/pages/Login/Login.module.scss +++ b/src/pages/Login/Login.module.scss @@ -10,87 +10,6 @@ justify-content: center; } - .loginForm { - position: relative; - - label { - display: block; - - @include typography(tabLabel); - color: $neutral900; - } - - input { - width: 100%; - margin-top: 6px; - padding: 16px; - border: 1px solid $neutral200; - border-radius: 8px; - - @include typography(bodyLarge); - color: $neutral900; - - &::placeholder { - color: $neutral400; - } - } - - small { - width: 100%; - position: absolute; - bottom: 65px; - left: 0; - text-align: center; - - @include typography(captionSmall); - color: $danger300; - } - - &__email, - &__password { - position: relative; - - .removeBtn { - display: none; - position: absolute; - top: 47px; - right: 14px; - cursor: default; - } - - &:focus-within { - input { - outline: none; - border-width: 1px; - border-color: $primary300; - } - - .removeBtn { - display: block; - } - } - } - - &__password { - margin-top: 24px; - } - - &__submitBtn { - width: 100%; - padding: 13px 0; - background: $primary300; - margin-top: 56px; - border-radius: 16px; - - @include typography(button); - color: $neutral0; - - &:hover { - background: $primary400; - } - } - } - .aboutAuth { display: flex; justify-content: center; diff --git a/src/pages/Login/Login.tsx b/src/pages/Login/Login.tsx index e618b7bc..1e7663c2 100644 --- a/src/pages/Login/Login.tsx +++ b/src/pages/Login/Login.tsx @@ -1,136 +1,20 @@ -import { useState } from "react"; -import { useForm } from "react-hook-form"; import { Link } from "react-router-dom"; import styles from "./Login.module.scss"; -import RemoveBtn from "@/assets/icons/removeBtn.svg?react"; +import LoginForm from "@/components/Auth/Login/LoginForm"; + import KakaoIcon from "@/assets/kakao/kakao_path.svg?react"; import Logo from "@/assets/logo.svg?react"; -interface Form { - email: string; - password: string; -} - -interface SubmitResult { - try: boolean; - isPassed: boolean; -} - function Login() { - const { - register, - resetField, - formState: { errors, dirtyFields }, - } = useForm
({ - mode: "onChange", - defaultValues: { - email: "", - password: "", - }, - }); - - const [submitResult, setSubmitResult] = useState({ - try: false, - isPassed: false, - }); - - const login = () => { - setSubmitResult({ ...submitResult, try: true }); - - const isError = Object.keys(errors).length > 0; - if (isError) { - setSubmitResult({ try: true, isPassed: false }); - return; - } - - setSubmitResult({ try: true, isPassed: true }); - - console.log(submitResult, "isError", isError, errors); - }; - - const resetEmail = () => { - resetField("email"); - }; - - const resetPassword = () => { - resetField("password"); - }; return (

- -
- - - - - {dirtyFields.email && ( - - )} -
- -
- - - - - {dirtyFields.password && ( - - )} -
- - {submitResult.try && !submitResult.isPassed ? ( - 이메일 또는 비밀번호를 확인해주세요. - ) : null} - - - +
비밀번호를 잊으셨나요? From 37fbdbbc0dae185f853103cbb2e61491add1a078 Mon Sep 17 00:00:00 2001 From: NamgungJongMin Date: Mon, 8 Jan 2024 13:21:43 +0900 Subject: [PATCH 5/5] Refactor: seperate types from components --- src/components/Auth/Input/InputEmail.tsx | 21 ++--------------- src/components/Auth/Input/InputPassword.tsx | 26 ++++++--------------- src/components/Auth/Login/LoginForm.tsx | 12 ++-------- src/types/auth.ts | 25 ++++++++++++++++++++ 4 files changed, 36 insertions(+), 48 deletions(-) create mode 100644 src/types/auth.ts diff --git a/src/components/Auth/Input/InputEmail.tsx b/src/components/Auth/Input/InputEmail.tsx index bde227e6..b6219e32 100644 --- a/src/components/Auth/Input/InputEmail.tsx +++ b/src/components/Auth/Input/InputEmail.tsx @@ -1,27 +1,10 @@ -import { UseFormRegister, UseFormResetField } from "react-hook-form"; - import styles from "./Input.module.scss"; import RemoveBtn from "@/assets/icons/removeBtn.svg?react"; -interface LoginForm { - email: string; - password: string; -} - -interface LoginDirtyFields { - email?: boolean; - password?: boolean; -} - -interface Props { - label: string; - dirtyFields: LoginDirtyFields; - register: UseFormRegister; - resetField: UseFormResetField; -} +import { LoginInput } from "@/types/auth"; -function InputEmail({ label, register, dirtyFields, resetField }: Props) { +function InputEmail({ label, register, dirtyFields, resetField }: LoginInput) { const resetEmail = () => { resetField("email"); }; diff --git a/src/components/Auth/Input/InputPassword.tsx b/src/components/Auth/Input/InputPassword.tsx index a3b3506a..b99ef1b2 100644 --- a/src/components/Auth/Input/InputPassword.tsx +++ b/src/components/Auth/Input/InputPassword.tsx @@ -1,27 +1,15 @@ -import { UseFormRegister, UseFormResetField } from "react-hook-form"; - import styles from "./Input.module.scss"; import RemoveBtn from "@/assets/icons/removeBtn.svg?react"; -interface LoginForm { - email: string; - password: string; -} - -interface LoginDirtyFields { - email?: boolean; - password?: boolean; -} - -interface Props { - label: string; - dirtyFields: LoginDirtyFields; - register: UseFormRegister; - resetField: UseFormResetField; -} +import { LoginInput } from "@/types/auth"; -function InputPassword({ label, register, dirtyFields, resetField }: Props) { +function InputPassword({ + label, + register, + dirtyFields, + resetField, +}: LoginInput) { const resetPassword = () => { resetField("password"); }; diff --git a/src/components/Auth/Login/LoginForm.tsx b/src/components/Auth/Login/LoginForm.tsx index 57a6736c..7e290703 100644 --- a/src/components/Auth/Login/LoginForm.tsx +++ b/src/components/Auth/Login/LoginForm.tsx @@ -6,22 +6,14 @@ import styles from "./LoginForm.module.scss"; import InputEmail from "../Input/InputEmail"; import InputPassword from "../Input/InputPassword"; -interface Form { - email: string; - password: string; -} - -interface SubmitResult { - try: boolean; - isPassed: boolean; -} +import { LoginForm, SubmitResult } from "@/types/auth"; function LoginForm() { const { register, resetField, formState: { errors, dirtyFields }, - } = useForm
({ + } = useForm({ mode: "onChange", defaultValues: { email: "", diff --git a/src/types/auth.ts b/src/types/auth.ts new file mode 100644 index 00000000..2937d280 --- /dev/null +++ b/src/types/auth.ts @@ -0,0 +1,25 @@ +import { UseFormRegister, UseFormResetField } from "react-hook-form"; + +interface SubmitResult { + try: boolean; + isPassed: boolean; +} + +interface LoginForm { + email: string; + password: string; +} + +interface LoginDirtyFields { + email?: boolean; + password?: boolean; +} + +interface LoginInput { + label: string; + dirtyFields: LoginDirtyFields; + register: UseFormRegister; + resetField: UseFormResetField; +} + +export type { LoginDirtyFields, LoginForm, LoginInput, SubmitResult };