diff --git a/package-lock.json b/package-lock.json index 669f7b5..463c863 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@tanstack/react-query-devtools": "^5.71.0", "@types/nodemailer": "^6.4.17", "axios": "^1.8.4", + "crypto-js": "^4.2.0", "env-cmd": "^10.1.0", "iron-session": "^8.0.4", "lucide": "^0.503.0", @@ -30,6 +31,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", + "@types/crypto-js": "^4.2.2", "@types/mysql": "^2.15.27", "@types/node": "^20", "@types/react": "^19", @@ -1946,6 +1948,13 @@ "integrity": "sha512-7qSgZbincDDDFyRweCIEvZULFAw5iz/DeunhvuxpL31nfntX3P4Yd4HkHBRg9H8CdqY1e5WFN1PZIz/REL9MVQ==", "license": "MIT" }, + "node_modules/@types/crypto-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz", + "integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mysql": { "version": "2.15.27", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", @@ -2396,6 +2405,12 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + }, "node_modules/css-line-break": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", diff --git a/package.json b/package.json index 5b0953b..0d54605 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@tanstack/react-query-devtools": "^5.71.0", "@types/nodemailer": "^6.4.17", "axios": "^1.8.4", + "crypto-js": "^4.2.0", "env-cmd": "^10.1.0", "iron-session": "^8.0.4", "lucide": "^0.503.0", @@ -37,6 +38,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", + "@types/crypto-js": "^4.2.2", "@types/mysql": "^2.15.27", "@types/node": "^20", "@types/react": "^19", diff --git a/src/components/pdf/SuitableDownloadPdf.tsx b/src/components/pdf/SuitableDownloadPdf.tsx index 60ffc07..901e6e2 100644 --- a/src/components/pdf/SuitableDownloadPdf.tsx +++ b/src/components/pdf/SuitableDownloadPdf.tsx @@ -1,12 +1,21 @@ 'use client' -import { useRef } from 'react' -import generatePDF, { Margin, Resolution } from 'react-to-pdf' +import { useEffect, useRef, useState } from 'react' +import generatePDF, { Margin, Options, Resolution, usePDF } from 'react-to-pdf' +import { useSuitable } from '@/hooks/useSuitable' +import { useSuitableStore } from '@/store/useSuitableStore' +import { SUITABLE_HEAD_CODE, type Suitable, type SuitableDetail } from '@/types/Suitable' export default function SuitableDownloadPdf() { + const [fileName, setFileName] = useState([]) + const [createTime, setCreateTime] = useState('') const targetRef = useRef(null) + const { toCodeName, toSuitableDetail, selectedSuitables, isSelectedSuitablesLoading } = useSuitable() + const { selectedCategory, suitableCommCode, selectedItemsSearching, setSelectedItemsSearching } = useSuitableStore() + const handleDownPdf = () => { - const options = { + const options: Options = { + filename: `${fileName.join('_')}.pdf`, method: 'open' as const, resolution: Resolution.HIGH, page: { @@ -31,14 +40,41 @@ export default function SuitableDownloadPdf() { generatePDF(targetRef, options) // generatePDF(targetRef, { filename: 'page.pdf' }) } + + const formatDateString = () => { + const now = new Date() + const year = now.getFullYear() + const month = now.getMonth() + 1 + const day = now.getDate() + const hours = now.getHours() + const minutes = now.getMinutes() + + return `${year}年${month}月${day}日 ${hours}:${minutes.toString().padStart(2, '0')}` + } + + useEffect(() => { + setCreateTime(formatDateString()) + setFileName([ + `(${suitableCommCode.get(SUITABLE_HEAD_CODE.ROOF_MATL_GRP_CD)?.find((category) => category.code === selectedCategory)?.codeJp})`, + '屋根材適合表', + ]) + if (!selectedItemsSearching) { + setSelectedItemsSearching(true) + } + }, []) + + if (!selectedCategory) return
잘못된 접근입니다.
+ if (isSelectedSuitablesLoading) return
Loading...
+ return ( <> + {/* */}
ハンファジャパン株式会社
-
(瓦) 屋根材適合表
-
2025年4月30日 10:40
+
{fileName.join(' ')}
+
{createTime}

本適合表は参考資料としてご使用下さい。

@@ -49,636 +85,43 @@ export default function SuitableDownloadPdf() {
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 + {selectedSuitables?.map((item: Suitable) => ( +
+
+ {item.productName} + {toCodeName(SUITABLE_HEAD_CODE.MANU_FT_CD, item.manuFtCd)} + {toCodeName(SUITABLE_HEAD_CODE.ROOF_MT_CD, item.roofMtCd)} +
+
+ + + + + + + + + + + + + + + + + {toSuitableDetail(item.detail).map((subItem: SuitableDetail) => ( + + + + + + + ))} + +
金具タイプ金具名設置可否備考
{toCodeName(SUITABLE_HEAD_CODE.ROOF_SH_CD, item.roofShCd)}{toCodeName(SUITABLE_HEAD_CODE.TRESTLE_MFPC_CD, subItem.trestleMfpcCd)}{subItem.trestleManufacturerProductName}{subItem.memo}
+
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
-
-
- 屋根材製品名 - メーカー名 - 屋根材の種類 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
金具タイプ金具名設置可否備考
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
木ねじ打ち込み式屋根技研支持瓦C で設置可支持瓦はアンダーラップの先端を削って納める(Try-U40はこの瓦の前身)
-
-
+ ))}
diff --git a/src/components/popup/SuitableDetailPopup.tsx b/src/components/popup/SuitableDetailPopup.tsx index 4baf4ec..31ad8ed 100644 --- a/src/components/popup/SuitableDetailPopup.tsx +++ b/src/components/popup/SuitableDetailPopup.tsx @@ -2,17 +2,18 @@ import Image from 'next/image' import { useCallback, useEffect, useState } from 'react' -import { usePopupController } from '@/store/popupController' import SuitableDetailPopupButton from './SuitableDetailPopupButton' import { useSuitable } from '@/hooks/useSuitable' +import { usePopupController } from '@/store/popupController' +import { useSuitableStore } from '@/store/useSuitableStore' import { SUITABLE_HEAD_CODE, type Suitable, type SuitableDetail } from '@/types/Suitable' export default function SuitableDetailPopup() { const popupController = usePopupController() - const { getSelectedItemsData, toCodeName, toSuitableDetail, suitableCheckIcon, suitableCheckMemo } = useSuitable() + const { toCodeName, toSuitableDetail, suitableCheckIcon, suitableCheckMemo, selectedSuitables, isSelectedSuitablesLoading } = useSuitable() + const { setSelectedItemsSearching } = useSuitableStore() const [openItems, setOpenItems] = useState>(new Set()) - const [suitableDetails, setSuitableDetails] = useState([]) // 아이템 열기/닫기 const toggleItemOpen = useCallback((itemId: number) => { @@ -24,8 +25,7 @@ export default function SuitableDetailPopup() { }, []) useEffect(() => { - // TODO: 로딩 처리 필요 - getSelectedItemsData().then((data) => setSuitableDetails(data)) + setSelectedItemsSearching(true) }, []) return ( @@ -45,56 +45,60 @@ export default function SuitableDetailPopup() {
- {suitableDetails.map((item: Suitable) => ( -
-
-
{item.productName}
-
- + {isSelectedSuitablesLoading ? ( +
Loading...
+ ) : ( + selectedSuitables?.map((item: Suitable) => ( +
+
+
{item.productName}
+
+ +
-
-
-
-
屋根技研 支持瓦
-
{toCodeName(SUITABLE_HEAD_CODE.MANU_FT_CD, item.manuFtCd)}
-
-
-
屋根材
-
{toCodeName(SUITABLE_HEAD_CODE.ROOF_MT_CD, item.roofMtCd)}
-
-
-
金具タイプ
-
{toCodeName(SUITABLE_HEAD_CODE.ROOF_SH_CD, item.roofShCd)}
-
-
- {toSuitableDetail(item.detail).map((subItem: SuitableDetail) => ( -
-
-
{toCodeName(SUITABLE_HEAD_CODE.TRESTLE_MFPC_CD, subItem.trestleMfpcCd)}
-
-
- -
- {subItem.memo && ( +
+
+
屋根技研 支持瓦
+
{toCodeName(SUITABLE_HEAD_CODE.MANU_FT_CD, item.manuFtCd)}
+
+
+
屋根材
+
{toCodeName(SUITABLE_HEAD_CODE.ROOF_MT_CD, item.roofMtCd)}
+
+
+
金具タイプ
+
{toCodeName(SUITABLE_HEAD_CODE.ROOF_SH_CD, item.roofShCd)}
+
+
+ {toSuitableDetail(item.detail).map((subItem: SuitableDetail) => ( +
+
+
{toCodeName(SUITABLE_HEAD_CODE.TRESTLE_MFPC_CD, subItem.trestleMfpcCd)}
+
- +
- )} + {subItem.memo && ( +
+ +
+ )} +
+
{suitableCheckMemo(subItem.trestleManufacturerProductName)}
+ {subItem.memo && ( +
+
備考
+
{subItem.memo}
+
+ )}
-
{suitableCheckMemo(subItem.trestleManufacturerProductName)}
- {subItem.memo && ( -
-
備考
-
{subItem.memo}
-
- )} -
- ))} + ))} +
-
- ))} + )) + )}
diff --git a/src/components/popup/SuitableDetailPopupButton.tsx b/src/components/popup/SuitableDetailPopupButton.tsx index 01f88ce..06725ec 100644 --- a/src/components/popup/SuitableDetailPopupButton.tsx +++ b/src/components/popup/SuitableDetailPopupButton.tsx @@ -7,26 +7,29 @@ export default function SuitableDetailPopupButton() { const popupController = usePopupController() const router = useRouter() + const handleClosePopup = () => { + popupController.setSuitableDetailPopup(false) + } + + const handleRedirectPage = (path: string) => { + handleClosePopup() + router.push(path) + } + return (
-
-
-
diff --git a/src/components/suitable/Suitable.tsx b/src/components/suitable/Suitable.tsx index 1fec8fc..e960de8 100644 --- a/src/components/suitable/Suitable.tsx +++ b/src/components/suitable/Suitable.tsx @@ -1,23 +1,13 @@ 'use client' import Image from 'next/image' -import { useEffect, useState } from 'react' +import { useState } from 'react' import SuitableList from './SuitableList' import SuitableSearch from './SuitableSearch' -import { useSuitable } from '@/hooks/useSuitable' export default function Suitable() { const [reference, setReference] = useState(true) - const { getSuitableCommCode, clearSuitableSearch } = useSuitable() - - useEffect(() => { - getSuitableCommCode() - return () => { - clearSuitableSearch({ items: true, category: true, keyword: true }) - } - }, []) - return (
diff --git a/src/components/suitable/SuitableButton.tsx b/src/components/suitable/SuitableButton.tsx index 9664f2c..110fc74 100644 --- a/src/components/suitable/SuitableButton.tsx +++ b/src/components/suitable/SuitableButton.tsx @@ -1,12 +1,14 @@ 'use client' +import { useRouter } from 'next/navigation' import { usePopupController } from '@/store/popupController' import { useSuitable } from '@/hooks/useSuitable' import { useSuitableStore } from '@/store/useSuitableStore' export default function SuitableButton() { const popupController = usePopupController() - const { getSuitableIds, clearSuitableSearch } = useSuitable() + const router = useRouter() + const { getSuitableIds, clearSuitableStore } = useSuitable() const { selectedItems, addAllSelectedItem } = useSuitableStore() const handleSelectAll = async () => { @@ -21,6 +23,14 @@ export default function SuitableButton() { popupController.setSuitableDetailPopup(true) } + const handleRedirectPdfDownload = () => { + if (selectedItems.size === 0) { + alert('屋根材を選択してください。') + return + } + router.push('/pdf/suitable') + } + return (
@@ -30,7 +40,7 @@ export default function SuitableButton() { 全選択 ) : ( - )} @@ -41,7 +51,7 @@ export default function SuitableButton() {
-
diff --git a/src/components/suitable/SuitableList.tsx b/src/components/suitable/SuitableList.tsx index 7aaeb5e..9db030d 100644 --- a/src/components/suitable/SuitableList.tsx +++ b/src/components/suitable/SuitableList.tsx @@ -20,7 +20,7 @@ export default function SuitableList() { isLoading, suitableCheckIcon, } = useSuitable() - const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore() + const { selectedItems, addSelectedItem, removeSelectedItem, setSelectedItemsSearching } = useSuitableStore() const [openItems, setOpenItems] = useState>(new Set()) const observerTarget = useRef(null) @@ -48,6 +48,7 @@ export default function SuitableList() { // 아이템 클릭 const handleItemClick = useCallback( (mainId: number, detailId?: number, detailIds?: Set): void => { + setSelectedItemsSearching(false) isItemSelected(mainId, detailId) ? removeSelectedItem(mainId, detailId) : addSelectedItem(mainId, detailId, detailIds) }, [isItemSelected, addSelectedItem, removeSelectedItem], diff --git a/src/components/suitable/SuitableSearch.tsx b/src/components/suitable/SuitableSearch.tsx index 8b4a883..ccc6aed 100644 --- a/src/components/suitable/SuitableSearch.tsx +++ b/src/components/suitable/SuitableSearch.tsx @@ -9,7 +9,7 @@ import { SUITABLE_HEAD_CODE } from '@/types/Suitable' export default function SuitableSearch() { const [searchValue, setSearchValue] = useState('') - const { getSuitableCommCode, clearSuitableSearch } = useSuitable() + const { getSuitableCommCode, clearSuitableStore } = useSuitable() const { suitableCommCode, selectedCategory, setSelectedCategory, setSearchKeyword } = useSuitableStore() const handleInputChange = (value: string) => { @@ -31,14 +31,12 @@ export default function SuitableSearch() { const handleInputClear = () => { setSearchValue('') - clearSuitableSearch({ items: true, keyword: true }) + clearSuitableStore({ items: true, keyword: true }) } useEffect(() => { + clearSuitableStore({ items: true, category: true, keyword: true }) getSuitableCommCode() - return () => { - clearSuitableSearch({ items: true, category: true, keyword: true }) - } }, []) return ( @@ -46,7 +44,7 @@ export default function SuitableSearch() {