x
This commit is contained in:
1 parent
0ceee3dbff
commit
2d39edbd57
18 files changed
+804
-153
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getCategoryImage, type Category, type CategoriesSectionPayload } from '@homaroma/types';
|
||||
import { getCategoryImage, resolveCategoryMediaUrl, type Category, type CategoriesSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function DynamicCategories({ payload, categories, loading }: Dyna
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-pop-bg/90 via-pop-bg/40 to-transparent z-10 opacity-80 group-hover:opacity-100 transition-opacity" />
|
||||
<img
|
||||
src={cat.imageUrl || getCategoryImage(getLocalizedField(cat.name, lang))}
|
||||
src={resolveCategoryMediaUrl(cat, 'card_portrait', getCategoryImage(getLocalizedField(cat.name, lang)))}
|
||||
className="absolute inset-0 w-full h-full object-cover group-hover:scale-105 transition-transform duration-700"
|
||||
alt={getLocalizedField(cat.name, lang)}
|
||||
onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
|
||||
|
||||
@@ -5,7 +5,7 @@ import Navbar from '../components/Navbar'
|
||||
import Footer from '../components/Footer'
|
||||
import ProductCard from '../components/ProductCard'
|
||||
import DynamicPageRenderer from '../components/DynamicPageRenderer'
|
||||
import { API_BASE, getCategoryImage, type Category, type Product, type PageSection } from '../types'
|
||||
import { API_BASE, getCategoryImage, getCategoryMedia, resolveCategoryMediaUrl, type Category, type Product, type PageSection } from '../types'
|
||||
import { getLocalizedField } from '../utils/localization'
|
||||
import { Sparkles, Layers, Grid3X3, ArrowRight } from 'lucide-react'
|
||||
|
||||
@@ -101,7 +101,13 @@ export default function CategoryPage() {
|
||||
const bottomSections = cmsSections.filter(s => s.isActive && s.type.toUpperCase() !== 'ANNOUNCEMENT_BAR' && s.type.toUpperCase() !== 'HERO' && s.type.toUpperCase() !== 'BANNER')
|
||||
|
||||
const categoryName = getLocalizedField(category?.name, lang)
|
||||
const categoryImageUrl = category?.imageUrl || (categoryName ? getCategoryImage(categoryName) : '')
|
||||
const fallbackImageUrl = categoryName ? getCategoryImage(categoryName) : ''
|
||||
const categoryThumbnailUrl = resolveCategoryMediaUrl(category, 'thumbnail', fallbackImageUrl)
|
||||
const heroDesktopUrl = resolveCategoryMediaUrl(category, 'hero_desktop', fallbackImageUrl)
|
||||
const heroMobileUrl = resolveCategoryMediaUrl(category, 'hero_mobile', heroDesktopUrl)
|
||||
const heroDesktopMedia = getCategoryMedia(category, 'hero_desktop')
|
||||
const heroMobileMedia = getCategoryMedia(category, 'hero_mobile')
|
||||
const hasArtDirectedHero = Boolean(category?.media?.some((item) => item.role === 'hero_desktop' || item.role === 'hero_mobile'))
|
||||
const layoutType = category?.layoutType || 'split_showcase'
|
||||
|
||||
// Determine Product Grid Class based on layout archetype
|
||||
@@ -130,7 +136,7 @@ export default function CategoryPage() {
|
||||
<Navbar categories={categories} />
|
||||
|
||||
{/* Hero / Banner Area */}
|
||||
{heroSections.length > 0 ? (
|
||||
{heroSections.length > 0 && !(layoutType === 'editorial_hero' && hasArtDirectedHero) ? (
|
||||
<div className="pt-20">
|
||||
<DynamicPageRenderer
|
||||
sections={heroSections}
|
||||
@@ -142,12 +148,19 @@ export default function CategoryPage() {
|
||||
/* ── Archetype 2: Editorial Hero Layout ── */
|
||||
<section className="relative overflow-hidden min-h-[380px] md:min-h-[460px] flex items-center justify-center border-b border-white/10 bg-night-950">
|
||||
{/* Immersive Background Image with Dark Gradient Overlays */}
|
||||
{categoryImageUrl && (
|
||||
{heroDesktopUrl && (
|
||||
<div className="absolute inset-0 z-0">
|
||||
<img
|
||||
src={categoryImageUrl}
|
||||
src={heroDesktopUrl}
|
||||
alt={categoryName}
|
||||
className="w-full h-full object-cover object-center filter brightness-[0.45] saturate-125 scale-105 transform transition-transform duration-1000"
|
||||
className="hidden h-full w-full object-cover filter brightness-[0.45] saturate-125 scale-105 transform transition-transform duration-1000 md:block"
|
||||
style={{ objectPosition: `${(heroDesktopMedia?.focalX ?? 0.5) * 100}% ${(heroDesktopMedia?.focalY ?? 0.5) * 100}%` }}
|
||||
/>
|
||||
<img
|
||||
src={heroMobileUrl}
|
||||
alt={categoryName}
|
||||
className="h-full w-full object-cover filter brightness-[0.45] saturate-125 scale-105 transform transition-transform duration-1000 md:hidden"
|
||||
style={{ objectPosition: `${(heroMobileMedia?.focalX ?? 0.5) * 100}% ${(heroMobileMedia?.focalY ?? 0.5) * 100}%` }}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-night-950 via-night-950/70 to-night-950/40" />
|
||||
<div className="absolute inset-0 bg-radial-gradient from-transparent via-night-950/40 to-night-950/90" />
|
||||
@@ -257,10 +270,10 @@ export default function CategoryPage() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{categoryImageUrl && (
|
||||
{categoryThumbnailUrl && (
|
||||
<div className="relative w-48 h-48 md:w-64 md:h-64 shrink-0 rounded-3xl overflow-hidden shadow-2xl border border-white/10 bg-night-950 group">
|
||||
<img
|
||||
src={categoryImageUrl}
|
||||
src={categoryThumbnailUrl}
|
||||
alt={categoryName}
|
||||
className="absolute inset-0 w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||
onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
|
||||
|
||||
Reference in new issue
Block a user