From 189e7ff4275a5afe9a844b4704d939efcefd42aa Mon Sep 17 00:00:00 2001 From: happyhyep Date: Mon, 18 Nov 2024 18:38:54 +0900 Subject: [PATCH] =?UTF-8?q?[FE][Feat]=20#197=20:=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20api=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로그인 dto 추가 - 로그인 api 연동 --- frontend/src/api/auth.api.ts | 27 ++++++++++ frontend/src/api/client.api.ts | 31 +++++++++++ frontend/src/api/dto/auth.dto.ts | 5 ++ frontend/src/api/dto/response.dto.ts | 16 ++++++ .../src/component/authmodal/AuthModal.tsx | 13 ++++- frontend/src/constants.ts | 17 ++++++ frontend/src/pages/Main.tsx | 2 +- frontend/src/utils/common/manageLocalData.ts | 53 +++++++++++++++++++ 8 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 frontend/src/api/auth.api.ts create mode 100644 frontend/src/api/client.api.ts create mode 100644 frontend/src/api/dto/auth.dto.ts create mode 100644 frontend/src/api/dto/response.dto.ts create mode 100644 frontend/src/constants.ts create mode 100644 frontend/src/utils/common/manageLocalData.ts diff --git a/frontend/src/api/auth.api.ts b/frontend/src/api/auth.api.ts new file mode 100644 index 00000000..905bed49 --- /dev/null +++ b/frontend/src/api/auth.api.ts @@ -0,0 +1,27 @@ +import { getApiClient } from '@/api/client.api.ts'; +import { ResponseDto } from '@/api/dto/response.dto.ts'; +import { LoginResEntity } from '@/api/dto/auth.dto.ts'; + +export const doLogin = (id: string, password: string): Promise> => { + const promiseFn = ( + fnResolve: (value: ResponseDto) => void, + fnReject: (reason?: any) => void, + ) => { + const apiClient = getApiClient(); + apiClient + .post('/auth/login', { id, password }) + .then(res => { + if (!res.data.success) { + console.error(res); + fnReject(`msg.${res.data.resultMsg}`); + } else { + fnResolve(new ResponseDto(res.data)); + } + }) + .catch(err => { + console.error(err); + fnReject('msg.RESULT_FAILED'); + }); + }; + return new Promise(promiseFn); +}; diff --git a/frontend/src/api/client.api.ts b/frontend/src/api/client.api.ts new file mode 100644 index 00000000..78bdadb1 --- /dev/null +++ b/frontend/src/api/client.api.ts @@ -0,0 +1,31 @@ +import { AppConfig } from '@/constants'; +import { loadLocalData } from '@/utils/common/manageLocalData.ts'; +import axios from 'axios'; + +let apiClient = axios.create({ + baseURL: AppConfig.API_SERVER, + headers: { + 'Content-type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': true, + }, +}); + +export function setApiToken(token: string): void { + if (apiClient) apiClient.defaults.headers.common.Authorization = `Bearer ${token}`; +} + +export const getApiClient = () => { + const token = loadLocalData(AppConfig.KEYS.LOGIN_TOKEN); + if (token) setApiToken(token); + if (!apiClient) { + apiClient = axios.create({ + baseURL: AppConfig.API_SERVER, + headers: { + 'Content-type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }); + } + return apiClient; +}; diff --git a/frontend/src/api/dto/auth.dto.ts b/frontend/src/api/dto/auth.dto.ts new file mode 100644 index 00000000..da567559 --- /dev/null +++ b/frontend/src/api/dto/auth.dto.ts @@ -0,0 +1,5 @@ +export class LoginResEntity { + token: string | undefined; + + userId: string | undefined; +} diff --git a/frontend/src/api/dto/response.dto.ts b/frontend/src/api/dto/response.dto.ts new file mode 100644 index 00000000..a071613b --- /dev/null +++ b/frontend/src/api/dto/response.dto.ts @@ -0,0 +1,16 @@ +export class ResponseDto { + resultCode = 0; + + resultMsg = ''; + + data?: T; + + totalCount = 0; + + constructor(data?: any) { + if (data.resultCode) this.resultCode = data.resultCode; + if (data.resultMsg) this.resultMsg = data.resultMsg; + if (data.data) this.data = data.data; + if (data.totalCount) this.totalCount = data.totalCount; + } +} diff --git a/frontend/src/component/authmodal/AuthModal.tsx b/frontend/src/component/authmodal/AuthModal.tsx index a13689a8..a0d3c114 100644 --- a/frontend/src/component/authmodal/AuthModal.tsx +++ b/frontend/src/component/authmodal/AuthModal.tsx @@ -1,5 +1,8 @@ import React, { useState } from 'react'; import { Modal } from '@/component/common/modal/Modal'; +import { doLogin } from '@/api/auth.api.ts'; +import { saveLocalData } from '@/utils/common/manageLocalData.ts'; +import { AppConfig } from '@/constants.ts'; interface IAuthModalProps { /** 모달이 열려 있는지 여부를 나타냅니다. */ @@ -43,7 +46,13 @@ export const AuthModal = (props: IAuthModalProps) => { }; const handleLoginClick = () => { - console.log('로그인 데이터:', loginData); + doLogin(loginData.id, loginData.pw).then(el => { + if (el.data?.token && el.data?.userId) { + saveLocalData(AppConfig.KEYS.LOGIN_TOKEN, el.data.token); + saveLocalData(AppConfig.KEYS.LOGIN_USER, el.data.userId); + } + window.location.reload(); + }); }; const handleSignUpClick = () => { @@ -63,7 +72,7 @@ export const AuthModal = (props: IAuthModalProps) => { }; return ( - + {modalType === 'login' ? ( <> diff --git a/frontend/src/constants.ts b/frontend/src/constants.ts new file mode 100644 index 00000000..1499d2fe --- /dev/null +++ b/frontend/src/constants.ts @@ -0,0 +1,17 @@ +export const KEYS = { + LOGIN_USER: 'LUT', + LOGIN_TOKEN: 'LUT_TK', +}; + +export const AppConfig = { + /** + * API SERVER + */ + API_SERVER: 'http://223.130.151.43:3001/api', + // API_SERVER: 'http://localhost:3001/api', + + /** + * ETC + */ + KEYS, +}; diff --git a/frontend/src/pages/Main.tsx b/frontend/src/pages/Main.tsx index 42bd85bd..f3c99bb5 100644 --- a/frontend/src/pages/Main.tsx +++ b/frontend/src/pages/Main.tsx @@ -1,4 +1,4 @@ -import React, { Fragment } from 'react'; +import { Fragment } from 'react'; import { getUserLocation } from '@/hooks/getUserLocation'; import { Map } from '@/component/maps/Map'; import { BottomSheet } from '@/component/BottomSheet/BottomSheet'; diff --git a/frontend/src/utils/common/manageLocalData.ts b/frontend/src/utils/common/manageLocalData.ts new file mode 100644 index 00000000..c74b7317 --- /dev/null +++ b/frontend/src/utils/common/manageLocalData.ts @@ -0,0 +1,53 @@ +/* eslint-disable */ +import lzString from 'lz-string' + +export function saveLocalData(key: string, val: string): void { + if (typeof window !== 'undefined') { + const storage = window.localStorage; + + if (storage) { + try { + storage.setItem(key, lzString.compressToUTF16(val)); + } catch (e) { + console.error('Storage Full ... clean old data...'); + for (const k in storage) { + if (k.indexOf('DATA_MESSAGE_DETAIL_') > -1) { + storage.removeItem(k); + } + } + storage.setItem(key, lzString.compressToUTF16(val)); + } + } + } +} + +export function loadLocalData(key: string): string | null { + if (typeof window !== undefined) { + const storage = window.localStorage; + + if (storage) { + const keyValue = storage.getItem(key); + if (keyValue) return lzString.decompressFromUTF16(keyValue); + } + } + return null; +} + +export function clearLocalData() { + if (typeof window !== undefined) { + const storage = window.localStorage; + + if (storage) { + storage.clear(); + } + } +} + +export function removeLocalData(key: string): void { + if (typeof window !== undefined) { + const storage = window.localStorage; + if (storage) { + storage.removeItem(key); + } + } +}