216 lines
6.1 KiB
TypeScript
216 lines
6.1 KiB
TypeScript
'use client'
|
|
|
|
import type { SessionData } from '@/types/Auth'
|
|
import { useEffect, useReducer, useState } from 'react'
|
|
import { useRouter } from 'next/navigation'
|
|
import { useLocalStorage } from 'usehooks-ts'
|
|
import { useQuery } from '@tanstack/react-query'
|
|
import { useSessionStore } from '@/store/session'
|
|
import { useAxios } from '@/hooks/useAxios'
|
|
interface AccountState {
|
|
loginId: string
|
|
pwd: string
|
|
}
|
|
|
|
export default function Login() {
|
|
const router = useRouter()
|
|
//비밀번호 보이기 숨기기
|
|
const [pwShow, setPwShow] = useState(false)
|
|
//ID 저장 체크박스
|
|
const [idSave, setIdSave] = useState(false)
|
|
//Q.PARTNERS 체크박스
|
|
const [isPartners, setIsPartners] = useState(false)
|
|
//로그인 상태
|
|
const [isLogin, setIsLogin] = useState(false)
|
|
|
|
const { axiosInstance } = useAxios()
|
|
|
|
const { session, setSession } = useSessionStore()
|
|
const [value, setValue, removeValue] = useLocalStorage<{ indivisualData: string }>('hanasysIndivisualState', { indivisualData: '' })
|
|
|
|
// ID Save 기능을 위한 로컬스토리지
|
|
const [savedLoginData, setSavedLoginData, removeSavedLoginData] = useLocalStorage<{
|
|
loginId: string
|
|
idSaveEnabled: boolean
|
|
}>('hanasysLoginData', {
|
|
loginId: '',
|
|
idSaveEnabled: false,
|
|
})
|
|
|
|
const reducer = (state: AccountState, newState: Partial<AccountState>) => ({ ...state, ...newState })
|
|
const [account, setAccount] = useReducer(reducer, {
|
|
loginId: '',
|
|
pwd: '',
|
|
})
|
|
|
|
// 컴포넌트 마운트 시 저장된 로그인 정보 불러오기
|
|
useEffect(() => {
|
|
if (savedLoginData.idSaveEnabled) {
|
|
setIdSave(true)
|
|
setAccount({ loginId: savedLoginData.loginId })
|
|
} else {
|
|
setIdSave(false)
|
|
setAccount({ loginId: '' })
|
|
}
|
|
}, [])
|
|
|
|
// ID Save 체크박스 변경 시 처리 (UI 상태만 변경)
|
|
const handleIdSaveChange = (checked: boolean) => {
|
|
setIdSave(checked)
|
|
}
|
|
|
|
const isValidEmail = (email: string) => {
|
|
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
|
return emailRegex.test(email)
|
|
}
|
|
|
|
const handleLogin = () => {
|
|
if (validateLogin()) {
|
|
setIsLogin(true)
|
|
}
|
|
}
|
|
|
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
if (e.key === 'Enter') {
|
|
handleLogin()
|
|
}
|
|
}
|
|
|
|
const validateLogin = () => {
|
|
if (account.loginId === '' || account.pwd === '') {
|
|
/** 아이디와 비밀번호를 입력해 주세요.*/
|
|
alert('IDとパスワードをご入力ください。')
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
interface LoginData {
|
|
code: number
|
|
message: string | null
|
|
result: SessionData
|
|
}
|
|
|
|
const {
|
|
data: loginData,
|
|
isPending,
|
|
error,
|
|
} = useQuery<LoginData, Error>({
|
|
queryKey: ['login', 'account'],
|
|
queryFn: async () => {
|
|
let url = ''
|
|
if (!isPartners) {
|
|
url = '/api/auth'
|
|
} else {
|
|
url = '/api/partner'
|
|
}
|
|
|
|
const { data } = await axiosInstance('').post<LoginData>(`${url}`, {
|
|
loginId: account.loginId,
|
|
pwd: account.pwd,
|
|
})
|
|
// const { data } = await axiosInstance(`${process.env.NEXT_PUBLIC_QSP_API_URL}`).post(`/api/user/login`, {
|
|
// loginId: account.loginId,
|
|
// pwd: account.pwd,
|
|
// })
|
|
|
|
return data
|
|
},
|
|
enabled: isLogin,
|
|
staleTime: 0,
|
|
retry: false,
|
|
})
|
|
|
|
useEffect(() => {
|
|
setIsLogin(false)
|
|
if (loginData?.code === 200) {
|
|
// 유저 정보 저장
|
|
setValue({
|
|
indivisualData: account.pwd,
|
|
})
|
|
|
|
// ID Save 체크박스 체크 시 저장
|
|
idSave
|
|
? setSavedLoginData({
|
|
loginId: account.loginId,
|
|
idSaveEnabled: true,
|
|
})
|
|
: removeSavedLoginData()
|
|
|
|
// 세션 정보 저장
|
|
console.log('🚀 ~ Login ~ loginData:', loginData)
|
|
setSession({
|
|
...session,
|
|
...loginData?.result,
|
|
})
|
|
router.push('/')
|
|
} else if (loginData?.code === 400) {
|
|
alert(loginData?.message)
|
|
setAccount({ loginId: '', pwd: '' })
|
|
}
|
|
}, [loginData])
|
|
|
|
useEffect(() => {
|
|
if (isValidEmail(account.loginId)) {
|
|
setIsPartners(true)
|
|
} else {
|
|
setIsPartners(false)
|
|
}
|
|
}, [account.loginId])
|
|
|
|
return (
|
|
<>
|
|
<div className="login-form-wrap">
|
|
<div className="login-form mb15">
|
|
<div className="login-input id">
|
|
<input
|
|
type="text"
|
|
className="login-frame"
|
|
placeholder="ID"
|
|
value={account.loginId}
|
|
onKeyDown={(e) => handleKeyDown(e)}
|
|
onChange={(e) => setAccount({ loginId: e.target.value })}
|
|
/>
|
|
<button className="login-icon" onClick={() => setAccount({ loginId: '' })}>
|
|
<i className="del-icon"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="login-form">
|
|
<div className="login-input pw">
|
|
<input
|
|
type={`${pwShow ? 'text' : 'password'}`}
|
|
className="login-frame"
|
|
placeholder="Password"
|
|
value={account.pwd}
|
|
onKeyDown={(e) => handleKeyDown(e)}
|
|
onChange={(e) => setAccount({ pwd: e.target.value })}
|
|
/>
|
|
<button className={`login-icon ${pwShow ? '' : 'act'}`} onClick={() => setPwShow(!pwShow)}>
|
|
<i className="show-icon"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="login-check-warp">
|
|
<div className="check-form-box">
|
|
<input type="checkbox" id="ch01" checked={idSave} onChange={(e) => handleIdSaveChange(e.target.checked)} />
|
|
<label htmlFor="ch01">ID Save</label>
|
|
</div>
|
|
<div className="toggle-form">
|
|
<label className="toggle-btn">
|
|
<input type="checkbox" checked={isPartners} onChange={() => setIsPartners(!isPartners)} />
|
|
<span className="slider"></span>
|
|
</label>
|
|
<div className="toggle-name">Q.PARTNERS</div>
|
|
</div>
|
|
</div>
|
|
<div className="login-btn-wrap">
|
|
<button className="btn-frame icon login" onClick={handleLogin}>
|
|
LOGIN <i className="btn-arr"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|