Skip to content

Commit

Permalink
[FE] 비회원 로그인 기능 구현 (#100)
Browse files Browse the repository at this point in the history
* chore: react-cookie 설치

* feat: cookies util 함수 구현

* feat: postAttendeeLogin api 함수 구현

* desgin(AttendeeLoginPage): AttendeeLoginPage style 정의

* feat(AttendeeLoginPage): AttendeeLoginPage 구현
  • Loading branch information
Yoonkyoungme authored Jul 26, 2024
1 parent a84b451 commit a6ad004
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 6 deletions.
40 changes: 34 additions & 6 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@emotion/react": "11.11.4",
"@tanstack/react-query": "5.51.1",
"react": "18.3.1",
"react-cookie": "^7.2.0",
"react-dom": "18.3.1",
"react-router-dom": "6.24.1"
},
Expand Down
40 changes: 40 additions & 0 deletions frontend/src/apis/attendee.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { API_URL } from '@constants/api';

interface PostAttendeeLoginRequest {
uuid: string;
request: {
name: string;
password: string;
};
}

interface PostAttendeeLoginResponse {
data: {
token: string;
};
}

const postAttendeeLogin = async (
props: PostAttendeeLoginRequest,
): Promise<PostAttendeeLoginResponse> => {
const { uuid, request } = props;
const url = `${API_URL}/api/v1/login/${uuid}`;

const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
});

if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

const data = await response.json();

return data;
};

export default postAttendeeLogin;
30 changes: 30 additions & 0 deletions frontend/src/pages/AttendeeLoginPage/AttendeeLoginPage.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { css } from '@emotion/react';

export const s_container = css`
display: flex;
flex-direction: column;
gap: 1rem;
align-items: center;
justify-content: center;
width: 100%;
height: calc(100vh - 6rem);
`;

export const s_inputContainer = css`
display: flex;
flex-direction: column;
gap: 1rem;
width: 90%;
height: 16rem;
padding: 1.6rem;
background-color: #f7dacb;
border-radius: 0.5rem;
`;

export const s_button = css`
width: 90%;
height: 3rem;
`;
61 changes: 61 additions & 0 deletions frontend/src/pages/AttendeeLoginPage/AttendeeLoginPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { useNavigate, useParams } from 'react-router-dom';

import Field from '@components/_common/Field';
import Input from '@components/_common/Input';

import useInput from '@hooks/useInput/useInput';

import postAttendeeLogin from '@apis/attendee';

import { setCookie } from '@utils/cookies';

import { s_button, s_container, s_inputContainer } from './AttendeeLoginPage.styles';

export default function AttendeeLoginPage() {
const { value: name, onValueChange: onNameChange } = useInput();
const { value: password, onValueChange: onPasswordChange } = useInput();

const navigate = useNavigate();
const { uuid } = useParams<{ uuid: string }>();

const handleLoginButtonClick = async () => {
if (!uuid) {
console.error('UUID is missing');
return;
}

try {
const response = await postAttendeeLogin({
uuid,
request: { name, password },
});

setCookie('token', response.data.token, { path: '/', maxAge: 604800 });

navigate('/meeting-time-pick'); // TODO: meeting 조회/수정 페이지로 이동
} catch (error) {
console.error('Login failed:', error);
}
};

return (
<div css={s_container}>
<div css={s_inputContainer}>
<Field labelText="이름" id="name">
<Input placeholder="이름을 입력하세요." value={name} onChange={onNameChange} />
</Field>
<Field labelText="비밀번호" id="password">
<Input
placeholder="비밀번호를 입력하세요."
type="password"
value={password}
onChange={onPasswordChange}
/>
</Field>
</div>
<button css={s_button} onClick={handleLoginButtonClick}>
로그인
</button>
</div>
);
}
20 changes: 20 additions & 0 deletions frontend/src/utils/cookies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Cookies } from 'react-cookie';

interface CookieOptions {
path?: string;
expires?: Date;
maxAge?: number;
domain?: string;
secure?: boolean;
sameSite?: 'strict' | 'lax' | 'none';
}

const cookies = new Cookies();

export const setCookie = (name: string, value: string, options?: CookieOptions) => {
return cookies.set(name, value, { ...options });
};

export const getCookie = (name: string) => {
return cookies.get(name);
};

0 comments on commit a6ad004

Please sign in to comment.