# DetailPanel - Theme Product vs Hotel Product 비ꡐ 뢄석 ## πŸ“Š 전체 κ°œμš” | ꡬ뢄 | Theme Product (μ‡Ό/곡연) | Hotel Product (μˆ™λ°•) | |------|------------------------|----------------------| | **데이터 μ†ŒμŠ€** | `themeCurationDetailInfoData[]` | `themeCurationHotelDetailData[]` | | **메인 μ»΄ν¬λ„ŒνŠΈ** | ShowProduct | HotelProduct | | **νŒ¨λ„ νƒ€μž…** | `panelInfo.type === "theme"` | `panelInfo.type === "hotel"` | | **μ„œλ²„ API** | getThemeCurationDetailInfo | getThemeHotelDetailInfo | | **Redux μ•‘μ…˜** | GET_THEME_CURATION_DETAIL_INFO | GET_THEME_HOTEL_DETAIL_INFO | --- ## 🎯 핡심 차이점 ### 1. 데이터 ꡬ쑰 #### Theme Product ```javascript themeCurationDetailInfoData: [ { prdtId, prdtNm, // μƒν’ˆ ID, 이름 imgUrls600: [], // 이미지 λ°°μ—΄ priceInfo: "299|199|Y|...", // 가격 정보 (νŒŒμ΄ν”„ ꡬ뢄) prdtMediaUrl, // λΉ„λ””μ˜€ URL showId, showNm, // μ‡Ό 정보 catCd, catNm, // μΉ΄ν…Œκ³ λ¦¬ soldoutFlag, // λ§€μ§„ μ—¬λΆ€ pmtSuptYn, // 결제 지원 revwGrd, // 평점 } ] ``` #### Hotel Product ```javascript themeCurationHotelDetailData: [ { hotelId, hotelNm, // ν˜Έν…” ID, 이름 hotelImgUrl, // ν˜Έν…” 썸넀일 imgUrls600: [], // 이미지 λ°°μ—΄ qrcodeUrl, // QR μ½”λ“œ hotelDetailInfo: { price, // 가격 (λ‹¨μˆœ 숫자) currencySign, // 톡화 기호 revwGrd, // 평점 hotelType, // ν˜Έν…” νƒ€μž… hotelAddr, // μ£Όμ†Œ nights, adultsCount, // μˆ™λ°•μΌ, 성인 수 roomType, // λ°© νƒ€μž… amenities: [], // νŽΈμ˜μ‹œμ„€ ID λ°°μ—΄ imgUrls: [] // 이미지 } } ] hotelData: { hotelInfo: { curationId, curationNm, ... }, amenities: [ { amntId, lgAmntNm, lgAmntImgUrl }, // ... ] } ``` --- ### 2. UI ꡬ쑰 #### Theme Product ``` ShowProduct β”œβ”€ ThemeIndicator β”‚ β”œβ”€ [메인 이미지] λ˜λŠ” [λΉ„λ””μ˜€] β”‚ └─ [썸넀일 슀크둀] β”œβ”€ IndicatorOptions β”‚ β”œβ”€ [μ„€λͺ…] [κ΅ν™˜μ •μ±…] [SMS] β”‚ └─ QR μ½”λ“œ └─ ShowSingleOption / ShowUnableOption └─ ꡬ맀 μ˜΅μ…˜ λ˜λŠ” κ΅¬λ§€λΆˆκ°€ λ©”μ‹œμ§€ ``` #### Hotel Product ``` HotelProduct β”œβ”€ ThemeIndicator β”‚ β”œβ”€ [메인 이미지] β”‚ └─ [썸넀일 슀크둀] β”œβ”€ IndicatorOptions β”‚ └─ [μ£Όμ†Œ 정보] └─ optionContainer β”œβ”€ [둜고 + 별점] β”œβ”€ [ν˜Έν…”λͺ… + νƒ€μž…] β”œβ”€ [νŽΈμ˜μ‹œμ„€ κ·Έλ¦¬λ“œ] (μ΅œλŒ€ 10개) β”œβ”€ [μ˜ˆμ•½μ •λ³΄ + 가격 + QR] └─ [SEE MORE] λ²„νŠΌ ``` --- ### 3. 가격 처리 #### Theme Product ```javascript // priceInfo = "299|199|Y|discount10|10%" const befPrice = priceInfo.split("|")[0]; // 원가 const lastPrice = priceInfo.split("|")[1]; // 할인가 const rewdAplyFlag = priceInfo.split("|")[2]; // 보상 적용 const discountRate = priceInfo.split("|")[4]; // ν• μΈμœ¨ // 둜그 전솑 params.befPrice = befPrice; params.lastPrice = lastPrice; ``` #### Hotel Product ```javascript // price = "299.99" (λ‹¨μˆœ 숫자) // currencySign = "$" // UI ν‘œμ‹œ
{hotelInfos[selectedIndex]?.hotelDetailInfo.currencySign} {hotelInfos[selectedIndex]?.hotelDetailInfo.price}
// 둜그 전솑 params.price = selectedHotelInfo.hotelInfo?.hotelDetailInfo?.price; ``` --- ### 4. 특수 κΈ°λŠ₯ #### Theme Product βœ… **λΉ„λ””μ˜€ μžλ™ μž¬μƒ** - `prdtMediaUrl` 쑴재 μ‹œ 첫 이미지 μœ„μΉ˜μ— λΉ„λ””μ˜€ - `launchedFromPlayer = false`일 λ•Œλ§Œ μžλ™ μž¬μƒ - λΉ„λ””μ˜€ μžλ§‰ 지원 (`prdtMediaSubtitlUrl`) βœ… **상세 정보 νŒμ—…** - [DESCRIPTION] λ²„νŠΌ: μƒν’ˆ μ„€λͺ… - [RETURNS & EXCHANGES] λ²„νŠΌ: λ°˜ν’ˆ/κ΅ν™˜ μ •μ±… - HTML λ§ˆν¬μ—… 지원 (`dangerouslySetInnerHTML`) βœ… **결제 μ˜΅μ…˜ 선택** - μ˜΅μ…˜ 선택 (이용일자, μ’Œμ„ λ“±) - μˆ˜λŸ‰ 선택 - μ˜΅μ…˜λ³„ 가격 계산 ❌ **νŽΈμ˜μ‹œμ„€ ν‘œμ‹œ μ—†μŒ** --- #### Hotel Product βœ… **νŽΈμ˜μ‹œμ„€ κ·Έλ¦¬λ“œ ν‘œμ‹œ** - μ΅œλŒ€ 10개 νŽΈμ˜μ‹œμ„€ μ•„μ΄μ½˜ + ν…μŠ€νŠΈ - 같은 μΉ΄ν…Œκ³ λ¦¬ 쀑볡 제거 - νŽΈμ˜μ‹œμ„€λ³„ 이미지 및 μ„€λͺ… βœ… **μ˜ˆμ•½ 정보 ν‘œμ‹œ** - μˆ™λ°• κΈ°κ°„ (nights) - 성인 수 (adultsCount) - λ°© νƒ€μž… (roomType) - μžλ™ ν¬λ§·νŒ… (예: "2 Nights 2 Adults") βœ… **별점 λ“±κΈ‰ μ‹œμŠ€ν…œ** - 평점 수치 β†’ 문자 λ“±κΈ‰ λ³€ν™˜ - Fair (≀2.4) / Good (2.5~3.4) / Very Good (3.5~4.4) / Excellent (β‰₯4.5) ❌ **λΉ„λ””μ˜€ 지원 μ—†μŒ** ❌ **μ˜΅μ…˜ 선택 μ—†μŒ** (μˆ™λ°• μ •λ³΄λŠ” 미리 정해짐) --- ### 5. 결제 μ—¬λΆ€ νŒλ‹¨ #### 곡톡점 ```javascript // 결제 OS 버전 체크 webOSVersion >= "6.0" // TRUE일 λ•Œλ§Œ 결제 UI ν‘œμ‹œ ``` #### Theme Product ```javascript const isBillingProductVisible = ( productInfo[selectedIndex]?.pmtSuptYn === "Y" && webOSVersion >= "6.0" ); // YES β†’ ShowSingleOption (ꡬ맀 μ˜΅μ…˜) // NO β†’ ShowUnableOption (κ΅¬λ§€λΆˆκ°€) ``` #### Hotel Product ```javascript // ν˜Έν…”μ€ pmtSuptYn 체크 μ—†μŒ (λͺ¨λ‘ κ΅¬λ§€λΆˆκ°€) // SMS "SEE MORE" λ²„νŠΌλ§Œ 제곡 // λͺ¨λ“  ν˜Έν…” μƒν’ˆμ΄ UnableOption ꡬ쑰 ``` --- ### 6. SMS νƒ€μž… μ½”λ“œ #### Theme Product ```javascript smsTpCd = "APP00204" // ν…Œλ§ˆ/μ‡Ό μƒν’ˆ ``` #### Hotel Product ```javascript smsTpCd = "APP00205" // ν˜Έν…” μƒν’ˆ ``` --- ### 7. 둜그 ν•„λ“œ #### 곡톡 ν•„λ“œ ```javascript { curationId, curationNm, // ν…Œλ§ˆ/νλ ˆμ΄μ…˜ patnrId, patncNm, // νŒŒνŠΈλ„ˆ prdtId, prdtNm, // μƒν’ˆ ID, 이름 revwGrd, // 평점 expsOrd, // μƒν’ˆ 순번 } ``` #### Theme Product μΆ”κ°€ ν•„λ“œ ```javascript { showId, showNm, // μ‡Ό 정보 catCd, catNm, // μΉ΄ν…Œκ³ λ¦¬ befPrice, lastPrice, // 원가, 할인가 rewdAplyFlag, // 보상 적용 tsvFlag, // 였늘의 νŠΉκ°€ shopTpNm: "product", // μƒν’ˆ νƒ€μž… } ``` #### Hotel Product μΆ”κ°€ ν•„λ“œ ```javascript { hotelId, // ν˜Έν…” ID (prdtId λŒ€μ²΄) price, // 가격 (λ‹¨μˆœ) shopTpNm: "hotel", // μƒν’ˆ νƒ€μž… } ``` --- ### 8. 선택 인덱슀 처리 #### Theme Product ```javascript // URL νŒŒλΌλ―Έν„°λ‘œ νŠΉμ • μƒν’ˆ μ§€μ • if (panelInfo?.themePrdtId) { for (let i = 0; i < themeProductInfos.length; i++) { if (themeProductInfos[i].prdtId === panelInfo?.themePrdtId) { setSelectedIndex(i); // ← ν•΄λ‹Ή μƒν’ˆμœΌλ‘œ 이동 } } } ``` #### Hotel Product ```javascript // URL νŒŒλΌλ―Έν„°λ‘œ νŠΉμ • ν˜Έν…” μ§€μ • if (panelInfo?.themeHotelId) { for (let i = 0; i < hotelInfos.length; i++) { if (hotelInfos[i].hotelId === panelInfo?.themeHotelId) { setSelectedIndex(i); // ← ν•΄λ‹Ή ν˜Έν…”λ‘œ 이동 } } } ``` --- ## πŸ“ λ ˆμ΄μ•„μ›ƒ 비ꡐ ### Theme Product | μš”μ†Œ | 크기 | |------|------| | ThemeIndicator | 834Γ—930px | | 메인 이미지 | 600Γ—600px | | 썸넀일 | 150Γ—150px (반볡) | | QR μ½”λ“œ | 160Γ—160px | ### Hotel Product | μš”μ†Œ | 크기 | |------|------| | ThemeIndicator | 774Γ—930px | | 메인 이미지 | 600Γ—600px | | optionContainer | 1026Γ—990px | | νŽΈμ˜μ‹œμ„€ λ°•μŠ€ | 138Γ—138px (반볡, μ΅œλŒ€ 10개) | | QR μ½”λ“œ | 160Γ—160px | --- ## πŸ”„ μ»΄ν¬λ„ŒνŠΈ μž¬μ‚¬μš© ### 곡유 μ»΄ν¬λ„ŒνŠΈ ``` ThemeIndicator β”œβ”€ Theme Productμ—μ„œ μ‚¬μš© └─ Hotel Productμ—μ„œλ„ μ‚¬μš© (λΉ„λ””μ˜€ μž¬μƒμ€ X) IndicatorOptions β”œβ”€ Theme Productμ—μ„œ μ‚¬μš© └─ Hotel Productμ—μ„œλ„ μ‚¬μš© (μ£Όμ†Œ μ •λ³΄λ§Œ ν‘œμ‹œ) StarRating β”œβ”€ Theme Productμ—μ„œ μ‚¬μš© └─ Hotel Productμ—μ„œλ„ μ‚¬μš© ``` ### μ „μš© μ»΄ν¬λ„ŒνŠΈ ``` Theme Product: β”œβ”€ ShowProduct.jsx β”œβ”€ ShowSingleOption.jsx β”œβ”€ ShowUnableOption.jsx └─ SingleOption / UnableOption (κΈ°μ‘΄) Hotel Product: β”œβ”€ HotelProduct.jsx └─ StarRating (ν˜Έν…” λ“±κΈ‰μš©) ``` --- ## πŸ“Š 정리 ν…Œμ΄λΈ” | κΈ°λŠ₯ | Theme | Hotel | |------|-------|-------| | **λΉ„λ””μ˜€ 지원** | βœ… | ❌ | | **μžλ™ μž¬μƒ** | βœ… | ❌ | | **νŽΈμ˜μ‹œμ„€ ν‘œμ‹œ** | ❌ | βœ… (μ΅œλŒ€ 10개) | | **μ˜ˆμ•½ 정보** | ❌ | βœ… (μˆ™λ°•μΌ, 성인 수) | | **λ“±κΈ‰ λ³€ν™˜** | ❌ | βœ… (Fair/Good/Very Good/Excellent) | | **μ˜΅μ…˜ 선택** | βœ… | ❌ | | **μˆ˜λŸ‰ 선택** | βœ… | ❌ | | **결제 κ°€λŠ₯** | 쑰건뢀 (pmtSuptYn) | ❌ (항상 λΆˆκ°€) | | **상세 νŒμ—…** | βœ… (μ„€λͺ…/κ΅ν™˜) | ❌ | | **가격 ν˜•μ‹** | `"299\|199\|Y\|..."` | `"299.99"` | | **톡화 기호** | λ―Έμ‚¬μš© | βœ… (`$`, `€`, `Β₯` λ“±) | | **SMS νƒ€μž…** | APP00204 | APP00205 | | **QR μ½”λ“œ** | βœ… | βœ… | | **둜그 좔적** | 상세 (가격, ν• μΈμœ¨) | κΈ°λ³Έ (κ°€κ²©λ§Œ) | --- ## 🎯 μ‚¬μš© μ‹œλ‚˜λ¦¬μ˜€ ### Theme Product μ‚¬μš© 예 ``` μ‚¬μš©μžκ°€ "였페라 곡연" 클릭 ↓ DetailPanel λ‘œλ“œ (type: "theme") ↓ ShowProduct λ Œλ”λ§ ↓ 곡연 λΉ„λ””μ˜€ μžλ™ μž¬μƒ ↓ μ‚¬μš©μžκ°€ μ„€λͺ… λ²„νŠΌ 클릭 ↓ μƒν’ˆ μ„€λͺ… νŒμ—… ν‘œμ‹œ ↓ μ‚¬μš©μžκ°€ SMS λ²„νŠΌ 클릭 ↓ μΉœκ΅¬μ—κ²Œ 곡연 정보 전솑 ``` ### Hotel Product μ‚¬μš© 예 ``` μ‚¬μš©μžκ°€ "두바이 ν˜Έν…”" 클릭 ↓ DetailPanel λ‘œλ“œ (type: "hotel") ↓ HotelProduct λ Œλ”λ§ ↓ ν˜Έν…” 사진, νŽΈμ˜μ‹œμ„€, 가격 ν‘œμ‹œ ↓ μ‚¬μš©μžκ°€ ν™”μ‚΄ν‘œλ‘œ λ‹€λ₯Έ ν˜Έν…” 선택 ↓ 별점/νŽΈμ˜μ‹œμ„€/가격 μ—…λ°μ΄νŠΈ ↓ μ‚¬μš©μžκ°€ SEE MORE λ²„νŠΌ 클릭 ↓ ν˜Έν…” 상세 정보 SMS 전솑 ``` --- ## πŸ’‘ 개발 κ°€μ΄λ“œ ### μƒˆλ‘œμš΄ μƒν’ˆ νƒ€μž… μΆ”κ°€ μ‹œ 1. **DetailPanel에 λΆ„κΈ° μΆ”κ°€** ```javascript if (panelInfo?.type === "newtype") { dispatch(getNewTypeDetailInfo(...)); } ``` 2. **Redux Action/Reducer 생성** ```javascript GET_NEWTYPE_DETAIL_INFO action μΆ”κ°€ state.home.newTypeData μƒνƒœ μΆ”κ°€ ``` 3. **메인 μ»΄ν¬λ„ŒνŠΈ 생성** (ShowProduct/HotelProduct μ°Έκ³ ) - ThemeIndicator μž¬μ‚¬μš© (λ˜λŠ” μ»€μŠ€ν„°λ§ˆμ΄μ§•) - IndicatorOptions μž¬μ‚¬μš© (λ˜λŠ” μ»€μŠ€ν„°λ§ˆμ΄μ§•) - μ„ΈλΆ€ UI μ»΄ν¬λ„ŒνŠΈ μž‘μ„± 4. **ThemeProduct에 λΌμš°νŒ… μΆ”κ°€** ```javascript {themeType === "newtype" && ( )} ``` --- ## πŸ”— κ΄€λ ¨ 파일 ꡬ쑰 ``` src/views/DetailPanel/ β”œβ”€ DetailPanel.jsx / DetailPanel.backup.jsx β”œβ”€ ThemeProduct/ β”‚ β”œβ”€ ThemeProduct.jsx (λΌμš°νŒ…) β”‚ β”œβ”€ ShowProduct.jsx (ν…Œλ§ˆ μƒν’ˆ) β”‚ β”œβ”€ HotelProduct.jsx (ν˜Έν…” μƒν’ˆ) β”‚ β”œβ”€ ShowOptions/ β”‚ β”‚ β”œβ”€ ShowSingleOption.jsx β”‚ β”‚ └─ ShowUnableOption.jsx β”‚ └─ *.module.less β”œβ”€ components/ β”‚ β”œβ”€ ProductOption.jsx (래퍼) β”‚ β”œβ”€ indicator/ β”‚ β”‚ β”œβ”€ ThemeIndicator.jsx (곡유) β”‚ β”‚ β”œβ”€ IndicatorOptions.jsx (곡유) β”‚ β”‚ └─ *.module.less β”‚ β”œβ”€ StarRating.jsx (곡유) β”‚ └─ ... β”œβ”€ SingleProduct/ β”‚ └─ SingleOption.jsx (ν…Œλ§ˆμš©) β”œβ”€ UnableProduct/ β”‚ └─ UnableOption.jsx (ν…Œλ§ˆμš©) └─ ... src/actions/ β”œβ”€ homeActions.js β”‚ β”œβ”€ getThemeCurationDetailInfo() β”‚ └─ getThemeHotelDetailInfo() └─ ... src/reducers/ └─ homeReducer.js β”œβ”€ GET_THEME_CURATION_DETAIL_INFO case └─ GET_THEME_HOTEL_DETAIL_INFO case ``` --- ## βœ… μ΅œμ’… 체크리슀트 ### Theme Product - βœ… λΉ„λ””μ˜€ μžλ™ μž¬μƒ (쑰건뢀) - βœ… 상세 정보 νŒμ—… (μ„€λͺ…/κ΅ν™˜) - βœ… μ˜΅μ…˜ 선택 (λ‚ μ§œ/μ’Œμ„) - βœ… μˆ˜λŸ‰ 선택 - βœ… 가격 ν• μΈμœ¨ ν‘œμ‹œ - βœ… 결제 κ°€λŠ₯ μ—¬λΆ€ νŒλ‹¨ - βœ… SMS 곡유 (λͺ¨λ“  μƒν’ˆ) - βœ… 상세 λ‘œκΉ… ### Hotel Product - βœ… ν˜Έν…” 이미지 가러리 - βœ… νŽΈμ˜μ‹œμ„€ κ·Έλ¦¬λ“œ (μ΅œλŒ€ 10개) - βœ… 별점 λ“±κΈ‰ λ³€ν™˜ - βœ… μ˜ˆμ•½ 정보 ν‘œμ‹œ (μˆ™λ°•μΌ, 성인 수) - βœ… 가격 + 톡화 기호 - βœ… μ£Όμ†Œ 정보 - βœ… QR μ½”λ“œ - βœ… SMS 곡유 (SEE MORE) - βœ… λ‘œκΉ… --- 이 λ¬Έμ„œλ₯Ό 톡해 Theme Product와 Hotel Product의 차이점을 λͺ…ν™•νžˆ 이해할 수 있으며, ν–₯ν›„ μœ μ‚¬ν•œ μƒν’ˆ νƒ€μž… μΆ”κ°€ μ‹œ μ°Έκ³ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.