Skip to content

Commit

Permalink
Merge pull request #40 from boostcampwm-2024/feature/connect/login-#4
Browse files Browse the repository at this point in the history
[FE] 로그인 API 연동 #4
  • Loading branch information
dannysir authored Nov 7, 2024
2 parents 0f27228 + 3388d71 commit bea670e
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 31 deletions.
31 changes: 22 additions & 9 deletions FE/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import useAuthStore from 'store/authStore';
import useLoginModalStore from 'store/useLoginModalStore';

export default function Header() {
const { toggleModal } = useLoginModalStore();
const { isLogin, resetToken } = useAuthStore();

return (
<header className='fixed left-0 top-0 h-[60px] w-full'>
Expand All @@ -26,15 +28,26 @@ export default function Header() {
</div>
</div>
<div className='flex items-center gap-4'>
<button
className='px-4 py-2 text-sm text-juga-grayscale-500'
onClick={toggleModal}
>
로그인
</button>
<button className='px-4 py-2 text-sm text-white rounded-lg bg-juga-grayscale-black'>
회원가입
</button>
{isLogin ? (
<button
className='px-4 py-2 text-sm text-juga-grayscale-500'
onClick={resetToken}
>
로그아웃
</button>
) : (
<>
<button
className='px-4 py-2 text-sm text-juga-grayscale-500'
onClick={toggleModal}
>
로그인
</button>
{/* <button className='px-4 py-2 text-sm text-white rounded-lg bg-juga-grayscale-black'>
회원가입
</button> */}
</>
)}
</div>
</div>
</header>
Expand Down
12 changes: 4 additions & 8 deletions FE/src/components/Login/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import { HTMLInputTypeAttribute } from 'react';
import { ComponentProps } from 'react';

type LoginInputProps = {
type: HTMLInputTypeAttribute;
placeholder: string;
};
type LoginInputProps = ComponentProps<'input'>;

export default function Input({ type, placeholder }: LoginInputProps) {
export default function Input({ ...props }: LoginInputProps) {
return (
<input
className='px-4 py-2 text-sm border-2 rounded-lg outline-none'
type={type}
placeholder={placeholder}
{...props}
/>
);
}
57 changes: 46 additions & 11 deletions FE/src/components/Login/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,72 @@
import useLoginModalStore from 'store/useLoginModalStore';
import Input from './Input';
import { ChatBubbleOvalLeftIcon } from '@heroicons/react/16/solid';
import { FormEvent, useEffect, useState } from 'react';
import { login } from 'service/auth';
import useAuthStore from 'store/authStore';

export default function Login() {
const { isOpen, toggleModal } = useLoginModalStore();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const { setAccessToken } = useAuthStore();

useEffect(() => {
setEmail('');
setPassword('');
}, [isOpen]);

if (!isOpen) return;

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const res = await login(email, password);

if ('error' in res) {
return;
}

setAccessToken(res.accessToken);
toggleModal();
};

return (
<>
<Overay onClick={() => toggleModal()} />
<section className='fixed left-1/2 top-1/2 flex w-[500px] -translate-x-1/2 -translate-y-1/2 flex-col rounded-2xl bg-white p-20 shadow-lg'>
<h2 className='text-3xl font-bold'>JuGa</h2>
<div className='flex flex-col gap-2 my-10'>
<Input type='text' placeholder='아이디' />
<Input type='password' placeholder='비밀번호' />
</div>
<div className='flex flex-col gap-2'>
<form className='flex flex-col mb-2' onSubmit={handleSubmit}>
<div className='flex flex-col gap-2 my-10'>
<Input
type='text'
placeholder='아이디'
value={email}
onChange={(e) => setEmail(e.target.value)}
autoComplete='username'
/>
<Input
type='password'
placeholder='비밀번호'
value={password}
onChange={(e) => setPassword(e.target.value)}
autoComplete='current-password'
/>
</div>
<button className='py-2 text-white transition rounded-3xl bg-juga-blue-40 hover:bg-juga-blue-50'>
로그인
</button>
<button className='flex items-center justify-center gap-2 rounded-3xl bg-yellow-300 px-3.5 py-2 transition hover:bg-yellow-400'>
<ChatBubbleOvalLeftIcon className='size-5' />
<p>카카오 계정으로 로그인</p>
</button>
</div>
</form>
<button className='flex items-center justify-center gap-2 rounded-3xl bg-yellow-300 px-3.5 py-2 transition hover:bg-yellow-400'>
<ChatBubbleOvalLeftIcon className='size-5' />
<p>카카오 계정으로 로그인</p>
</button>
</section>
</>
);
}

function Overay({ onClick }: { onClick: () => void }) {
return (
<div className='fixed inset-0 bg-black opacity-5' onClick={onClick}></div>
<div className='fixed inset-0 bg-black opacity-30' onClick={onClick}></div>
);
}
1 change: 0 additions & 1 deletion FE/src/components/StockIndex/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export function Chart({ name }: StockIndexChartProps) {
<p className='font-semibold text-juga-blue-40'>-31.55(-1.2%)</p>
</div>
<canvas
id='lineChart'
ref={canvasRef}
width={600}
height={300}
Expand Down
15 changes: 15 additions & 0 deletions FE/src/service/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { LoginFailResponse, LoginSuccessResponse } from 'types';

export async function login(
email: string,
password: string,
): Promise<LoginSuccessResponse | LoginFailResponse> {
return fetch('http://223.130.151.42:3000/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email,
password,
}),
}).then((res) => res.json());
}
21 changes: 21 additions & 0 deletions FE/src/store/authStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { create } from 'zustand';

type AuthStore = {
accessToken: string | null;
isLogin: boolean;
setAccessToken: (token: string) => void;
resetToken: () => void;
};

const useAuthStore = create<AuthStore>((set) => ({
accessToken: null,
isLogin: false,
setAccessToken: (token: string) => {
set({ accessToken: token, isLogin: token !== null });
},
resetToken: () => {
set({ accessToken: null, isLogin: false });
},
}));

export default useAuthStore;
9 changes: 9 additions & 0 deletions FE/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type LoginSuccessResponse = {
accessToken: string;
};

export type LoginFailResponse = {
error: string;
message: string[];
statusCode: number;
};
2 changes: 0 additions & 2 deletions FE/src/utils/chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ export const drawChart = (ctx: CanvasRenderingContext2D, data: number[]) => {
chartHeight -
(chartHeight * (point - yMin)) / (yMax - yMin);

console.log(point);

if (i === 0) {
ctx.moveTo(x, y);
} else {
Expand Down

0 comments on commit bea670e

Please sign in to comment.