Untitled

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

interface GridHeroProps {
  config: ClientConfig;
}

export function GridHero({ config }: GridHeroProps) {
  const heroConfig = config.welcomeHero || {};
  const images = heroConfig.images || [config.highlightImage];
  
  // Get processed image URLs
  const imageUrls = images.map(img => 
    img.startsWith('http') 
      ? img 
      : getR2ImageUrl(config.id, img.split('/').pop() || '')
  );
  
  // Fill in with duplicates if less than 4 images
  while (imageUrls.length < 4) {
    imageUrls.push(imageUrls[imageUrls.length % imageUrls.length]);
  }
  
  const overlayOpacity = heroConfig.overlayOpacity ?? 0.2;
  const textColor = heroConfig.textColor === 'dark' ? 'text-gray-800' : 'text-white';
  
  return (
    <div className="relative h-screen w-full overflow-hidden">
      {/* Grid Layout */}
      <div className="grid h-full w-full grid-cols-2 grid-rows-2">
        {imageUrls.slice(0, 4).map((url, index) => (
          <div key={index} className="relative overflow-hidden">
            <img
              src={url}
              alt={`Image ${index + 1}`}
              className="h-full w-full object-cover"
            />
            <div 
              className="absolute inset-0 bg-black" 
              style={{ opacity: overlayOpacity }}
            />
          </div>
        ))}
      </div>
      
      {/* Overlay for content */}
      <div className="absolute inset-0 bg-black/40" />
      
      {/* Content */}
      <div className="absolute inset-0 z-10 flex 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 }}
          />
        )}
        
        <motion.h1
          className="mb-4 max-w-4xl text-4xl font-bold text-white sm:text-5xl md:text-6xl lg:text-7xl"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ duration: 0.8, delay: 0.4 }}
        >
          {config.title}
        </motion.h1>
        
        {heroConfig.subtitle && (
          <motion.p
            className="mb-6 max-w-xl text-lg text-white sm:text-xl"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ duration: 0.8, delay: 0.6 }}
          >
            {heroConfig.subtitle}
          </motion.p>
        )}
        
        <motion.div
          className="text-lg text-white sm:text-xl"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ duration: 0.8, delay: 0.8 }}
        >
          {config.date}
        </motion.div>
      </div>
      
      {/* Scroll Indicator */}
      {(heroConfig.scrollIndicator ?? true) && (
        <motion.div
          className="absolute bottom-8 left-0 right-0 flex justify-center"
          initial={{ opacity: 0, y: -20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ 
            duration: 0.8, 
            delay: 1,
            repeat: Infinity,
            repeatType: "reverse",
            repeatDelay: 0.5
          }}
        >
          <ChevronDown className="h-8 w-8 text-white" />
        </motion.div>
      )}
    </div>
  );
}
Editor is loading...
Leave a Comment