Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(QYOG-37): 로그인 모달 작업 #74

Merged
merged 9 commits into from
Apr 13, 2024
Binary file added src/assets/social/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/social/kakao.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/social/naver.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/svg/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/components/Design/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import * as S from "./emotion";
export default function Modal({
children,
isOpen = false,
setIsOpen,
focusTrap = false,
shouldCloseToClickOutside = true,
horizonAlign = "center",
Expand All @@ -24,6 +25,7 @@ export default function Modal({
}: {
children: React.ReactNode;
isOpen?: boolean;
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
shouldCloseToClickOutside?: boolean;
horizonAlign?: "center" | "left" | "right";
verticalAlign?: "center" | "top" | "bottom";
Expand All @@ -45,6 +47,7 @@ export default function Modal({
return;
setShow(false);
rest.onClose?.();
setIsOpen(false);
};

useEffect(() => {
Expand Down
1 change: 1 addition & 0 deletions src/components/Svg/Icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { default as RightArrow24 } from "./right-arrow-24";
export { default as Search30 } from "./search-30";
export { default as Pan35 } from "./pan-35";
export { default as CheckSquare35 } from "./check-square-35";
export { default as Logo } from "./logo";
42 changes: 42 additions & 0 deletions src/components/Svg/Icons/logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { forwardRef, Ref } from "react";
import { IconProps } from "../Icon";
import Svg from "../Svg";
const Logo = forwardRef(
(
{ size, title, desc, titleId, descId, ...props }: IconProps,
ref: Ref<SVGSVGElement>
) => {
let ariaLabelledBy: string | undefined = titleId ? titleId : "";
ariaLabelledBy += desc && descId ? ` ${descId}` : "";
ariaLabelledBy = ariaLabelledBy ? ariaLabelledBy : undefined;
props["aria-labelledby"] = ariaLabelledBy;
return (
<Svg
width={size}
height={size}
viewBox="0 0 48 48"
xmlns="http://www.w3.org/2000/svg"
title={title}
titleId={titleId}
desc={desc}
descId={descId}
aria-labelledby={ariaLabelledBy}
aria-hidden={!ariaLabelledBy}
ref={ref}
{...props}
>
{!!title && <title id={titleId}>{title}</title>}
{!!desc && <desc id={descId}>{desc}</desc>}
<path d="M44.6901 19.14C44.6801 15.12 44.7101 11.09 44.6801 7.07001C44.6601 3.15001 41.5801 0.0600085 37.6701 0.0400085C27.4901 0.0100085 17.3101 0 7.13013 0C3.08013 0 0.0301494 3.07998 0.0201494 7.13998C0.0101494 11.09 0.0101494 15.04 0.0201494 18.98C0.0201494 20.97 0.950101 21.89 2.9701 21.89C8.0601 21.9 13.1501 21.9 18.2401 21.89C19.9501 21.89 21.0401 20.91 21.0501 19.41C21.0601 17.86 20.0301 16.94 18.2701 16.94C14.3701 16.94 10.4701 16.92 6.57008 16.96C5.79008 16.97 5.56009 16.75 5.58009 15.97C5.63009 13.4 5.60011 10.83 5.60011 8.26001C5.60011 5.83001 6.47012 4.94998 8.87012 4.94998C15.8901 4.94998 22.9201 4.93999 29.9401 4.95999C31.9101 4.96999 33.8801 5.03999 35.8401 5.14999C38.2101 5.27999 39.3701 6.38001 39.5801 8.60001C39.6301 9.12001 39.6401 9.64 39.6401 10.16C39.6401 14.93 39.6401 19.7 39.6401 24.46C39.6401 25.24 39.6401 26.02 39.6401 26.81C39.6401 27.14 39.6901 27.45 39.1301 27.4C35.0901 27.08 31.0401 27.32 26.9901 27.26C25.0201 27.23 24.0901 28.21 24.0901 30.23C24.0801 34.63 24.0601 39.02 24.1101 43.42C24.1201 44.31 23.8701 44.53 23.0001 44.53C17.9801 44.49 12.9701 44.51 7.95008 44.51C5.60008 44.51 5.65009 44.51 5.58009 42.13C5.55009 41.19 5.89009 41.06 6.71009 41.06C10.4301 41.1 14.1401 41.09 17.8601 41.07C19.7601 41.06 20.7501 40.04 20.7701 38.16C20.7801 37.01 20.7901 35.85 20.7701 34.7C20.6801 30.8 17.7801 27.72 14.0101 27.66C10.1801 27.59 6.36004 27.65 2.53004 27.64C1.82004 27.64 1.22011 27.87 0.73011 28.38C-0.0198897 29.16 -0.189909 30.09 0.210091 31.06C0.640091 32.13 1.52006 32.62 2.68006 32.62C5.95006 32.61 9.22012 32.61 12.4901 32.62C13.8601 32.63 14.8901 33.44 15.1701 34.68C15.4401 35.86 15.2901 36.05 14.1101 36.05C10.3901 36.05 6.68009 36.03 2.96009 36.06C0.980091 36.07 0.0400469 37.06 0.0400469 39.03C0.0400469 41.45 0.0400469 43.87 0.0400469 46.29C0.0400469 48.68 0.86013 49.51 3.25013 49.51C9.60013 49.51 15.9601 49.51 22.3101 49.51C28.7001 49.51 35.0901 49.51 41.4801 49.51C43.9801 49.51 44.8301 48.66 44.8201 46.17C44.7701 37.16 44.7201 28.15 44.6901 19.14ZM38.4501 44.53C35.7801 44.5 33.1101 44.5 30.4401 44.53C29.8201 44.54 29.6101 44.37 29.6201 43.73C29.6601 41.95 29.6301 40.16 29.6301 38.38C29.6301 36.6 29.6501 34.81 29.6201 33.03C29.6101 32.39 29.8201 32.2 30.4501 32.22C32.4501 32.26 34.4501 32.21 36.4501 32.24C38.1701 32.26 39.2301 33.32 39.2401 35.03C39.2601 37.93 39.2301 40.83 39.2601 43.72C39.2801 44.36 39.0801 44.54 38.4501 44.53Z" />
</Svg>
);
}
);
Logo.defaultProps = {
// size: 48,
// focusable: false,
// "aria-hidden": true,
// role: "img",
// fill: "currentcolor",
};
export default Logo;
79 changes: 77 additions & 2 deletions src/components/UI/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,41 @@
* Copyright (c) 2024 Your Company
*/

import React from "react";
import React, { useState, useEffect } from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import { useAtom } from "jotai";
import { useSession } from "next-auth/react";

import * as S from "./emotion";
import { useAuth } from "@/hooks";
import { accessTokenAtom } from "@/globalState";
import { authSocialAPI } from "@/apis";

import Logo from "@/assets/main/logo.png";
import { Row } from "@/components/Layouts";
import { Button } from "@/components/Design";
import { Typography, WhatIF } from "@/components/Utilities";
import { LoginModal } from "@/containers/Login";

export default function Header({}: {}) {
const { isLoggedIn, logout } = useAuth();
const [isOpen, setIsOpen] = useState<boolean>(false);
const router = useRouter();

const [accessToken, setAccessToken] = useAtom(accessTokenAtom);
const { data } = useSession();

useEffect(() => {
if (!accessToken) {
if (data) {
authSignIn(data!.user, setAccessToken);
}
} else {
setIsOpen(false);
}
}, [accessToken, data]);

const handleRoute = (ev: React.MouseEvent<HTMLButtonElement>) => {
const target = ev.currentTarget as HTMLButtonElement;
const id = target.id;
Expand Down Expand Up @@ -52,8 +71,61 @@ export default function Header({}: {}) {
}
};

async function authSignIn(user: any, setItem: any) {
await authSocialAPI
.authSocialCheckRegistration({
loginType: user.provider.toUpperCase(),
snsToken: user.access_token,
})
.then((res) => {
if (res.data) {
authSocialAPI
.authSocialSignIn({
loginType: user.provider.toUpperCase(),
snsToken: user.access_token,
})
.then((res) => {
setItem(res.data.accessToken);
})
.catch((err) =>
//에러처리
console.log(err)
);
} else {
authSocialAPI
.authSocialSignUp({
loginType: user.provider.toUpperCase(),
snsToken: user.access_token,
name: null,
email: null,
role: "student",
phoneNumber: null,
grade: null,
gender: "male",
profilePath: null,
//@ts-ignore
majorId: null,
})
.then((res) => {
//@ts-ignore
setItem(res.data.accessToken);
})
.catch((err) =>
//에러처리
console.log(err.data)
);
}
})
.catch((err) =>
//에러처리
console.log(err)
);
}

return (
<S.Container horizonAlign="distribute" verticalAlign="center">
<LoginModal isOpen={isOpen} setIsOpen={setIsOpen} />

<Row gap={66}>
<Button.Text id="root" onClick={handleRoute}>
<Image width="155" height="37" src={Logo} alt="메인헤더로고" />
Expand Down Expand Up @@ -104,7 +176,10 @@ export default function Header({}: {}) {
id="sign-in"
typoSize="SubTitle2"
typoColor="neutral_60"
onClick={handleRoute}
onClick={() => {
setIsOpen(!isOpen);
console.log(isOpen);
}}
hoverTypoColor="neutral_90"
>
로그인
Expand Down
166 changes: 81 additions & 85 deletions src/containers/Login/Form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,99 +4,95 @@
* Copyright (c) 2023 Your Company
*/

import { signIn, useSession } from "next-auth/react";
import { useEffect } from "react";
import { authSocialAPI } from "@/apis";
import { signIn } from "next-auth/react";
import { accessTokenAtom } from "@/globalState";
import { useAtom } from "jotai";
import { useRouter } from "next/router";
import { useAuth } from "@/hooks";
import * as S from "./emotion";
import Logo from "@/assets/main/logo_2.png";
import Google from "@/assets/social/google.png";
import Naver from "@/assets/social/naver.png";
import Kakao from "@/assets/social/kakao.png";
import { Typography } from "@/components/Utilities";

export default function Form() {
const { data } = useSession();
const [accessToken, setAccessToken] = useAtom(accessTokenAtom);
const router = useRouter();
const { logout } = useAuth();

useEffect(() => {
if (!accessToken) {
if (data) {
authSignIn(data!.user, setAccessToken);
}
} else {
router.push("/");
}
console.log(accessToken);
}, [accessToken, data]);

async function authSignIn(user: any, setItem: any) {
await authSocialAPI
.authSocialCheckRegistration({
loginType: user.provider.toUpperCase(),
snsToken: user.access_token,
})
.then((res) => {
if (res.data) {
authSocialAPI
.authSocialSignIn({
loginType: user.provider.toUpperCase(),
snsToken: user.access_token,
})
.then((res) => {
setItem(res.data.accessToken);
})
.catch((err) =>
//에러처리
console.log(err)
);
} else {
authSocialAPI
.authSocialSignUp({
loginType: user.provider.toUpperCase(),
snsToken: user.access_token,
name: null,
email: null,
role: "student",
phoneNumber: null,
grade: null,
gender: "male",
profilePath: null,
//@ts-ignore
majorId: null,
})
.then((res) => {
//@ts-ignore
setItem(res.data.accessToken);
})
.catch((err) =>
//에러처리
console.log(err.data)
);
}
})
.catch((err) =>
//에러처리
console.log(err)
);
}

return (
<div>
{!accessToken ? (
<div>
<button onClick={async () => signIn("kakao")}>카카오</button>
<button onClick={() => signIn("google")}>구글</button>
<button onClick={() => signIn("naver")}>네이버</button>
</div>
) : (
<button
onClick={() => {
logout();
}}
>
로그아웃
</button>
)}
</div>
<S.Wrap>
<S.Left verticalAlign="center" horizonAlign="center">
<S.LeftLogo src={Logo} alt="LeftLogo" />
</S.Left>
<S.Right verticalAlign="center" horizonAlign="center">
<S.RightLogo name="Logo" fill="primary_100" />
<S.Regist>
<Typography typoSize="Head3" typoColor="primary_100">
회원가입
</Typography>
</S.Regist>
{!accessToken ? (
<S.ButtonDiv>
<S.Button
verticalAlign="center"
horizonAlign="center"
bgColor="#34AD37"
onClick={() => signIn("naver")}
>
<S.ButtonLogoDiv
horizonAlign="center"
verticalAlign="center"
bgColor="#2D843A"
>
<S.ButtonLogo src={Naver} alt="naverIcon" />
</S.ButtonLogoDiv>
<S.ButtonText textColor="white">
네이버 계정으로 가입
</S.ButtonText>
</S.Button>
<S.Button
horizonAlign="center"
verticalAlign="center"
bgColor="#FFC63A"
onClick={() => signIn("kakao")}
>
<S.ButtonLogoDiv
horizonAlign="center"
verticalAlign="center"
bgColor="#FFBB12"
>
<S.ButtonLogo src={Kakao} alt="kakaoIcon" />
</S.ButtonLogoDiv>
<S.ButtonText textColor="white">
카카오 계정으로 가입
</S.ButtonText>
</S.Button>
<S.Button
horizonAlign="center"
verticalAlign="center"
bgColor="white"
onClick={() => signIn("google")}
>
<S.ButtonLogoDiv
horizonAlign="center"
verticalAlign="center"
bgColor="white"
>
<S.ButtonLogo src={Google} alt="googleIcon" />
</S.ButtonLogoDiv>
<S.ButtonText textColor="black">구글 계정으로 가입</S.ButtonText>
</S.Button>
</S.ButtonDiv>
) : (
<button
onClick={() => {
logout();
}}
>
로그아웃
</button>
)}
</S.Right>
</S.Wrap>
);
}
Loading
Loading