Skip to content

Commit 0eac82d

Browse files
authored
[Feat] 게스트 로그인 구현
[Feat] 게스트 로그인 구현
2 parents 8e77481 + e7b5e3a commit 0eac82d

File tree

2 files changed

+114
-85
lines changed

2 files changed

+114
-85
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { useState } from 'react';
2+
import WelcomeCharacter from '@components/WelcomeCharacter';
3+
import { useAuth } from '@/hooks/useAuth';
4+
import { Button } from '@components/ui/button';
5+
import { createPortal } from 'react-dom';
6+
import Modal from '@components/Modal';
7+
import { GithubIcon, GoogleIcon } from '@components/Icons';
8+
import axiosInstance from '@/services/axios';
9+
10+
function LogInButton() {
11+
const [showModal, setShowModal] = useState(false);
12+
const { requestLogIn, setLogIn } = useAuth();
13+
14+
const handleLogInClick = () => {
15+
setShowModal(true);
16+
};
17+
18+
const handleGuestLogIn = () => {
19+
axiosInstance.post('/v1/auth/signin/guest').then(response => {
20+
if (response.data.success) {
21+
setLogIn(response.data.data.accessToken);
22+
}
23+
});
24+
};
25+
26+
return (
27+
<>
28+
<Button className="bg-surface-brand-default hover:bg-surface-brand-alt" onClick={handleLogInClick}>
29+
로그인
30+
</Button>
31+
{showModal &&
32+
createPortal(
33+
<Modal setShowModal={setShowModal} modalClassName="h-[360px] w-1/3">
34+
<div className="flex flex-col flex-1">
35+
<div className="flex flex-row h-24 text-text-strong font-bold text-3xl md:text-5xl items-center justify-center px-5">
36+
WELCOME!
37+
<WelcomeCharacter size={80} />
38+
</div>
39+
<div className="flex flex-row md:flex-col h-full justify-around items-center gap-3 p-4">
40+
<button
41+
onClick={() => {
42+
requestLogIn('github');
43+
}}
44+
className="flex flex-row items-center h-16 w-15 md:w-4/5 border border-border-bold rounded-circle "
45+
>
46+
<GithubIcon size={60} />
47+
<span className="hidden flex-1 md:flex justify-center text-text-strong text-display-bold16 lg:text-display-bold24 px-5">
48+
Gihub로 로그인하기
49+
</span>
50+
</button>
51+
<button
52+
onClick={() => {
53+
requestLogIn('google');
54+
}}
55+
className="flex flex-row items-center h-16 w-15 md:w-4/5 border border-border-bold rounded-circle "
56+
>
57+
<GoogleIcon />
58+
<span className="hidden md:flex flex-1 justify-center text-text-strong text-display-bold16 lg:text-display-bold24 px-5">
59+
Google로 로그인하기
60+
</span>
61+
</button>
62+
<button className="border-none underline" onClick={handleGuestLogIn}>
63+
게스트로 로그인하기
64+
</button>
65+
</div>
66+
</div>
67+
</Modal>,
68+
document.body,
69+
)}
70+
</>
71+
);
72+
}
73+
74+
export default LogInButton;

apps/client/src/components/Header/index.tsx

+40-85
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
import { useContext, useEffect, useRef, useState } from 'react';
2-
import { Button } from '@components/ui/button';
32
import { useNavigate } from 'react-router-dom';
4-
import { cn } from '@utils/utils';
5-
import { Character, GithubIcon, GoogleIcon, Logo } from '@components/Icons';
6-
import { createPortal } from 'react-dom';
7-
import Modal from '@components/Modal';
8-
import WelcomeCharacter from '@components/WelcomeCharacter';
9-
import { useAuth } from '@hooks/useAuth';
10-
import { AuthContext } from '@/contexts/AuthContext';
3+
import { Character, Logo } from '@components/Icons';
114
import { Avatar, AvatarFallback, AvatarImage } from '@components/ui/avatar';
5+
import { AuthContext } from '@/contexts/AuthContext';
126
import axiosInstance from '@/services/axios';
7+
import { cn } from '@utils/utils';
8+
import LogInButton from './LogInButton';
9+
import { Button } from '../ui/button';
10+
import { useAuth } from '@/hooks/useAuth';
1311

1412
function Header() {
1513
const [isCheckedIn, setIsCheckedIn] = useState(false);
16-
const [showModal, setShowModal] = useState(false);
14+
const [profileImgUrl, setProfileImgUrl] = useState('');
1715
const broadcastRef = useRef<Window | null>(null);
18-
const [profileImgUrl, setProfileImgUrl] = useState<string>('');
19-
const navigate = useNavigate();
20-
21-
const { requestLogIn, logout } = useAuth();
2216
const { isLoggedIn } = useContext(AuthContext);
17+
const { logout } = useAuth();
18+
const navigate = useNavigate();
2319

2420
const handleLogoClick = () => {
2521
if (window.location.pathname === '/') {
@@ -28,16 +24,6 @@ function Header() {
2824
navigate('/');
2925
}
3026
};
31-
32-
const handleLogInClick = () => {
33-
setShowModal(true);
34-
};
35-
36-
const handleLogOutClick = () => {
37-
logout();
38-
navigate('/');
39-
};
40-
4127
const handleCheckInClick = () => {
4228
if (broadcastRef.current && !broadcastRef.current.closed) {
4329
broadcastRef.current.focus();
@@ -71,6 +57,11 @@ function Header() {
7157
}
7258
};
7359

60+
const handleLogOutClick = () => {
61+
logout();
62+
navigate('/');
63+
};
64+
7465
useEffect(() => {
7566
if (!isLoggedIn) return;
7667
axiosInstance.get('/v1/members/profile-image').then(response => {
@@ -85,69 +76,33 @@ function Header() {
8576
<Character size={48} />
8677
<Logo width={109} height={50} />
8778
</div>
88-
{isLoggedIn ? (
89-
<div className="flex gap-2 items-center">
90-
<Button
91-
className={cn({
92-
'bg-surface-brand-default hover:bg-surface-brand-alt': !isCheckedIn,
93-
})}
94-
onClick={handleCheckInClick}
95-
>
96-
체크인
97-
</Button>
98-
<Button onClick={handleLogOutClick}>로그아웃</Button>
99-
<Avatar
100-
onClick={() => {
101-
navigate('/profile');
102-
}}
103-
className="cursor-pointer h-10 w-10"
104-
aria-label="마이페이지로 이동"
105-
>
106-
<AvatarImage src={profileImgUrl} className="h-10 w-10" alt="마이페이지로 이동" />
107-
<AvatarFallback className="bg-surface-alt">MY</AvatarFallback>
108-
</Avatar>
109-
</div>
110-
) : (
111-
<Button className="bg-surface-brand-default hover:bg-surface-brand-alt" onClick={handleLogInClick}>
112-
로그인
113-
</Button>
114-
)}
115-
{showModal &&
116-
createPortal(
117-
<Modal setShowModal={setShowModal} modalClassName="h-80 w-1/3">
118-
<div className="flex flex-col flex-1">
119-
<div className="flex flex-row h-24 text-text-strong font-bold text-3xl md:text-5xl items-center justify-center px-5">
120-
WELCOME!
121-
<WelcomeCharacter size={80} />
122-
</div>
123-
<div className="flex flex-row md:flex-col h-full justify-around items-center gap-3 p-4">
124-
<button
125-
onClick={() => {
126-
requestLogIn('github');
127-
}}
128-
className="flex flex-row items-center h-16 w-15 md:w-4/5 border border-border-bold rounded-circle "
129-
>
130-
<GithubIcon size={60} />
131-
<span className="hidden flex-1 md:flex justify-center text-text-strong text-display-bold16 lg:text-display-bold24 px-5">
132-
Gihub로 로그인하기
133-
</span>
134-
</button>
135-
<button
136-
onClick={() => {
137-
requestLogIn('google');
138-
}}
139-
className="flex flex-row items-center h-16 w-15 md:w-4/5 border border-border-bold rounded-circle "
140-
>
141-
<GoogleIcon />
142-
<span className="hidden md:flex flex-1 justify-center text-text-strong text-display-bold16 lg:text-display-bold24 px-5">
143-
Google로 로그인하기
144-
</span>
145-
</button>
146-
</div>
147-
</div>
148-
</Modal>,
149-
document.body,
79+
<div className="flex items-center">
80+
{isLoggedIn ? (
81+
<div className="flex gap-2 items-center">
82+
<Button
83+
className={cn({
84+
'bg-surface-brand-default hover:bg-surface-brand-alt': !isCheckedIn,
85+
})}
86+
onClick={handleCheckInClick}
87+
>
88+
체크인
89+
</Button>
90+
<Button onClick={handleLogOutClick}>로그아웃</Button>
91+
<Avatar
92+
onClick={() => {
93+
navigate('/profile');
94+
}}
95+
className="cursor-pointer h-10 w-10"
96+
aria-label="마이페이지로 이동"
97+
>
98+
<AvatarImage src={profileImgUrl} className="h-10 w-10" alt="마이페이지로 이동" />
99+
<AvatarFallback className="bg-surface-alt">MY</AvatarFallback>
100+
</Avatar>
101+
</div>
102+
) : (
103+
<LogInButton />
150104
)}
105+
</div>
151106
</header>
152107
);
153108
}

0 commit comments

Comments
 (0)