feat: 지붕재 적합성 데이터 아코디언 처리 추가, 적합성 아이콘 수정
This commit is contained in:
parent
84771ad742
commit
4392802298
@ -1,5 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import Image from 'next/image'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import SuitableList from './SuitableList'
|
import SuitableList from './SuitableList'
|
||||||
import { useSuitable } from '@/hooks/useSuitable'
|
import { useSuitable } from '@/hooks/useSuitable'
|
||||||
@ -77,22 +78,34 @@ export default function Suitable() {
|
|||||||
<ul className="reference-list">
|
<ul className="reference-list">
|
||||||
<li className="reference-item">
|
<li className="reference-item">
|
||||||
<div className="reference-item-bx">
|
<div className="reference-item-bx">
|
||||||
<i className="compliance-icon check"></i>設置可能
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_check_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
<span>設置可能</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li className="reference-item">
|
<li className="reference-item">
|
||||||
<div className="reference-item-bx">
|
<div className="reference-item-bx">
|
||||||
<i className="compliance-icon x"></i>設置可能
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_x_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
<span>設置不可</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li className="reference-item">
|
<li className="reference-item">
|
||||||
<div className="reference-item-bx">
|
<div className="reference-item-bx">
|
||||||
<i className="compliance-icon quest"></i>設置可能
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_quest_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
<span>お問い合わせ</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li className="reference-item">
|
<li className="reference-item">
|
||||||
<div className="reference-item-bx">
|
<div className="reference-item-bx">
|
||||||
<i className="compliance-icon tip"></i>設置可能
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_tip_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
<span>備考</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -1,71 +1,87 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import Image from 'next/image'
|
||||||
|
import { useState } from 'react'
|
||||||
import SuitableNoData from './SuitableNoData'
|
import SuitableNoData from './SuitableNoData'
|
||||||
import { useSuitable } from '@/hooks/useSuitable'
|
import { useSuitable } from '@/hooks/useSuitable'
|
||||||
import { useSuitableStore } from '@/store/useSuitableStore'
|
import { useSuitableStore } from '@/store/useSuitableStore'
|
||||||
import { SUITABLE_HEAD_CODE, type SuitableMain, type SuitableDetail } from '@/types/Suitable'
|
import { SUITABLE_HEAD_CODE, type SuitableMain, type SuitableDetail } from '@/types/Suitable'
|
||||||
|
|
||||||
export default function SuitableList() {
|
export default function SuitableList() {
|
||||||
const { toCodeName, suitableSearchResults, isSearchLoading } = useSuitable()
|
const { toCodeName, suitableSearchResults, isSearchLoading, filterSuitableDetail } = useSuitable()
|
||||||
const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore()
|
const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore()
|
||||||
|
const [openItems, setOpenItems] = useState<Set<number>>(new Set())
|
||||||
|
|
||||||
const handleItemClick = (itemId: number) => {
|
const handleItemClick = (itemId: number) => {
|
||||||
selectedItems.some((selected) => selected === itemId) ? removeSelectedItem(itemId) : addSelectedItem(itemId)
|
selectedItems.some((selected) => selected === itemId) ? removeSelectedItem(itemId) : addSelectedItem(itemId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleItemOpen = (itemId: number) => {
|
||||||
|
setOpenItems((prev) => {
|
||||||
|
const newOpenItems = new Set(prev)
|
||||||
|
newOpenItems.has(itemId) ? newOpenItems.delete(itemId) : newOpenItems.add(itemId)
|
||||||
|
return newOpenItems
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: 추후 지붕재 적합성 데이터 CUD 구현 시 ×, ー 데이터 관리 필요
|
// TODO: 추후 지붕재 적합성 데이터 CUD 구현 시 ×, ー 데이터 관리 필요
|
||||||
const suitableCheck = (value: string) => {
|
const suitableCheck = (value: string) => {
|
||||||
if (value === '×') {
|
if (value === '×') {
|
||||||
return <i className="compliance-icon x" />
|
return (
|
||||||
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_x_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
} else if (value === 'ー') {
|
} else if (value === 'ー') {
|
||||||
return <i className="compliance-icon quest" />
|
return (
|
||||||
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_quest_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return <i className="compliance-icon check" />
|
return (
|
||||||
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_check_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterSuitableDetail = (mainId: number): SuitableDetail[] | undefined => {
|
|
||||||
const result: SuitableDetail[] = []
|
|
||||||
for (const subItem of suitableSearchResults?.suitableDetail ?? []) {
|
|
||||||
if (subItem.MAIN_ID > mainId) break
|
|
||||||
if (subItem.MAIN_ID === mainId) {
|
|
||||||
result.push(subItem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isSearchLoading ? (
|
{isSearchLoading ? (
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
) : suitableSearchResults && suitableSearchResults.suitable.length > 0 ? (
|
) : suitableSearchResults && suitableSearchResults.suitable.length > 0 ? (
|
||||||
suitableSearchResults.suitable.map((item: SuitableMain) => (
|
suitableSearchResults.suitable.map((item: SuitableMain) => (
|
||||||
<div className={`compliance-check-bx act`} key={item.ID}>
|
<div className={`compliance-check-bx ${openItems.has(item.ID) ? 'act' : ''}`} key={item.ID}>
|
||||||
<div className="check-name-wrap">
|
<div className="check-name-wrap">
|
||||||
<div className="check-form-box com-tit">
|
<div className="check-form-box ">
|
||||||
<input type="checkbox" id={`ch${item.ID}`} />
|
<input type="checkbox" id={`ch${item.ID}`} onClick={() => handleItemClick(item.ID)} />
|
||||||
<label htmlFor={`ch${item.ID}`}>{item.PRODUCT_NAME}</label>
|
<label htmlFor={`ch${item.ID}`}>{item.PRODUCT_NAME}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="check-name-btn">
|
<div className="check-name-btn">
|
||||||
<button className="bx-btn" onClick={() => handleItemClick(item.ID)}></button>
|
<button className="bx-btn" onClick={() => toggleItemOpen(item.ID)}></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul className="reference-list check">
|
<ul className="reference-list check">
|
||||||
<li className="reference-item">
|
{filterSuitableDetail(item.ID)?.map((subItem: SuitableDetail) => (
|
||||||
{filterSuitableDetail(item.ID)?.map((subItem: SuitableDetail) => (
|
<li className="reference-item" key={subItem.ID}>
|
||||||
<div className="check-item-wrap" key={subItem.ID}>
|
<div className="check-item-wrap">
|
||||||
<div className="check-form-box com-txt">
|
<div className="check-form-box light">
|
||||||
<input type="checkbox" id={`ch${subItem.ID}`} />
|
<input type="checkbox" id={`ch${subItem.ID}`} />
|
||||||
<label htmlFor={`ch${subItem.ID}`}>{toCodeName(SUITABLE_HEAD_CODE.TRESTLE_MFPC_CD, subItem.TRESTLE_MFPC_CD)}</label>
|
<label htmlFor={`ch${subItem.ID}`}>{toCodeName(SUITABLE_HEAD_CODE.TRESTLE_MFPC_CD, subItem.TRESTLE_MFPC_CD)}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="compliance-icon-wrap">
|
<div className="compliance-icon-wrap">
|
||||||
{suitableCheck(subItem.TRESTLE_MANUFACTURER_PRODUCT_NAME)}
|
{suitableCheck(subItem.TRESTLE_MANUFACTURER_PRODUCT_NAME)}
|
||||||
{subItem.MEMO && <i className="compliance-icon tip"></i>}
|
{subItem.MEMO && (
|
||||||
|
<div className="compliance-icon">
|
||||||
|
<Image src={'/assets/images/sub/compliance_tip_icon.svg'} width={22} height={22} alt=""></Image>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
</li>
|
||||||
</li>
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|||||||
@ -82,6 +82,17 @@ export function useSuitable() {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const filterSuitableDetail = (mainId: number): SuitableDetail[] | undefined => {
|
||||||
|
const result: SuitableDetail[] = []
|
||||||
|
for (const subItem of suitableSearchResults?.suitableDetail ?? []) {
|
||||||
|
if (subItem.MAIN_ID > mainId) break
|
||||||
|
if (subItem.MAIN_ID === mainId) {
|
||||||
|
result.push(subItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getSuitables,
|
getSuitables,
|
||||||
getSuitableCommCode,
|
getSuitableCommCode,
|
||||||
@ -91,5 +102,6 @@ export function useSuitable() {
|
|||||||
suitableSearchResults,
|
suitableSearchResults,
|
||||||
refetchBySearch,
|
refetchBySearch,
|
||||||
isSearchLoading,
|
isSearchLoading,
|
||||||
|
filterSuitableDetail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user