import React, { CSSProperties } from 'react'; import { useNode, UserComponent } from '@craftjs/core'; import { cssPropsToString } from '../../utils/style-helpers'; interface HeroProps { heading?: string; subtitle?: string; buttonText?: string; buttonHref?: string; secondaryButtonText?: string; secondaryButtonHref?: string; bgType?: 'color' | 'gradient' | 'image' | 'video'; bgColor?: string; bgGradientFrom?: string; bgGradientTo?: string; bgGradientAngle?: number; bgImage?: string; bgVideo?: string; overlayColor?: string; overlayOpacity?: number; textColor?: string; buttonBgColor?: string; buttonTextColor?: string; minHeight?: string; verticalAlign?: 'top' | 'center' | 'bottom'; textAlign?: 'left' | 'center' | 'right'; style?: CSSProperties; } // Helper: build the background CSS value function buildBackground(props: HeroProps): string { switch (props.bgType) { case 'gradient': return `linear-gradient(${props.bgGradientAngle || 135}deg, ${props.bgGradientFrom || '#667eea'}, ${props.bgGradientTo || '#764ba2'})`; case 'image': return props.bgImage ? `url('${props.bgImage}') center/cover no-repeat` : '#1e293b'; case 'color': default: return props.bgColor || '#1e293b'; } } export const HeroSimple: UserComponent = ({ heading = 'Build Something Amazing', subtitle = 'Create beautiful websites without writing a single line of code.', buttonText = 'Get Started', buttonHref = '#', secondaryButtonText = '', secondaryButtonHref = '#', bgType = 'color', bgColor = '#1e293b', bgGradientFrom = '#667eea', bgGradientTo = '#764ba2', bgGradientAngle = 135, bgImage = '', bgVideo = '', overlayColor = '#000000', overlayOpacity = 0, textColor = '#ffffff', buttonBgColor = '#3b82f6', buttonTextColor = '#ffffff', minHeight = '500px', verticalAlign = 'center', textAlign = 'center', style = {}, }) => { const { connectors: { connect, drag } } = useNode(); const bg = buildBackground({ bgType, bgColor, bgGradientFrom, bgGradientTo, bgGradientAngle, bgImage, } as HeroProps); const justifyMap = { top: 'flex-start', center: 'center', bottom: 'flex-end' }; return (
{ if (ref) connect(drag(ref)); }} style={{ ...style, background: bgType !== 'image' ? bg : undefined, backgroundImage: bgType === 'image' && bgImage ? `url('${bgImage}')` : undefined, backgroundSize: bgType === 'image' ? 'cover' : undefined, backgroundPosition: bgType === 'image' ? 'center' : undefined, minHeight: minHeight === '100vh' ? '100vh' : minHeight, display: 'flex', alignItems: justifyMap[verticalAlign] || 'center', justifyContent: 'center', position: 'relative', overflow: 'hidden', padding: '60px 20px', }} > {/* Video background */} {bgType === 'video' && bgVideo && (
); }; /* ---------- Settings panel ---------- */ const inputStyle: React.CSSProperties = { width: '100%', padding: '6px 8px', background: '#27272a', color: '#e4e4e7', border: '1px solid #3f3f46', borderRadius: 4, fontSize: 12, }; const labelStyle: React.CSSProperties = { fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 4, }; const btnStyle = (active: boolean): React.CSSProperties => ({ flex: 1, padding: '6px 4px', fontSize: 11, borderRadius: 4, cursor: 'pointer', border: '1px solid #3f3f46', background: active ? '#3b82f6' : '#27272a', color: active ? '#fff' : '#a1a1aa', fontWeight: active ? 600 : 400, }); const HeroSettings: React.FC = () => { const { actions: { setProp }, props } = useNode((node) => ({ props: node.data.props as HeroProps, })); return (
{/* Content */}
setProp((p: HeroProps) => { p.heading = e.target.value; })} style={inputStyle} />