Skip to content

Commit

Permalink
Merge pull request #98 from TripInfoWeb/dev_auth
Browse files Browse the repository at this point in the history
Dev auth
  • Loading branch information
ssssksss authored Jul 8, 2024
2 parents 29d2025 + 0bca798 commit d17b24e
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 79 deletions.
1 change: 1 addition & 0 deletions public/lottie/loading-airplane.json

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/app/auth/loading/kakao/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import AuthKaKaoContainer from "@/containers/auth/AuthKaKaoContainer";

const Page = () => {

return (
<AuthKaKaoContainer />
);
};
export default Page
81 changes: 2 additions & 79 deletions src/app/auth/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

import introLottie from "@/../public/lottie/solitour-intro-image.json";
import LottieComponent from "@/components/common/lottie/LottieComponent";
import SignInContainer from "@/containers/auth/SignInContainer";
import { Metadata } from "next";
import Image from "next/image";
import Link from "next/link";

export const metadata: Metadata = {
title: "로그인 페이지",
Expand All @@ -18,81 +15,7 @@ export default function page() {
}
style={{ minHeight: "calc(100vh - 30rem)" }}
>
<div className={"flex max-w-[17.5rem] flex-col pb-[8.125rem] pt-[6rem]"}>
<h1 className={"pb-[1rem] text-3xl font-bold"}> 로그인 </h1>
<p className={"text-md text-[#666]"}>
SNS로 솔리투어에 로그인하고 더 많은 서비스를 즐겨보세요!
</p>
<div className={"relative h-[245px] w-[275px] py-[.75rem]"}>
<LottieComponent
lottieFile={introLottie}
className="h-full w-[275px]"
/>
<div className="absolute left-[4.5rem] top-[6.25rem]">
<Image
src={"/solitour-intro-image.svg"}
alt={"kakao-logo-image"}
width={177}
height={107}
/>
</div>
</div>
<Link
className={
"relative mb-[0.75rem] flex h-[2.875rem] w-full items-center justify-center rounded-xl bg-[#FEE500]"
}
href={`https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=${process.env.KAKAO_REST_API_KEY}&redirect_uri=${process.env.KAKAO_REDIRECT_URL}&prompt=login`}
>
<div className="absolute left-[1rem] top-[50%] aspect-square w-[1rem] translate-y-[-50%]">
<Image
src={"/kakao-icon.svg"}
alt={"kakao-logo-image"}
fill={true}
/>
</div>
카카오로 로그인
</Link>
<Link
className={
"relative mb-[3rem] h-[2.875rem] w-full rounded-xl outline outline-[1px] outline-offset-[-1px] outline-[#D9D9D9] items-center justify-center flex"
}
href={`https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=${process.env.GOOGLE_CLIENT_ID}&redirect_uri=${process.env.GOOGLE_REDIRECT_URL}&scope=email profile&prompt=select_account`}
>
<div className="absolute left-[1rem] top-[50%] aspect-square w-[1rem] translate-y-[-50%]">
<Image
src={"/google-icon.svg"}
alt={"google-logo-image"}
fill={true}
/>
</div>
구글로 로그인
</Link>
<div className={"relative flex w-full justify-center"}>
<div className={"absolute top-[-.5rem] flex flex-col items-center"}>
<div
className={
"relative translate-y-[-100%] rounded-xl bg-[#000] px-[1rem] py-[0.5rem] text-[0.625rem] text-[#fff]"
}
>
1초만의 빠른 회원가입
<div
className={
"absolute left-[50%] top-[2rem] h-0 w-0 translate-x-[-50%] translate-y-[-50%] border-l-[7px] border-r-[7px] border-t-[7px] border-x-transparent border-t-[black]"
}
></div>
</div>
</div>
<p className={"relative flex w-full justify-center"}>
아직 계정이 없으신가요?
<Link
href={"/auth/signup"}
className={"px-[0.25rem] font-bold text-[#00B488]"}
>
회원가입
</Link>
</p>
</div>
</div>
<SignInContainer />
</main>
);
}
Expand Down
21 changes: 21 additions & 0 deletions src/components/auth/AuthLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import LottieAirplane from "@/../public/lottie/loading-airplane.json";
import LottieComponent from "@/components/common/lottie/LottieComponent";

const AuthLoading = () => {
return (
<div
className={
"fixed left-0 top-0 z-50 flex flex-col h-[100vh] w-[100vw] items-center justify-center bg-white"
}
>
<div className={"relative h-[245px] w-[275px]"}>
<LottieComponent
lottieFile={LottieAirplane}
className="h-full w-[275px]"
/>
</div>
<p> 로딩 중... </p>
</div>
);
};
export default AuthLoading;
81 changes: 81 additions & 0 deletions src/components/auth/SignIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import introLottie from "@/../public/lottie/solitour-intro-image.json";
import LottieComponent from "@/components/common/lottie/LottieComponent";
import Image from "next/image";
import Link from "next/link";

const SignIn = () => {
return (
<div className={"flex max-w-[17.5rem] flex-col pb-[8.125rem] pt-[6rem]"}>
<h1 className={"pb-[1rem] text-3xl font-bold"}> 로그인 </h1>
<p className={"text-md text-[#666]"}>
SNS로 솔리투어에 로그인하고 더 많은 서비스를 즐겨보세요!
</p>
<div className={"relative h-[245px] w-[275px] py-[.75rem]"}>
<LottieComponent
lottieFile={introLottie}
className="h-full w-[275px]"
/>
<div className="absolute left-[4.5rem] top-[6.25rem]">
<Image
src={"/solitour-intro-image.svg"}
alt={"kakao-logo-image"}
width={177}
height={107}
/>
</div>
</div>
<Link
className={
"relative mb-[0.75rem] flex h-[2.875rem] w-full items-center justify-center rounded-xl bg-[#FEE500]"
}
href={`https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=${process.env.KAKAO_REST_API_KEY}&redirect_uri=${process.env.KAKAO_REDIRECT_URL}`}
>
<div className="absolute left-[1rem] top-[50%] aspect-square w-[1rem] translate-y-[-50%]">
<Image src={"/kakao-icon.svg"} alt={"kakao-logo-image"} fill={true} />
</div>
카카오로 로그인
</Link>
<Link
className={
"relative mb-[3rem] flex h-[2.875rem] w-full items-center justify-center rounded-xl outline outline-[1px] outline-offset-[-1px] outline-[#D9D9D9]"
}
href={`https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=${process.env.GOOGLE_CLIENT_ID}&redirect_uri=${process.env.GOOGLE_REDIRECT_URL}&scope=email profile&prompt=select_account`}
>
<div className="absolute left-[1rem] top-[50%] aspect-square w-[1rem] translate-y-[-50%]">
<Image
src={"/google-icon.svg"}
alt={"google-logo-image"}
fill={true}
/>
</div>
구글로 로그인
</Link>
<div className={"relative flex w-full justify-center"}>
<div className={"absolute top-[-.5rem] flex flex-col items-center"}>
<div
className={
"relative translate-y-[-100%] rounded-xl bg-[#000] px-[1rem] py-[0.5rem] text-[0.625rem] text-[#fff]"
}
>
1초만의 빠른 회원가입
<div
className={
"absolute left-[50%] top-[2rem] h-0 w-0 translate-x-[-50%] translate-y-[-50%] border-l-[7px] border-r-[7px] border-t-[7px] border-x-transparent border-t-[black]"
}
></div>
</div>
</div>
<p className={"relative flex w-full justify-center"}>
아직 계정이 없으신가요?
<Link
href={"/auth/signup"}
className={"px-[0.25rem] font-bold text-[#00B488]"}
>
회원가입
</Link>
</p>
</div>
</div>
);
};
export default SignIn;
54 changes: 54 additions & 0 deletions src/containers/auth/AuthKaKaoContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"use client";

import AuthLoading from "@/components/auth/AuthLoading";
import UrlQueryStringToObject from "@/utils/UrlQueryStringToObject";
import { useRouter } from "next/navigation";
import { useEffect } from "react";


const AuthKaKaoContainer = () => {
const router = useRouter();

useEffect(() => {
const _queryStringObject = UrlQueryStringToObject<{
[key: string]: string;
}>(window.location.href);
const kakaoLogin = async () => {
try {
const response = await fetch(
`${process.env.BACKEND_URL}/api/auth/oauth2/login?type=kakao&redirectUrl=${process.env.KAKAO_REDIRECT_URL}
&code=${_queryStringObject?.code}`,
{
method: "GET",
headers: {
"Content-Type": "application/json;charset=utf-8",
"Access-Control-Allow-Origin": "*",
},
credentials: "include",
},
);

if (!response.ok) {
throw new Error("Network response was not ok");
}

const res = await response.json();
console.log(res);
// res.accessToken 받아서 사용자 정보 받아오고 홈으로 이동
router.push("/");
} catch (error) {
console.error(
"로그인 실패",
error,
);
router.push("/auth/signin")
}
};

kakaoLogin();
}, []);

return <AuthLoading />
};

export default AuthKaKaoContainer;
12 changes: 12 additions & 0 deletions src/containers/auth/SignInContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"use client";

import SignIn from "@/components/auth/SignIn";

const SignInContainer = () => {

return (
<SignIn />
);
};

export default SignInContainer;
54 changes: 54 additions & 0 deletions src/store/authStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { StateCreator, create } from "zustand";
import { devtools } from "zustand/middleware";

// 1. 상태 인터페이스 정의
interface AuthState {
id: number;
userStatus: string; // "활성화" | "휴먼" | "삭제" | "관리자" | "";
nickname: string;
name: string;
age: number; // 연도
sex: string;
email: string;
phoneNumber: string;
isAdmin: boolean;
createdAt: string;
}

// 2. 액션 인터페이스 정의
interface AuthActions {
initialize: () => void;
setUser: (data: Partial<AuthState>) => void;
}

// 3. 초기 상태 정의
const initialState: AuthState = {
id: NaN,
userStatus: "",
nickname: "",
name: "",
age: 0,
sex: "",
email: "",
phoneNumber: "",
isAdmin: false,
createdAt: "",
};

// 4. 상태 및 액션 생성
const authStore: StateCreator<AuthState & AuthActions> = (set, get) => ({
...initialState,
initialize: () => set(initialState),
setUser: (data) =>
set(() => ({
...data,
})),
});

const useAuthStore = create<AuthState & AuthActions>()<any>(
process.env.NODE_ENV === "development" ? devtools(authStore) : authStore,
);

export type useAuthStoreType = AuthState & AuthActions;

export default useAuthStore;
25 changes: 25 additions & 0 deletions src/utils/UrlQueryStringToObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @description 주소에서 parameter 부분을 빼서 객체로
*/

interface IObjectKeys {
[key: string]: string | number | undefined;
}

const UrlQueryStringToObject = <T extends IObjectKeys>(
url?: string,
): T | undefined => {
const obj: IObjectKeys = {};
const _url = url || window.document.location.href;
const queryString = _url.substring(_url.indexOf("?") + 1, _url.length);
queryString.split("&").map((i) => {
const [key, value] = i.split("=");
obj[key] = decodeURIComponent(value);
});
if (_url.indexOf("?") === -1) {
return undefined;
}
return obj as T;
};

export default UrlQueryStringToObject;

0 comments on commit d17b24e

Please sign in to comment.