Untitled

 avatar
unknown
plain_text
2 months ago
4.4 kB
4
Indexable
// components/hero-designs/ModernHero.tsx
import { motion } from "framer-motion";
import { ChevronDown } from "lucide-react";
import { ClientConfig } from "@/lib/client-config";
import { getR2ImageUrl } from "@/lib/r2";

interface ModernHeroProps {
  config: ClientConfig;
}

export function ModernHero({ config }: ModernHeroProps) {
  const heroConfig = config.welcomeHero || {};
  const images = heroConfig.images || [config.highlightImage];
  const mainImage = images[0];
  const imageUrl = mainImage.startsWith('http') 
    ? mainImage 
    : getR2ImageUrl(config.id, mainImage.split('/').pop() || '');
  
  const overlayOpacity = heroConfig.overlayOpacity ?? 0.3;
  const textColor = heroConfig.textColor === 'dark' ? 'text-gray-800' : 'text-white';
  
  // Split title into words for animation
  const titleWords = config.title.split(' ');
  
  return (
    <div className="relative h-screen w-full overflow-hidden">
      {/* Background Image */}
      <div className="absolute inset-0">
        <img
          src={imageUrl}
          alt={config.title}
          className="h-full w-full object-cover"
        />
        <div 
          className="absolute inset-0 bg-gradient-to-b from-black/70 via-black/40 to-black/70" 
          style={{ opacity: overlayOpacity }}
        />
      </div>
      
      {/* Content */}
      <div className="relative z-10 flex h-full flex-col items-center justify-center px-4 text-center">
        {heroConfig.showLogo && heroConfig.logoUrl && (
          <motion.img
            src={heroConfig.logoUrl}
            alt="Logo"
            className="mb-8 h-16 w-auto"
            initial={{ opacity: 0, y: -20 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.8, delay: 0.2 }}
          />
        )}
        
        {/* Animated Title Words */}
        <div className="mb-4 flex max-w-4xl flex-wrap justify-center gap-x-3 gap-y-2">
          {titleWords.map((word, index) => (
            <motion.span
              key={index}
              className={`${textColor} text-4xl font-bold sm:text-5xl md:text-6xl lg:text-7xl`}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
            >
              {word}
            </motion.span>
          ))}
        </div>
        
        {/* Animated Subtitle with Reveal Effect */}
        {heroConfig.subtitle && (
          <div className="relative mt-6 overflow-hidden">
            <motion.div
              className="relative overflow-hidden"
              initial={{ width: 0 }}
              animate={{ width: "100%" }}
              transition={{ duration: 1.2, delay: 0.6 + titleWords.length * 0.1 }}
            >
              <motion.p
                className={`${textColor} max-w-xl text-lg sm:text-xl px-3`}
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                transition={{ duration: 0.5, delay: 0.8 + titleWords.length * 0.1 }}
              >
                {heroConfig.subtitle}
              </motion.p>
            </motion.div>
          </div>
        )}
        
        {/* Animated Date */}
        <motion.div
          className={`${textColor} mt-8 text-lg sm:text-xl`}
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5, delay: 1 + titleWords.length * 0.1 }}
        >
          {config.date}
        </motion.div>
      </div>
      
      {/* Gradient Overlay at Bottom */}
      <div className="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-t from-black/40 to-transparent"></div>
      
      {/* Scroll Indicator */}
      {(heroConfig.scrollIndicator ?? true) && (
        <motion.div
          className="absolute bottom-8 left-0 right-0 flex justify-center"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ 
            duration: 0.8, 
            delay: 1.2 + titleWords.length * 0.1,
            repeat: Infinity,
            repeatType: "reverse",
            repeatDelay: 0.5
          }}
        >
          <ChevronDown className={`${textColor} h-8 w-8`} />
        </motion.div>
      )}
    </div>
  );
}
Editor is loading...
Leave a Comment