[251019] feat: TItemCard.new.jsx version control

🕐 커밋 시간: 2025. 10. 19. 11:55:43

📊 변경 통계:
  • 총 파일: 1개
  • 추가: +47줄
  • 삭제: -52줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/components/TItemCard/TItemCard.new.jsx

🔧 함수 변경 내용:
  📄 com.twin.app.shoptime/src/components/TItemCard/TItemCard.new.jsx (javascript):
     Added: parsePrice(), generateMockEnergyLabels(), hashCode()
     Deleted: hashCode()

🔧 주요 변경 내용:
  • UI 컴포넌트 아키텍처 개선

Performance: 코드 최적화로 성능 개선 기대
This commit is contained in:
2025-10-19 11:55:43 +09:00
parent cf3bc87230
commit 40df2c042e

View File

@@ -51,6 +51,13 @@ const STRING_CONF = {
ENERGY_ERROR: 'Failed to load energy label',
};
const ENERGY_LABEL_MODE = {
API_ONLY: 'API_ONLY',
WITH_MOCK: 'WITH_MOCK',
};
const CURRENT_ENERGY_LABEL_MODE = ENERGY_LABEL_MODE.WITH_MOCK;
export const removeDotAndColon = (string) => {
return /[.:]/.test(string) ? string.replace(/[.:]/g, '') : string;
};
@@ -59,6 +66,30 @@ const parsePrice = (price) => {
return parseFloat(price?.replace(/[^0-9.-]+/g, '') || '0');
};
const generateMockEnergyLabels = (productId) => {
const hashCode = (str) => {
let hash = 0;
const s = String(str);
for (let i = 0; i < s.length; i++) {
hash = (hash << 5) - hash + s.charCodeAt(i);
hash = hash & hash;
}
return Math.abs(hash);
};
const seed = productId ? hashCode(productId) : Math.floor(Math.random() * 1000);
const randomCount = (seed % 3) + 1;
const testIcons = [testEnergyIconA, testEnergyIconB, testEnergyIconC];
const testGrades = ['A (TEST)', 'B (TEST)', 'C (TEST)'];
return Array.from({ length: randomCount }, (_, index) => ({
enrgLblUrl: testEnergyPdf,
enrgLblIcnUrl: testIcons[index],
enrgGrade: testGrades[index],
}));
};
export default memo(function TItemCardNew({
children,
className,
@@ -420,41 +451,29 @@ export default memo(function TItemCardNew({
</p>
)}
</div>
{/* 🧪 테스트: 모든 상품에 [EnergyLabel] 표시 (test.pdf 변환 확인용) */}
{/* ✅ 실제 운영: 아래 주석 삭제하고 원래 조건문으로 복구 */}
{(() => {
const hasValidApiData =
euEnrgLblInfos?.length > 0 &&
euEnrgLblInfos[0]?.enrgLblIcnUrl !== null &&
euEnrgLblInfos[0]?.enrgLblIcnUrl !== undefined;
let energyLabels;
// 실제 API 데이터가 있으면 사용
if (euEnrgLblInfos?.length > 0 && euEnrgLblInfos[0]?.enrgLblIcnUrl !== null) {
if (CURRENT_ENERGY_LABEL_MODE === ENERGY_LABEL_MODE.API_ONLY) {
if (!hasValidApiData) {
return null;
}
energyLabels = euEnrgLblInfos;
} else if (CURRENT_ENERGY_LABEL_MODE === ENERGY_LABEL_MODE.WITH_MOCK) {
if (hasValidApiData) {
energyLabels = euEnrgLblInfos;
} else {
energyLabels = generateMockEnergyLabels(productId);
}
} else {
// 🧪 테스트: 랜덤으로 1~3개 생성
// productId 전체를 해시해서 균등한 분산 (같은 상품은 항상 같은 개수)
const hashCode = (str) => {
let hash = 0;
const s = String(str);
for (let i = 0; i < s.length; i++) {
hash = (hash << 5) - hash + s.charCodeAt(i);
hash = hash & hash; // Convert to 32bit integer
}
return Math.abs(hash);
};
const seed = productId ? hashCode(productId) : Math.floor(Math.random() * 1000);
const randomCount = (seed % 3) + 1; // 1, 2, 3 중 하나
const testIcons = [testEnergyIconA, testEnergyIconB, testEnergyIconC];
const testGrades = ['A (TEST)', 'B (TEST)', 'C (TEST)'];
energyLabels = Array.from({ length: randomCount }, (_, index) => ({
enrgLblUrl: testEnergyPdf,
enrgLblIcnUrl: testIcons[index],
enrgGrade: testGrades[index],
}));
return null;
}
// 하나의 labelImgBox 안에 모든 라벨 배치 (세로로 쌓임)
return (
<div className={css.labelImgBox}>
{energyLabels
@@ -476,30 +495,6 @@ export default memo(function TItemCardNew({
</div>
);
})()}
{/*
원래 코드 (테스트 완료 후 복구):
{euEnrgLblInfos &&
euEnrgLblInfos.length > 0 &&
euEnrgLblInfos[0]?.enrgLblIcnUrl !== null &&
euEnrgLblInfos.map(
(info, index) =>
index < 3 && (
<div key={index} className={css.labelImgBox}>
<SpottableTemp
spotlightDisabled={Boolean(!cursorVisible)}
onClick={(e) => onEnergyClick(e, info.enrgLblUrl)}
aria-label={`Energy Efficiency ${info.enrgGrade || ""}`}
>
<CustomImage
alt={`Energy Label ${info.enrgGrade || index + 1}`}
delay={0}
src={info.enrgLblIcnUrl}
/>
</SpottableTemp>
</div>
)
)}
*/}
</div>
{isBestSeller && rank && (
<div className={css.bestSeller}>