diff --git a/frontend/src/app/cars/[id]/page.tsx b/frontend/src/app/cars/[id]/page.tsx index b7d7ccd..0ec7ab8 100644 --- a/frontend/src/app/cars/[id]/page.tsx +++ b/frontend/src/app/cars/[id]/page.tsx @@ -336,14 +336,14 @@ export default function CarDetailPage() { const lockedImagesCount = (showAllImages || checkingAccess || isBannerCar === null) ? 0 : Math.max(0, STANDARD_PHOTO_COUNT - displayImages.length); return ( -
-
+
+
{/* Back Button */}
)} -
+
{/* Images */}
{/* Main Image */} -
+
{displayImages.length > 0 ? ( - + {language === 'ko' ? '판매완료' : 'SOLD OUT'}
@@ -536,12 +536,12 @@ export default function CarDetailPage() { {/* Details */}
-
-

+
+

{translate(car.car_name) || `${translate(car.maker?.name) || ''} ${translate(car.model?.name) || ''}`.trim() || '-'}

{car.soldout && ( - + {language === 'ko' ? '판매완료' : 'SOLD OUT'} )} @@ -550,22 +550,22 @@ export default function CarDetailPage() { {(() => { const price = formatPrice(car.final_price_krw || car.price_krw); return ( -
-

+

+

{price.usdt !== '-' ? price.usdt : t.contactForPrice}

{/* Show local currency for all languages */} {price.local !== '-' && ( -

({price.local})

+

({price.local})

)}
); })()} {/* Specs Grid */} -
-

{t.specifications}

-
+
+

{t.specifications}

+
{t.year}

{car.year || '-'}{car.month ? ` / ${car.month}` : ''}

@@ -602,8 +602,8 @@ export default function CarDetailPage() {
{/* Status - Only show full details if purchased */} -
-

{t.vehicleStatus}

+
+

{t.vehicleStatus}

{hasAccess ? (
@@ -637,9 +637,9 @@ export default function CarDetailPage() { {/* Performance Check Section */} {performanceCheck?.found && ( -
-

- +
+

+ {t.performanceCheck || 'Performance Check Report'} diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 58fd78e..b65ee52 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -33,11 +33,11 @@ export default function Home() {
{/* Hero Section with Film Strip Slider */}
-
-

+
+

{t.premiumKoreanUsedCars}

-

+

{t.qualityVehiclesExported}

@@ -45,10 +45,10 @@ export default function Home() { {/* Film Strip Slider */} -
+
{t.requestVehicle} @@ -56,58 +56,58 @@ export default function Home() {

{/* Features */} -
+
-

{t.whyChooseUs}

-
-
-
- +

{t.whyChooseUs}

+
+
+
+
-

{t.qualityAssured}

-

{t.qualityAssuredDesc}

+

{t.qualityAssured}

+

{t.qualityAssuredDesc}

-
-
- +
+
+
-

{t.bestPrices}

-

{t.bestPricesDesc}

+

{t.bestPrices}

+

{t.bestPricesDesc}

-
-
- +
+
+
-

{t.fullSupport}

-

{t.fullSupportDesc}

+

{t.fullSupport}

+

{t.fullSupportDesc}

{/* CTA */} -
+
-

{t.readyToFindYourCar}

-

+

{t.readyToFindYourCar}

+

{t.browseOurCollection}

-
+
{t.browseCars} {t.contactUs} diff --git a/frontend/src/components/FilmStripSlider.tsx b/frontend/src/components/FilmStripSlider.tsx index f37df14..26adbe4 100644 --- a/frontend/src/components/FilmStripSlider.tsx +++ b/frontend/src/components/FilmStripSlider.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useState, useRef } from 'react'; +import { useEffect, useState, useRef, useCallback } from 'react'; import { motion, useAnimationControls } from 'framer-motion'; import Image from 'next/image'; import Link from 'next/link'; @@ -22,6 +22,39 @@ const defaultSettings: HeroBannerSettings = { auto_play: true, }; +// 반응형 이미지 크기 계산 +const useResponsiveImageSize = (baseWidth: number, baseHeight: number) => { + const [dimensions, setDimensions] = useState({ width: baseWidth, height: baseHeight }); + + useEffect(() => { + const updateDimensions = () => { + const screenWidth = window.innerWidth; + if (screenWidth < 480) { + // Extra small mobile + setDimensions({ width: 200, height: 130 }); + } else if (screenWidth < 640) { + // Mobile + setDimensions({ width: 260, height: 170 }); + } else if (screenWidth < 768) { + // Tablet + setDimensions({ width: 320, height: 200 }); + } else if (screenWidth < 1024) { + // Small desktop + setDimensions({ width: 400, height: 250 }); + } else { + // Large desktop + setDimensions({ width: baseWidth, height: baseHeight }); + } + }; + + updateDimensions(); + window.addEventListener('resize', updateDimensions); + return () => window.removeEventListener('resize', updateDimensions); + }, [baseWidth, baseHeight]); + + return dimensions; +}; + // 샘플 배너 데이터 (API 데이터가 없을 때 사용) const sampleBanners: HeroBanner[] = [ { @@ -104,9 +137,12 @@ export default function FilmStripSlider({ banners, settings }: FilmStripSliderPr const currentXRef = useRef(0); const animationStartTimeRef = useRef(0); - const imageWidth = effectiveSettings.image_width; - const imageHeight = effectiveSettings.image_height; - const gap = 16; // gap between images + // 반응형 이미지 크기 사용 + const { width: imageWidth, height: imageHeight } = useResponsiveImageSize( + effectiveSettings.image_width, + effectiveSettings.image_height + ); + const gap = 12; // gap between images (smaller on mobile) const singleSetWidth = (imageWidth + gap) * effectiveBanners.length; const totalDuration = effectiveBanners.length * (effectiveSettings.slide_interval / 1000); @@ -250,11 +286,11 @@ export default function FilmStripSlider({ banners, settings }: FilmStripSliderPr }; return ( -
- {/* Film strip effect - top perforation */} -
+
+ {/* Film strip effect - top perforation (hidden on very small screens) */} +
{Array.from({ length: 30 }).map((_, i) => ( -
+
))}
@@ -262,14 +298,16 @@ export default function FilmStripSlider({ banners, settings }: FilmStripSliderPr
{duplicatedBanners.map((banner, index) => (
- {/* Film strip effect - bottom perforation */} -
+ {/* Film strip effect - bottom perforation (hidden on very small screens) */} +
{Array.from({ length: 30 }).map((_, i) => ( -
+
))}
{/* Gradient overlays for fade effect at edges */} -
-
+
+
- {/* Navigation Arrows */} + {/* Navigation Arrows - smaller on mobile */} diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index 3e061db..d4acb8c 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -217,10 +217,10 @@ export default function Header() { {/* Right side: Notifications + Language + Auth */} -
- {/* Notification Bell */} +
+ {/* Notification Bell - hidden on very small screens */} {user && ( -
+
@@ -345,25 +347,26 @@ export default function Header() { <> {t.login} {t.register} )} - {/* Mobile menu button */} + {/* Mobile menu button - always visible on mobile */} +
+ ) : ( +
+ setMobileMenuOpen(false)} + > + {t.login} + + setMobileMenuOpen(false)} + > + {t.register} + +
+ )} +
)}