-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat(web): add Valentines Day theme to homepage #11201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| "use client" | ||
|
|
||
| import { useEffect, useState } from "react" | ||
|
|
||
| interface FloatingHeart { | ||
| id: number | ||
| left: number | ||
| size: number | ||
| duration: number | ||
| delay: number | ||
| opacity: number | ||
| } | ||
|
|
||
| export function FloatingHearts() { | ||
| const [hearts, setHearts] = useState<FloatingHeart[]>([]) | ||
| const [isVisible, setIsVisible] = useState(true) | ||
|
|
||
| useEffect(() => { | ||
| // Check if we're in the Valentine's date range (Feb 1-15) | ||
| const now = new Date() | ||
| const month = now.getMonth() // 0-indexed, so February is 1 | ||
| const day = now.getDate() | ||
| const isValentinesSeason = month === 1 && day >= 1 && day <= 15 | ||
| setIsVisible(isValentinesSeason) | ||
|
|
||
| if (!isValentinesSeason) return | ||
|
|
||
| // Generate random hearts | ||
| const generatedHearts: FloatingHeart[] = Array.from({ length: 15 }, (_, i) => ({ | ||
| id: i, | ||
| left: Math.random() * 100, | ||
| size: 12 + Math.random() * 16, | ||
| duration: 8 + Math.random() * 12, | ||
| delay: Math.random() * 10, | ||
| opacity: 0.1 + Math.random() * 0.2, | ||
| })) | ||
| setHearts(generatedHearts) | ||
| }, []) | ||
|
|
||
| if (!isVisible || hearts.length === 0) return null | ||
|
|
||
| return ( | ||
| <div className="pointer-events-none fixed inset-0 z-0 overflow-hidden" aria-hidden="true"> | ||
| {hearts.map((heart) => ( | ||
| <div | ||
| key={heart.id} | ||
| className="absolute animate-float-up text-rose-500/50 dark:text-rose-400/30" | ||
| style={{ | ||
| left: `${heart.left}%`, | ||
| bottom: "-50px", | ||
| fontSize: `${heart.size}px`, | ||
| animationDuration: `${heart.duration}s`, | ||
| animationDelay: `${heart.delay}s`, | ||
| opacity: heart.opacity, | ||
| }}> | ||
| ❤ | ||
| </div> | ||
| ))} | ||
| </div> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,46 @@ | ||||||
| "use client" | ||||||
|
|
||||||
| import { Heart, Sparkles } from "lucide-react" | ||||||
| import { useEffect, useState } from "react" | ||||||
|
|
||||||
| export function ValentinesBanner() { | ||||||
| const [isVisible, setIsVisible] = useState(true) | ||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initializing
Suggested change
Fix it with Roo Code or mention @roomote and request a fix. |
||||||
|
|
||||||
| // Check if we're in the Valentine's date range (Feb 1-15) | ||||||
| useEffect(() => { | ||||||
| const now = new Date() | ||||||
| const month = now.getMonth() // 0-indexed, so February is 1 | ||||||
| const day = now.getDate() | ||||||
| // Show banner from Feb 1-15 | ||||||
| const isValentinesSeason = month === 1 && day >= 1 && day <= 15 | ||||||
| setIsVisible(isValentinesSeason) | ||||||
| }, []) | ||||||
|
|
||||||
| if (!isVisible) return null | ||||||
|
|
||||||
| return ( | ||||||
| <div className="relative overflow-hidden bg-gradient-to-r from-pink-500 via-rose-500 to-red-500 py-2.5 text-white"> | ||||||
| {/* Animated sparkles background */} | ||||||
| <div className="absolute inset-0 overflow-hidden"> | ||||||
| {[...Array(6)].map((_, i) => ( | ||||||
| <Sparkles | ||||||
| key={i} | ||||||
| className="absolute animate-pulse text-white/30" | ||||||
| style={{ | ||||||
| left: `${15 + i * 15}%`, | ||||||
| top: `${20 + (i % 3) * 20}%`, | ||||||
| animationDelay: `${i * 0.3}s`, | ||||||
| transform: `scale(${0.6 + (i % 3) * 0.2})`, | ||||||
| }} | ||||||
| /> | ||||||
| ))} | ||||||
| </div> | ||||||
|
|
||||||
| <div className="container relative mx-auto flex items-center justify-center gap-3 px-4 text-center text-sm font-medium"> | ||||||
| <Heart className="size-4 animate-heartbeat fill-current" /> | ||||||
| <span>Happy Valentine's Day! Spread the love and build something amazing with Roo Code</span> | ||||||
| <Heart className="size-4 animate-heartbeat fill-current" style={{ animationDelay: "0.5s" }} /> | ||||||
| </div> | ||||||
| </div> | ||||||
| ) | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The server-side
isValentinesSeason()check is cached for up to 1 hour (revalidate = 3600), while client components (ValentinesBanner,FloatingHearts) independently check the date in real-time viauseEffect. At date boundaries (Jan 31 -> Feb 1 or Feb 15 -> Feb 16), this can cause visual inconsistency where the background glow color (server-determined) doesn't match the banner/hearts visibility (client-determined). Consider passing the server-calculatedisValentinesvalue as a prop to client components, or accept this as an acceptable edge case at date boundaries.Fix it with Roo Code or mention @roomote and request a fix.