diff --git a/package-lock.json b/package-lock.json
index f114c00d..3208be09 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,7 @@
"axios": "^1.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-icons": "^4.11.0",
"react-router-dom": "^6.16.0"
},
"devDependencies": {
@@ -4438,11 +4439,27 @@
"react": "^18.2.0"
}
},
+ "node_modules/react-icons": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz",
+ "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/react-kakao-login": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/react-kakao-login/-/react-kakao-login-2.1.1.tgz",
+ "integrity": "sha512-t9htk41/i0zUY7q92mtqdqVZZ018BPi1DgbSVVrPCmuMKhZGJOnZ9OfaKLVPu3sn8QXbJc3dPwqKOiElpb44hQ==",
+ "peerDependencies": {
+ "react": ">= 15.3.0"
+ }
+ },
"node_modules/react-router": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz",
@@ -8564,11 +8581,23 @@
"scheduler": "^0.23.0"
}
},
+ "react-icons": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz",
+ "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==",
+ "requires": {}
+ },
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-kakao-login": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/react-kakao-login/-/react-kakao-login-2.1.1.tgz",
+ "integrity": "sha512-t9htk41/i0zUY7q92mtqdqVZZ018BPi1DgbSVVrPCmuMKhZGJOnZ9OfaKLVPu3sn8QXbJc3dPwqKOiElpb44hQ==",
+ "requires": {}
+ },
"react-router": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz",
diff --git a/package.json b/package.json
index 778ef4d5..e54899f5 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"axios": "^1.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-icons": "^4.11.0",
"react-router-dom": "^6.16.0"
},
"devDependencies": {
diff --git a/src/components/common/EventCard/EventCard.style.ts b/src/components/common/EventCard/EventCard.style.ts
new file mode 100644
index 00000000..54291057
--- /dev/null
+++ b/src/components/common/EventCard/EventCard.style.ts
@@ -0,0 +1,69 @@
+import styled from '@emotion/styled';
+
+const ContainerStyled = styled.div`
+ display: flex;
+ width: 25rem;
+ height: 17rem;
+ font-family: 'MainThin';
+ cursor: pointer;
+ transition: transform 0.3s ease;
+
+ &:hover {
+ transform: scale(1.02);
+ }
+`;
+
+const PosterAreaStyled = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 12rem;
+ height: 17rem;
+`;
+
+const EventInfoWrapper = styled.div`
+ display: flex;
+ justify-content: space-between;
+ flex-direction: column;
+ margin: 3%;
+`;
+
+const TitleStyled = styled.div`
+ padding-bottom: 3%;
+ font-family: 'MainBold';
+ font-size: 1.5rem;
+`;
+
+const EventDateStyled = styled.div`
+ font-size: 1rem;
+`;
+
+const EventFooterWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: end;
+ height: 20%;
+ margin-right: 3%;
+`;
+
+const PlaceStyled = styled.div`
+ color: grey;
+ font-size: 1rem;
+`;
+
+const ClubNameStyled = styled.div`
+ font-family: 'MainRegular';
+ font-size: 0.8rem;
+`;
+
+export {
+ ContainerStyled,
+ PosterAreaStyled,
+ EventInfoWrapper,
+ TitleStyled,
+ EventDateStyled,
+ EventFooterWrapper,
+ PlaceStyled,
+ ClubNameStyled,
+};
diff --git a/src/components/common/EventCard/EventCard.tsx b/src/components/common/EventCard/EventCard.tsx
new file mode 100644
index 00000000..80ab50ff
--- /dev/null
+++ b/src/components/common/EventCard/EventCard.tsx
@@ -0,0 +1,52 @@
+import { useNavigate } from 'react-router-dom';
+
+import {
+ ClubNameStyled,
+ ContainerStyled,
+ EventDateStyled,
+ EventFooterWrapper,
+ EventInfoWrapper,
+ PlaceStyled,
+ PosterAreaStyled,
+ TitleStyled,
+} from './EventCard.style';
+
+interface EventProps {
+ eventId: number;
+ eventPoster: string;
+ eventTitle: string;
+ eventDate: string;
+ eventPlace: string;
+ clubName: string;
+}
+
+const EventCard = ({
+ eventId,
+ eventPoster,
+ eventTitle,
+ eventDate,
+ eventPlace,
+ clubName,
+}: EventProps) => {
+ const navigate = useNavigate();
+
+ return (
+ navigate(`/event/detail/${eventId}`)}>
+
+
+
+
+
+ {eventTitle}
+ {eventDate}
+
+
+ {eventPlace}
+ {clubName}
+
+
+
+ );
+};
+
+export default EventCard;
diff --git a/src/components/kakaoLoginButton/KakaoLoginButton.style.ts b/src/components/kakaoLoginButton/KakaoLoginButton.style.ts
new file mode 100644
index 00000000..ce512add
--- /dev/null
+++ b/src/components/kakaoLoginButton/KakaoLoginButton.style.ts
@@ -0,0 +1,19 @@
+import styled from '@emotion/styled';
+
+const KakaoLoginButtonStyled = styled.div`
+ width: 300px;
+ height: 50px;
+ border-radius: 15px;
+ background-color: ${(props) => props.theme.color.kakaoYellow};
+`;
+
+const KakaoLoginLink = styled.a`
+ text-decoration: none;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+`;
+
+export { KakaoLoginButtonStyled, KakaoLoginLink };
diff --git a/src/components/kakaoLoginButton/KakaoLoginButton.tsx b/src/components/kakaoLoginButton/KakaoLoginButton.tsx
new file mode 100644
index 00000000..4ad5f86e
--- /dev/null
+++ b/src/components/kakaoLoginButton/KakaoLoginButton.tsx
@@ -0,0 +1,13 @@
+import { KAKAO_AUTH_URL } from '@/constants/auth';
+
+import { KakaoLoginButtonStyled, KakaoLoginLink } from './KakaoLoginButton.style';
+
+const KakaoLoginButton = () => {
+ return (
+
+ 카카오계정으로 로그인하기
+
+ );
+};
+
+export default KakaoLoginButton;
diff --git a/src/constants/LoginPage.ts b/src/constants/LoginPage.ts
new file mode 100644
index 00000000..52b0349a
--- /dev/null
+++ b/src/constants/LoginPage.ts
@@ -0,0 +1,9 @@
+const LogoText = {
+ SPACE_CLUB: 'Space Club',
+};
+
+const Message = {
+ WELCOME: '스페이스 클럽에 오신 걸 환영합니다!',
+};
+
+export { LogoText, Message };
diff --git a/src/constants/auth.ts b/src/constants/auth.ts
new file mode 100644
index 00000000..2add8e88
--- /dev/null
+++ b/src/constants/auth.ts
@@ -0,0 +1,3 @@
+export const KAKAO_REST_API_KEY = 'd358bd786d22951d3c433fe2cbcd6689';
+export const KAKAO_REDIRECT_URI = 'http://localhost:5173/oauth/kakao';
+export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_REST_API_KEY}&redirect_uri=${KAKAO_REDIRECT_URI}&response_type=code`;
diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx
new file mode 100644
index 00000000..4e352434
--- /dev/null
+++ b/src/pages/LoginPage.tsx
@@ -0,0 +1,11 @@
+import KakaoLoginButton from '@/components/kakaoLoginButton/KakaoLoginButton';
+
+const LoginPage = () => {
+ return (
+ <>
+ ;
+ >
+ );
+};
+
+export default LoginPage;
diff --git a/src/pages/LoginPage/LoginPage.style.ts b/src/pages/LoginPage/LoginPage.style.ts
new file mode 100644
index 00000000..7a3e25a9
--- /dev/null
+++ b/src/pages/LoginPage/LoginPage.style.ts
@@ -0,0 +1,71 @@
+import styled from '@emotion/styled';
+
+import Theme from '@styles/Theme';
+
+const PageContainerStyled = styled.div`
+ display: flex;
+ height: 100vh;
+`;
+
+const LogoAreaStyled = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 50%;
+ min-width: 30rem;
+ height: 100vh;
+ min-height: 30rem;
+`;
+
+const LogoCircleStyled = styled.div`
+ width: 28rem;
+ height: 28rem;
+ border-radius: 50%;
+ background: linear-gradient(
+ 139deg,
+ #012a36 10.1%,
+ rgba(50, 51, 96, 0.78) 46.84%,
+ rgba(113, 42, 124, 0.51) 69.53%,
+ rgba(0, 221, 49, 0.15) 88.79%
+ );
+ overflow: hidden;
+`;
+
+const LogoTextStyled = styled.h1`
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ top: 1rem;
+ right: 3rem;
+ color: ${Theme.color.logoTextColor};
+ text-align: end;
+ font-size: 6.25rem;
+ font-family: 'LogoFont';
+`;
+
+const LoginAreaStyled = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 50%;
+ min-width: 30rem;
+ height: 100vh;
+ min-height: 30rem;
+ font-family: 'MainBold';
+`;
+
+const TitleStyled = styled.h1`
+ padding: 0 10% 3rem 10%;
+ font-weight: bold;
+ font-size: large;
+`;
+
+export {
+ PageContainerStyled,
+ LogoAreaStyled,
+ LogoCircleStyled,
+ LogoTextStyled,
+ LoginAreaStyled,
+ TitleStyled,
+};
diff --git a/src/pages/LoginPage/LoginPage.tsx b/src/pages/LoginPage/LoginPage.tsx
new file mode 100644
index 00000000..bc0564bd
--- /dev/null
+++ b/src/pages/LoginPage/LoginPage.tsx
@@ -0,0 +1,30 @@
+import { LogoText, Message } from '@/constants/LoginPage';
+
+import KakaoLoginButton from '@components/kakaoLoginButton/KakaoLoginButton';
+
+import {
+ LoginAreaStyled,
+ LogoAreaStyled,
+ LogoCircleStyled,
+ LogoTextStyled,
+ PageContainerStyled,
+ TitleStyled,
+} from './LoginPage.style';
+
+const LoginPage = () => {
+ return (
+
+
+
+ {LogoText.SPACE_CLUB}
+
+
+
+ {Message.WELCOME}
+
+
+
+ );
+};
+
+export default LoginPage;
diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx
index 400cba81..fd51a4b8 100644
--- a/src/pages/MainPage.tsx
+++ b/src/pages/MainPage.tsx
@@ -1,5 +1,3 @@
-import React from 'react';
-
const MainPage = () => {
return
main
;
};
diff --git a/src/pages/OauthRedirectPage.tsx b/src/pages/OauthRedirectPage.tsx
new file mode 100644
index 00000000..354afe20
--- /dev/null
+++ b/src/pages/OauthRedirectPage.tsx
@@ -0,0 +1,11 @@
+import { useEffect } from 'react';
+
+const OauthRedirectPage = () => {
+ const authCode = new URL(window.location.href).searchParams.get('code');
+
+ useEffect(() => {}, []);
+
+ return OauthRedirectPage
;
+};
+
+export default OauthRedirectPage;
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 3ca9df3b..63a25abc 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -1,7 +1,9 @@
import App from '@/App';
import Layout from '@/pages/Layout';
+import LoginPage from '@/pages/LoginPage/LoginPage';
import MainPage from '@/pages/MainPage';
import NotFoundPage from '@/pages/NotFoundPage';
+import OauthRedirectPage from '@/pages/OauthRedirectPage';
import ProfilePage from '@/pages/ProfilePage';
import RegisterPage from '@/pages/RegisterPage/RegisterPage';
import ClubEventPage from '@/pages/club/ClubEventPage';
@@ -22,10 +24,18 @@ const router = createBrowserRouter([
path: '/',
element: ,
children: [
+ {
+ path: 'login',
+ element: ,
+ },
{
path: 'register',
element: ,
},
+ {
+ path: 'oauth/kakao',
+ element: ,
+ },
{
path: '',
element: ,
@@ -86,6 +96,9 @@ const router = createBrowserRouter([
path: 'writeform',
element: ,
},
+ {
+ path: 'https://kauth.kakao.com/oauth',
+ },
],
},
],
diff --git a/src/styles/Theme.ts b/src/styles/Theme.ts
index 16cd8ea4..6da5d7b8 100644
--- a/src/styles/Theme.ts
+++ b/src/styles/Theme.ts
@@ -6,6 +6,7 @@ const color = {
secondary: '#ff5a03',
white: '#ffffff',
black: '#000000',
+ kakaoYellow: '#FEE500',
gray: '#d9d9d9',
indigo: '#003949',
logoTextColor: '#fafafa',