429 lines
16 KiB
JavaScript
429 lines
16 KiB
JavaScript
'use client'
|
|
import { Fragment, useCallback, useContext, useEffect, useState } from 'react'
|
|
|
|
import Link from 'next/link'
|
|
import { usePathname, useRouter } from 'next/navigation'
|
|
|
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
|
import { dimmedStore, sessionStore } from '@/store/commonAtom'
|
|
|
|
import { useMessage } from '@/hooks/useMessage'
|
|
import { checkSession } from '@/lib/authActions'
|
|
import { useLogout } from '@/hooks/useLogout'
|
|
|
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
|
|
|
import UserInfoModal from '@/components/myInfo/UserInfoModal'
|
|
import { useAxios } from '@/hooks/useAxios'
|
|
import { globalLocaleStore } from '@/store/localeAtom'
|
|
|
|
import { stuffSearchState } from '@/store/stuffAtom'
|
|
import { QcastContext } from '@/app/QcastProvider'
|
|
|
|
import { usePopup } from '@/hooks/usePopup'
|
|
import { commonCodeState } from '@/store/commonCodeAtom'
|
|
import { isObjectNotEmpty } from '@/util/common-utils'
|
|
import { roofMaterialsAtom } from '@/store/settingAtom'
|
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
|
import { useSwal } from '@/hooks/useSwal'
|
|
|
|
export const ToggleonMouse = (e, act, target) => {
|
|
const listWrap = e.target.closest(target)
|
|
const ListItem = Array.from(listWrap.childNodes)
|
|
ListItem.forEach((el) => {
|
|
if (act === 'add') {
|
|
el.classList.add('mouse')
|
|
} else {
|
|
el.classList.remove('mouse')
|
|
}
|
|
})
|
|
if (act === 'add') {
|
|
e.target.parentElement.classList.remove('mouse')
|
|
}
|
|
}
|
|
|
|
export default function Header(props) {
|
|
const [userInfoModal, setUserInfoModal] = useState(false)
|
|
const router = useRouter()
|
|
|
|
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
|
|
|
const { closeAll } = usePopup()
|
|
const { logoutProcess } = useLogout()
|
|
|
|
const { userSession } = props
|
|
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
|
const { getMessage } = useMessage()
|
|
const pathName = usePathname()
|
|
// if (pathName.includes('login') || pathName.includes('join')) {
|
|
// return null
|
|
// }
|
|
const [selected, setSelected] = useState('')
|
|
|
|
const { isGlobalLoading } = useContext(QcastContext)
|
|
|
|
const dimmedState = useRecoilValue(dimmedStore)
|
|
const isDimmed = dimmedState ? 'opacity-50 bg-black' : ''
|
|
|
|
// Link 이동 자동 로그인
|
|
const [globalLocaleState, setGlbalLocaleState] = useRecoilState(globalLocaleStore)
|
|
const { promisePost } = useAxios(globalLocaleState)
|
|
|
|
const qOrderUrl = process.env.NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL
|
|
const qMusubiUrl = process.env.NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL
|
|
|
|
const [SelectOptions, setSelectOptions] = useState([])
|
|
|
|
const [commonCode, setCommonCode] = useRecoilState(commonCodeState)
|
|
const { promiseGet } = useAxios()
|
|
|
|
const { swalFire } = useSwal()
|
|
|
|
/**
|
|
* 지붕재 목록 Header에서 조회
|
|
*/
|
|
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
|
|
const { getRoofMaterialList } = useMasterController()
|
|
useEffect(() => {
|
|
async function initRoofMaterial() {
|
|
if (roofMaterials.length !== 0) {
|
|
return
|
|
}
|
|
const { data } = await getRoofMaterialList()
|
|
|
|
const roofLists = data.map((item, idx) => ({
|
|
...item,
|
|
id: item.roofMatlCd,
|
|
name: item.roofMatlNm,
|
|
selected: idx === 0,
|
|
index: idx,
|
|
nameJp: item.roofMatlNmJp,
|
|
length: item.lenBase && parseInt(item.lenBase),
|
|
width: item.widBase && parseInt(item.widBase),
|
|
raft: item.raftBase && parseInt(item.raftBase),
|
|
layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL,
|
|
hajebichi: item.roofPchBase && parseInt(item.roofPchBase),
|
|
pitch: item.pitch ? parseInt(item.pitch) : 4,
|
|
angle: item.angle ? parseInt(item.angle) : 21.8,
|
|
}))
|
|
setRoofMaterials(roofLists)
|
|
}
|
|
initRoofMaterial()
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
const getCommonCode = async () => {
|
|
await promiseGet({ url: '/api/commcode/qc-comm-code' }).then((res) => {
|
|
setCommonCode(Object.groupBy(res.data, ({ clHeadCd }) => clHeadCd))
|
|
})
|
|
}
|
|
|
|
if (!isObjectNotEmpty(commonCode)) {
|
|
getCommonCode()
|
|
}
|
|
}, [])
|
|
|
|
const getAutoLoginParam = async () => {
|
|
await promisePost({ url: '/api/login/v1.0/user/login/autoLoginEncryptData', data: { loginId: userSession.userId } })
|
|
.then((res) => {
|
|
if (res) {
|
|
setSelectOptions(
|
|
userSession.storeId === 'T01'
|
|
? [
|
|
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
|
|
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
|
{ id: 2, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
|
{ id: 3, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
|
{ id: 4, name: 'Q.PARTNERS', link: `https://q-partners.q-cells.jp/qcast_login.php`, target: '_blank' },
|
|
|
|
]
|
|
: userSession.groupId === '60000'
|
|
? [
|
|
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
|
|
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
|
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
|
{ id: 3, name: 'Q.PARTNERS', link: `https://q-partners.q-cells.jp/qcast_login.php`, target: '_blank' },
|
|
]
|
|
: [
|
|
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
|
|
{ id: 1, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
|
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
|
{ id: 3, name: 'Q.PARTNERS', link: `https://q-partners.q-cells.jp/qcast_login.php`, target: '_blank' },
|
|
],
|
|
)
|
|
onChangeSelect({ id: 0, name: getMessage('site.header.link1') })
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
alert(error.response.data.message)
|
|
})
|
|
}
|
|
|
|
useEffect(() => {
|
|
getAutoLoginParam()
|
|
}, [userSession])
|
|
|
|
const openEconomicSimulation = async () => {
|
|
const encRes = await promiseGet({
|
|
url: '/api/pwrGnrSimulation/encData',
|
|
params: { saleStoreId: sessionState.saleStoreId, userId: sessionState.userId },
|
|
})
|
|
const { encSaleStoreId, encUserId } = encRes.data
|
|
|
|
if (!encSaleStoreId || !encUserId) return
|
|
|
|
const authRes = await fetch(process.env.NEXT_PUBLIC_ECONOMIC_SIMULATION_AUTH_URL, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ encSaleStoreId, encUserId }),
|
|
})
|
|
|
|
if (authRes.ok) {
|
|
window.open(process.env.NEXT_PUBLIC_ECONOMIC_SIMULATION_URL, 'economicSimulation', `height=${screen.height},width=${screen.width},fullscreen=yes`)
|
|
} else {
|
|
const body = await authRes.json()
|
|
swalFire({ text: body.resultMessage, type: 'error' })
|
|
}
|
|
}
|
|
|
|
const menus = [
|
|
{ id: 0, name: 'header.menus.home', url: '/', children: [] },
|
|
{
|
|
id: 1,
|
|
name: 'header.menus.management',
|
|
url: '',
|
|
children: [
|
|
// { id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempdetail', children: [] },
|
|
{ id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempReg', children: [] },
|
|
{ id: 4, name: 'header.menus.management.stuffList', url: '/management/stuff', children: [] },
|
|
],
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'header.menus.community',
|
|
url: '',
|
|
children: [
|
|
{ id: 5, name: 'header.menus.community.notice', url: '/community/notice', children: [] },
|
|
{ id: 6, name: 'header.menus.community.faq', url: '/community/faq', children: [] },
|
|
{ id: 7, name: 'header.menus.community.archive', url: '/community/archive', children: [] },
|
|
],
|
|
},
|
|
{ id: 8, name: 'qna.title', url: '/community/qna', children: [] },
|
|
...(process.env.NEXT_PUBLIC_RUN_MODE !== 'production'
|
|
? [{ id: 9, name: 'header.menus.economic.simulation', action: openEconomicSimulation, children: [] }]
|
|
: []),
|
|
]
|
|
|
|
const syncSession = useCallback(() => {
|
|
setSessionState({ ...userSession })
|
|
})
|
|
|
|
useEffect(() => {
|
|
syncSession()
|
|
}, [userSession])
|
|
|
|
const onChangeSelect = (option) => {
|
|
setSelected(option)
|
|
}
|
|
|
|
const navPage = () => {
|
|
if (selected.link) {
|
|
if (selected.target === '_blank') {
|
|
window.open(selected.link)
|
|
} else {
|
|
location.href = selected.link
|
|
}
|
|
}
|
|
}
|
|
|
|
// 물건메뉴 이외 클릭시 물건 리코일 비우기
|
|
const removeStuffRecoil = (menu) => {
|
|
//menu.id 0 HOME
|
|
//menu.id 3 신규물건등록
|
|
//menu.id 4 물건리스트
|
|
//menu.id 5 공지사항
|
|
//menu.id 6 FAQ
|
|
//menu.id 7 자료실
|
|
if (menu.id === 0 || menu.id === 5 || menu.id === 6 || menu.id === 7) {
|
|
setStuffSearch({
|
|
...stuffSearch,
|
|
code: 'DELETE',
|
|
})
|
|
}
|
|
}
|
|
|
|
const getMenuTemplate = (menus) => {
|
|
return menus.map((menu) => {
|
|
return (
|
|
<li
|
|
key={`${menu.id}`}
|
|
className={'nav-item'}
|
|
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')}
|
|
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')}
|
|
>
|
|
{menu.children.length === 0 ? (
|
|
menu.action ? (
|
|
<button key={`${menu.id}`} onClick={() => menu.action()}>
|
|
{getMessage(menu.name)}
|
|
</button>
|
|
) : (
|
|
<Link
|
|
key={`${menu.id}`}
|
|
href={menu.url}
|
|
replace={true}
|
|
onClick={(e) => {
|
|
|
|
if(pathName === '/floor-plan') {
|
|
e.preventDefault() // 기본 네비게이션 방지
|
|
e.stopPropagation() // 이벤트 전파 방지
|
|
swalFire({
|
|
text : getMessage('common.link.confirm'), // 적절한 확인 메시지
|
|
type : 'confirm',
|
|
confirmFn: () => {
|
|
// 확인 버튼 클릭 시 실행
|
|
removeStuffRecoil(menu)
|
|
if (pathName === '/' && menu.id !== 8) {
|
|
window.location.reload()
|
|
} else {
|
|
router.push(menu.url)
|
|
}
|
|
router.push(menu.url)
|
|
}
|
|
})
|
|
} else {
|
|
removeStuffRecoil(menu)
|
|
if (pathName === '/' && menu.id !== 8) {
|
|
window.location.reload()
|
|
} else {
|
|
router.push(menu.url)
|
|
}
|
|
}
|
|
}}
|
|
>
|
|
{getMessage(menu.name)}
|
|
</Link>
|
|
)
|
|
) : (
|
|
<Fragment key={`${menu.id}`}>
|
|
<button>{getMessage(menu.name)}</button>
|
|
<ul className="nav-depth2">
|
|
{menu.children.map((m) => {
|
|
return (
|
|
<li
|
|
key={`${m.id}`}
|
|
className={'nav-depth2-item'}
|
|
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
|
|
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
|
|
>
|
|
<Link
|
|
scroll={false}
|
|
href={m.url}
|
|
replace={true}
|
|
onClick={(e) => {
|
|
if(pathName === '/floor-plan') {
|
|
e.preventDefault() // 기본 네비게이션 방지
|
|
e.stopPropagation() // 이벤트 전파 방지
|
|
swalFire({
|
|
text: getMessage('common.link.confirm'), // 적절한 확인 메시지
|
|
type: 'confirm',
|
|
confirmFn: () => {
|
|
// 확인 버튼 클릭 시 기존 로직 실행
|
|
removeStuffRecoil(m)
|
|
router.push(m.url)
|
|
}
|
|
})
|
|
} else {
|
|
removeStuffRecoil(m)
|
|
}
|
|
}
|
|
}
|
|
>
|
|
{getMessage(m.name)}
|
|
</Link>
|
|
</li>
|
|
)
|
|
})}
|
|
</ul>
|
|
</Fragment>
|
|
)}
|
|
</li>
|
|
)
|
|
})
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{!(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && (
|
|
<header className={isDimmed}>
|
|
<div className="header-inner">
|
|
<div className="header-right">
|
|
<h1 className="logo">
|
|
<Link
|
|
href={'/'}
|
|
onClick={(e) => {
|
|
setStuffSearch({
|
|
...stuffSearch,
|
|
code: 'DELETE',
|
|
})
|
|
if (pathName === '/') {
|
|
window.location.reload()
|
|
} else if(pathName === '/floor-plan') {
|
|
e.preventDefault() // 기본 네비게이션 방지
|
|
e.stopPropagation() // 이벤트 전파 방지
|
|
swalFire({
|
|
text: getMessage('common.link.confirm'), // 적절한 확인 메시지
|
|
type: 'confirm',
|
|
confirmFn: () => {
|
|
// 확인 버튼 클릭 시 기존 로직 실행
|
|
//removeStuffRecoil(m)
|
|
router.push('/')
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
}}
|
|
></Link>
|
|
</h1>
|
|
<nav>
|
|
<ul className="nav-list ">{getMenuTemplate(menus)}</ul>
|
|
</nav>
|
|
</div>
|
|
<div className="header-left">
|
|
<div className="profile-box">
|
|
<Link
|
|
href="#"
|
|
onClick={() => {
|
|
setUserInfoModal(true)
|
|
closeAll()
|
|
}}
|
|
>
|
|
<button className="profile">{userSession.userNm}</button>
|
|
</Link>
|
|
{userInfoModal && <UserInfoModal userId={sessionState.userId} userInfoModal={userInfoModal} setUserInfoModal={setUserInfoModal} />}
|
|
</div>
|
|
<div className="sign-out-box">
|
|
<button
|
|
className="sign-out"
|
|
onClick={() => logoutProcess()}
|
|
>
|
|
{getMessage('header.logout')}
|
|
</button>
|
|
</div>
|
|
<div className="select-box">
|
|
<QSelectBox options={SelectOptions} onChange={onChangeSelect} title={getMessage('site.header.link1')} />
|
|
</div>
|
|
<div className="btn-wrap">
|
|
<button className="btn-frame small dark" onClick={() => navPage()}>
|
|
{getMessage('header.go')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
)}
|
|
</>
|
|
)
|
|
}
|