diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 984fcf0..e3ec672 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -31,6 +31,6 @@ jobs: run: npm install - name: Build - # env: + # .env: # NEXT_PUBLIC_API_ENDPOINT: ${{ secrets.NEXT_PUBLIC_API_ENDPOINT }} run: npm run build diff --git a/.gitignore b/.gitignore index 43163e9..793aece 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* -# local env files +# local .env files .env*.local # vercel @@ -35,4 +35,5 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts -.idea \ No newline at end of file +.idea +.env \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f61385e..08a26c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", "@tanstack/react-query": "^5.51.11", + "axios": "^1.7.2", "framer-motion": "^11.3.8", "next": "14.2.5", "react": "^18", @@ -2892,6 +2893,11 @@ "dev": true, "license": "MIT" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2918,6 +2924,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", @@ -3177,6 +3193,17 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -3415,6 +3442,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", @@ -4345,6 +4380,25 @@ "node": ">=10" } }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -4372,6 +4426,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/framer-motion": { "version": "11.3.8", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.8.tgz", @@ -5877,6 +5944,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -6456,6 +6542,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/package.json b/package.json index 0de3596..fca1453 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", "@tanstack/react-query": "^5.51.11", + "axios": "^1.7.2", "framer-motion": "^11.3.8", "next": "14.2.5", "react": "^18", diff --git a/src/app/intro/layout.tsx b/src/app/intro/layout.tsx new file mode 100644 index 0000000..5c2c795 --- /dev/null +++ b/src/app/intro/layout.tsx @@ -0,0 +1,7 @@ +import { ReactNode, Suspense } from 'react'; + +const Layout = ({ children }: { children: ReactNode }) => { + return Loading...}>{children}; +}; + +export default Layout; diff --git a/src/app/intro/page.tsx b/src/app/intro/page.tsx index 6e8ec89..21b6888 100644 --- a/src/app/intro/page.tsx +++ b/src/app/intro/page.tsx @@ -14,9 +14,11 @@ import { Textarea, VStack, } from '@chakra-ui/react'; -import { useMemo, useState } from 'react'; +import { Suspense, useEffect, useMemo, useState } from 'react'; import Link from 'next/link'; import Jinsimi from '@/component/common/jinsimi'; +import axios from 'axios'; +import { useSearchParams } from 'next/navigation'; const CharacterPanel = ({ headText }: { headText: string }) => { return ( @@ -48,7 +50,7 @@ const LiteraryPanel = ({ setIndex }: { setIndex: any }) => { return ( - (상황에 맞춰) 자유롭게 편지를 써주세요! + (진심이가 되어) 자유롭게 편지를 써주세요! @@ -86,6 +88,21 @@ const LiteraryPanel = ({ setIndex }: { setIndex: any }) => { export default function IntroPage() { const [pageIndex, setPageIndex] = useState(0); + const searchParams = useSearchParams(); + const code = searchParams.get('code'); + + const getAuth = async () => { + const res = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/auth/kakao/callback`, + { + code, + } + ); + console.log('res', res); + }; + useEffect(() => { + getAuth(); + }, []); const Panel = useMemo(() => { switch (pageIndex) { diff --git a/src/app/login/kakaoLoginButton.tsx b/src/app/login/kakaoLoginButton.tsx index 9f245d4..4d98991 100644 --- a/src/app/login/kakaoLoginButton.tsx +++ b/src/app/login/kakaoLoginButton.tsx @@ -1,25 +1,42 @@ // https://developers.kakao.com/docs/latest/ko/kakaologin/design-guide // https://www.figma.com/community/file/1232637617420363657 + +'use client'; + import { Button, ButtonProps } from '@chakra-ui/react'; import KakaoSymbol from '@/component/icon/kakaoSymbol'; +import { useRouter } from 'next/navigation'; + +const KakaologinButton = (props: ButtonProps) => { + const router = useRouter(); + const REST_API_KEY = process.env.NEXT_PUBLIC_KAKAO_REST_API_KEY; + const REDIRECT_URI = process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI; + + const KakaoLogin = () => { + router.push( + `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code` + ); + }; -const KakaologinButton = (props: ButtonProps) => ( - -); + return ( + + ); +}; export default KakaologinButton; diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index c6079e3..443121c 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,13 +1,15 @@ -import { Box, Heading, VStack } from '@chakra-ui/react'; +import { Box, Heading, HStack, VStack } from '@chakra-ui/react'; import KakaologinButton from './kakaoLoginButton'; const Login = () => { return ( // NOTE : center에 위치하는 컨텐츠의 최대 너비는 모바일 화면을 기준으로 600px으로 설정함 (논의 필요...) - - 로그인 페이지 - + + + 로그인 페이지 + + 로고