Files
Event-Management-System/RIT-EVENT-MANAGEMENT--main/components/SpecialEventsBanner.tsx

183 lines
8.4 KiB
TypeScript

import React, { useState } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { SpecialEvent } from '../types';
interface SpecialEventsBannerProps {
specialEvents: SpecialEvent[];
}
const SpecialEventsBanner: React.FC<SpecialEventsBannerProps> = ({ specialEvents }) => {
const [isOpen, setIsOpen] = useState(false);
const hasEvents = specialEvents && specialEvents.length > 0;
const handleRedirect = (link: string) => {
window.location.href = link;
};
const defaultTitle = "The Grand Chronicles of RIT";
const defaultDescription = "Hark! The tides have brought forth prestigious gatherings and legendary challenges. Seek thy destiny in the links below.";
return (
<section className="py-12 relative overflow-hidden bg-transparent">
{/* Background glow (Softer and centered) */}
<div className="absolute inset-0 z-0 opacity-5 pointer-events-none">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[400px] bg-amber-500/20 blur-[80px] rounded-full"></div>
</div>
<div className="max-w-2xl mx-auto px-6 relative z-10">
{/* New Header: Descriptive text above the scroll */}
<div className="text-center mb-12">
<h2 className="font-medieval text-3xl md:text-5xl text-[#3e2723] mb-4 opacity-90">
Special Events Registry
</h2>
<p className="font-parchment text-sm md:text-base text-[#5d4037]/70 italic tracking-wide">
Tap the ancient scroll to reveal the current decrees of RIT
</p>
<div className="w-16 h-[1px] bg-[#8d6e63]/20 mx-auto mt-6"></div>
</div>
<motion.div
initial="closed"
animate={isOpen ? "open" : "closed"}
className="relative flex flex-col items-center"
>
{/* Top Roller - Interactive */}
<motion.div
onClick={() => setIsOpen(!isOpen)}
className="relative z-30 w-full h-16 rounded-full shadow-[0_8px_32px_rgba(62,39,35,0.25)] border-[3px] border-[#3e2723]/60 overflow-hidden cursor-pointer active:scale-95 transition-transform"
style={{
backgroundImage: 'url(/wood_roller_texture.png)',
backgroundSize: '100% 100%',
backgroundPosition: 'center'
}}
>
{/* End Caps: Fixes the 'broken corner' look */}
<div className="absolute inset-y-0 left-0 w-8 bg-gradient-to-r from-[#1a0f0d] to-transparent opacity-80"></div>
<div className="absolute inset-y-0 right-0 w-8 bg-gradient-to-l from-[#1a0f0d] to-transparent opacity-80"></div>
<div className="absolute inset-0 bg-gradient-to-b from-black/10 via-transparent to-black/20"></div>
<div className="absolute inset-x-4 inset-y-0 flex items-center justify-between pointer-events-none px-4">
<div className="w-4 h-4 rounded-full border border-white/5 bg-white/5 blur-[1px]"></div>
<div className="w-4 h-4 rounded-full border border-white/5 bg-white/5 blur-[1px]"></div>
</div>
<div className="absolute inset-0 flex items-center justify-center opacity-0 hover:opacity-100 transition-opacity">
<span className="text-[10px] font-medieval text-white/60 uppercase tracking-[0.3em] bg-black/20 px-4 py-1 rounded-full backdrop-blur-sm">
{isOpen ? 'Tap to Close' : 'Tap to Open'}
</span>
</div>
</motion.div>
{/* Parchment Body */}
<motion.div
variants={{
closed: {
height: 0,
opacity: 0,
transition: { duration: 0.5, ease: "easeInOut" }
},
open: {
height: 'auto',
opacity: 1,
transition: { duration: 0.8, ease: "easeOut" }
}
}}
className="relative z-20 w-[94%] overflow-hidden origin-top"
style={{
backgroundImage: 'url(/parchment_texture.png)',
backgroundSize: 'cover',
backgroundPosition: 'center'
}}
>
{/* Inner Shadow Shadow */}
<div className="absolute inset-0 bg-gradient-to-r from-black/5 via-transparent to-black/5 pointer-events-none shadow-inner"></div>
<div className="p-8 md:p-12 text-center space-y-8">
<motion.div
variants={{
closed: { opacity: 0, y: -20 },
open: { opacity: 1, y: 0 }
}}
>
<h2 className="font-medieval text-3xl md:text-5xl text-[#3e2723] mb-4 drop-shadow-sm">
{hasEvents ? defaultTitle : "The Void Chronicles"}
</h2>
<div className="w-24 h-[1px] bg-[#8d6e63]/20 mx-auto mb-6"></div>
<p className="font-parchment text-base md:text-xl text-[#5d4037] leading-relaxed max-w-lg mx-auto italic opacity-90">
{hasEvents ? defaultDescription : "The magic portal remains dormant. Check back when the moons align."}
</p>
</motion.div>
<div className="grid grid-cols-1 gap-6 pt-4">
{specialEvents.map((event, index) => (
<motion.div
key={event.id}
variants={{
closed: { opacity: 0, scale: 0.95 },
open: { opacity: 1, scale: 1 }
}}
transition={{ delay: isOpen ? 0.3 + (index * 0.1) : 0 }}
whileHover={{ scale: 1.02 }}
className="group cursor-pointer relative"
onClick={() => handleRedirect(event.link)}
>
<div className="border border-[#8d6e63]/15 bg-[#8d6e63]/5 p-5 rounded-lg backdrop-blur-[1px] transition-all duration-300 group-hover:bg-[#8d6e63]/10 group-hover:border-[#8d6e63]/30">
<h3 className="font-medieval text-xl md:text-2xl text-[#3e2723] mb-2 group-hover:text-[#795548] transition-colors">
{event.title}
</h3>
<p className="font-parchment text-xs md:text-sm text-[#5d4037] line-clamp-2 opacity-80">
{event.description}
</p>
<div className="mt-3 flex justify-end">
<span className="text-[9px] font-medieval uppercase tracking-[0.2em] text-[#8d6e63] group-hover:text-[#3e2723] flex items-center gap-2">
Behold <i className="fas fa-feather-pointed"></i>
</span>
</div>
</div>
</motion.div>
))}
</div>
{hasEvents && (
<div className="font-medieval text-[10px] text-[#8d6e63]/40 uppercase tracking-[0.4em] pt-8">
End of Scroll
</div>
)}
</div>
</motion.div>
{/* Bottom Roller - Interactive */}
<motion.div
onClick={() => setIsOpen(!isOpen)}
variants={{
closed: { y: -64 }, // Perfect overlap (h-16 = 64px)
open: { y: 0 }
}}
transition={{ duration: 0.8, ease: "easeOut" }}
className="relative z-30 w-full h-16 rounded-full shadow-[0_-8px_32px_rgba(62,39,35,0.25)] border-[3px] border-[#3e2723]/60 overflow-hidden cursor-pointer active:scale-95 transition-transform"
style={{
backgroundImage: 'url(/wood_roller_texture.png)',
backgroundSize: '100% 100%',
backgroundPosition: 'center'
}}
>
{/* End Caps: Fixes the 'broken corner' look */}
<div className="absolute inset-y-0 left-0 w-8 bg-gradient-to-r from-[#1a0f0d] to-transparent opacity-80"></div>
<div className="absolute inset-y-0 right-0 w-8 bg-gradient-to-l from-[#1a0f0d] to-transparent opacity-80"></div>
<div className="absolute inset-0 bg-gradient-to-t from-black/10 via-transparent to-black/20"></div>
</motion.div>
</motion.div>
</div>
<style>{`
.font-medieval { font-family: 'Pirata One', cursive; }
.font-parchment { font-family: 'Almendra', serif; }
`}</style>
</section>
);
};
export default SpecialEventsBanner;