This commit is contained in:
Your Name committed 2026-07-12 00:46:25 -04:00
1 parent 5c09629b6f
commit 2e00715142
5 files changed
+27 -14

No files matched your search

@@ -1,12 +1,13 @@
import { UploadCloud, Image as ImageIcon } from 'lucide-react'; import { UploadCloud, Image as ImageIcon } from 'lucide-react';
import { type PageSection } from '@homaroma/types'; import { type PageSection } from '@homaroma/types';
import FocalPointPicker from './FocalPointPicker';
interface HeroV2FormProps { interface HeroV2FormProps {
editingSection: Partial<PageSection>; editingSection: Partial<PageSection>;
editingLang: string; editingLang: string;
getLocalizedValue: (payload: any, field: string) => string; getLocalizedValue: (payload: any, field: string) => string;
updateLocalizedValue: (field: string, value: string) => void; updateLocalizedValue: (field: string, value: string) => void;
updatePayloadValue: (field: string, value: string | number | boolean) => void; updatePayloadValue: (field: string, value: any) => void;
setUploadTarget: (target: { type: 'main' | 'slide'; index?: number } | null) => void; setUploadTarget: (target: { type: 'main' | 'slide'; index?: number } | null) => void;
setIsMediaModalOpen: (open: boolean) => void; setIsMediaModalOpen: (open: boolean) => void;
} }
@@ -47,6 +48,16 @@ export default function HeroV2Form({
</div> </div>
</div> </div>
{editingSection.payload?.imageUrl && (
<div className="md:col-span-2">
<FocalPointPicker
imageUrl={editingSection.payload.imageUrl}
focalPoint={editingSection.payload.focalPoint}
onChange={(focalPoint) => updatePayloadValue('focalPoint', focalPoint)}
/>
</div>
)}
<div className="space-y-2"> <div className="space-y-2">
<label className="text-[10px] uppercase font-bold tracking-widest text-slate-400">Alignment</label> <label className="text-[10px] uppercase font-bold tracking-widest text-slate-400">Alignment</label>
<select <select
+3 -3
View File
@@ -36,8 +36,8 @@ export default function DynamicHero({ payload }: DynamicHeroProps) {
}; };
return ( return (
<section className="ui-hero-shell"> <section className="relative w-full flex flex-col md:block md:h-[90vh] md:aspect-[21/9] bg-[#EBE7E0] overflow-hidden">
<div className="absolute inset-0 z-0"> <div className="relative w-full h-[50vh] min-h-[400px] md:absolute md:inset-0 md:h-full md:z-0">
<img <img
src={imageUrl || `${import.meta.env.VITE_API_URL.replace('/api', '')}/assets/hero.png`} src={imageUrl || `${import.meta.env.VITE_API_URL.replace('/api', '')}/assets/hero.png`}
className="w-full h-full object-cover" className="w-full h-full object-cover"
@@ -49,7 +49,7 @@ export default function DynamicHero({ payload }: DynamicHeroProps) {
/> />
</div> </div>
<div className="ui-hero-content animate-fade-in"> <div className="relative z-10 mx-auto py-12 w-full max-w-4xl space-y-6 px-8 text-center md:py-0 md:h-full md:flex md:flex-col md:justify-center md:items-center animate-fade-in">
<p className="text-pop-black/70 font-semibold tracking-[0.3em] text-xs md:text-sm uppercase drop-shadow-md"> <p className="text-pop-black/70 font-semibold tracking-[0.3em] text-xs md:text-sm uppercase drop-shadow-md">
{tagline || t('hero.defaultTagline')} {tagline || t('hero.defaultTagline')}
</p> </p>
+3 -4
View File
@@ -46,18 +46,17 @@ export default function DynamicHeroV2({ payload }: DynamicHeroV2Props) {
}; };
return ( return (
<section className="relative w-full h-[80vh] min-h-[600px] bg-white flex items-center overflow-hidden"> <section className="relative w-full flex flex-col md:block md:h-[80vh] md:min-h-[600px] bg-white overflow-hidden">
<div className="absolute inset-0 w-full h-full"> <div className="relative w-full h-[50vh] min-h-[400px] md:absolute md:inset-0 md:h-full">
<img <img
src={imageUrl} src={imageUrl}
alt={title || 'Hero'} alt={title || 'Hero'}
className="w-full h-full object-cover" className="w-full h-full object-cover"
style={{ objectPosition: focalPoint ? `${focalPoint.x} ${focalPoint.y}` : undefined }} style={{ objectPosition: focalPoint ? `${focalPoint.x} ${focalPoint.y}` : undefined }}
/> />
<div className="absolute inset-0 bg-gradient-to-r from-white/90 via-white/50 to-transparent pointer-events-none" />
</div> </div>
<div className="relative z-10 w-full max-w-7xl mx-auto px-6 md:px-12"> <div className="relative z-10 w-full max-w-7xl mx-auto px-6 py-12 md:py-0 md:h-full md:flex md:items-center md:px-12">
<div className={`max-w-xl flex flex-col gap-6 ${alignClass}`}> <div className={`max-w-xl flex flex-col gap-6 ${alignClass}`}>
{tagline && ( {tagline && (
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
@@ -107,16 +107,18 @@ function HeroSection({ payload, lang }: { payload: Record<string, unknown>, lang
const focalPoint = typeof payload.focalPoint === 'object' && payload.focalPoint ? (payload.focalPoint as { x: string, y: string }) : undefined const focalPoint = typeof payload.focalPoint === 'object' && payload.focalPoint ? (payload.focalPoint as { x: string, y: string }) : undefined
return ( return (
<section className="ui-hero-shell"> <section className="relative w-full flex flex-col md:block md:h-[90vh] md:aspect-[21/9] bg-surface-page overflow-hidden">
<div className="relative w-full h-[50vh] min-h-[400px] md:absolute md:inset-0 md:h-full">
<Image <Image
src={imageUrl} src={imageUrl}
alt={title || ''} alt={title || ''}
fill fill
unoptimized unoptimized
className="absolute inset-0 h-full w-full scale-[1.02] object-cover" className="object-cover md:scale-[1.02]"
style={{ objectPosition: focalPoint ? `${focalPoint.x} ${focalPoint.y}` : undefined }} style={{ objectPosition: focalPoint ? `${focalPoint.x} ${focalPoint.y}` : undefined }}
/> />
<div className="relative z-10 mx-auto mt-16 w-full max-w-4xl space-y-6 px-8 text-center md:mt-0"> </div>
<div className="relative z-10 mx-auto py-12 w-full max-w-4xl space-y-6 px-8 text-center md:py-0 md:h-full md:flex md:flex-col md:justify-center md:items-center">
<div className="space-y-6"> <div className="space-y-6">
{tagline && ( {tagline && (
<p className="text-xs font-semibold uppercase tracking-[0.3em] text-[#EAEFEA] drop-shadow-md md:text-sm"> <p className="text-xs font-semibold uppercase tracking-[0.3em] text-[#EAEFEA] drop-shadow-md md:text-sm">
@@ -221,8 +223,8 @@ function HeroV2Section({ payload, lang }: { payload: Record<string, unknown>, la
const alignClass = align === 'center' ? 'text-center items-center mx-auto' : align === 'right' ? 'text-right items-end ml-auto' : 'text-left items-start' const alignClass = align === 'center' ? 'text-center items-center mx-auto' : align === 'right' ? 'text-right items-end ml-auto' : 'text-left items-start'
return ( return (
<section className="relative w-full h-[80vh] min-h-[600px] bg-surface-page flex items-center overflow-hidden"> <section className="relative w-full flex flex-col md:block md:h-[80vh] md:min-h-[600px] bg-surface-page overflow-hidden">
<div className="absolute inset-0 w-full h-full"> <div className="relative w-full h-[50vh] min-h-[400px] md:absolute md:inset-0 md:h-full">
<Image <Image
src={imageUrl} src={imageUrl}
alt={title || 'Hero'} alt={title || 'Hero'}
@@ -233,7 +235,7 @@ function HeroV2Section({ payload, lang }: { payload: Record<string, unknown>, la
/> />
</div> </div>
<div className="relative z-10 w-full max-w-7xl mx-auto px-6 md:px-12"> <div className="relative z-10 w-full max-w-7xl mx-auto px-6 py-12 md:py-0 md:h-full md:flex md:items-center md:px-12">
<div className={`max-w-xl flex flex-col gap-6 ${alignClass}`}> <div className={`max-w-xl flex flex-col gap-6 ${alignClass}`}>
{tagline && ( {tagline && (
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
+1
View File
@@ -572,6 +572,7 @@ export const HeroV2SectionPayloadSchema = z.object({
primaryButtonLink: z.string().optional(), primaryButtonLink: z.string().optional(),
secondaryButtonText: LocalizedStringSchema.optional(), secondaryButtonText: LocalizedStringSchema.optional(),
secondaryButtonLink: z.string().optional(), secondaryButtonLink: z.string().optional(),
focalPoint: z.object({ x: z.string(), y: z.string() }).optional(),
}); });
export type HeroV2SectionPayload = z.infer<typeof HeroV2SectionPayloadSchema>; export type HeroV2SectionPayload = z.infer<typeof HeroV2SectionPayloadSchema>;