Import source: src/components/TrendingTracks/TrendingTracks
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import { useRef, useEffect } from 'react'
|
||||
import { motion, useInView } from 'framer-motion'
|
||||
import { gsap } from 'gsap'
|
||||
import { ScrollTrigger } from 'gsap/ScrollTrigger'
|
||||
import TrackRow from './TrackRow'
|
||||
import { tracks } from '../../data/mockData'
|
||||
|
||||
gsap.registerPlugin(ScrollTrigger)
|
||||
|
||||
export default function TrendingTracks({ currentTrack, onPlay }) {
|
||||
const sectionRef = useRef()
|
||||
const ref = useRef()
|
||||
const inView = useInView(ref, { once: true, margin: '-80px' })
|
||||
|
||||
useEffect(() => {
|
||||
const ctx = gsap.context(() => {
|
||||
gsap.from('.track-item', {
|
||||
x: -24,
|
||||
opacity: 0,
|
||||
stagger: 0.06,
|
||||
ease: 'power3.out',
|
||||
scrollTrigger: {
|
||||
trigger: sectionRef.current,
|
||||
start: 'top 78%',
|
||||
},
|
||||
})
|
||||
}, sectionRef)
|
||||
return () => ctx.revert()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<section id="charts" ref={sectionRef} className="py-28 px-6"
|
||||
style={{ background: 'var(--dark-surface)' }}>
|
||||
<div className="section-divider" />
|
||||
|
||||
<div className="max-w-3xl mx-auto" ref={ref}>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
animate={inView ? { opacity: 1, y: 0 } : {}}
|
||||
transition={{ duration: 0.7 }}
|
||||
className="flex items-end justify-between mb-12 mt-14"
|
||||
>
|
||||
<div>
|
||||
<p className="text-xs tracking-[0.28em] uppercase gold-text mb-3 font-medium">Hot Right Now</p>
|
||||
<h2 className="font-display font-bold text-white leading-tight"
|
||||
style={{ fontSize: 'clamp(2rem, 5vw, 3.5rem)', letterSpacing: '-0.02em' }}>
|
||||
Trending <span className="gold-gradient-text">Tracks</span>
|
||||
</h2>
|
||||
</div>
|
||||
<div className="text-right hidden sm:block">
|
||||
<p className="text-xs text-muted">Updated</p>
|
||||
<p className="text-xs text-secondary font-mono mt-0.5">Weekly</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Column headers */}
|
||||
<div className="flex items-center gap-4 px-4 mb-3 text-xs text-muted uppercase tracking-widest">
|
||||
<span className="w-5 text-center">#</span>
|
||||
<span className="w-11 flex-shrink-0" />
|
||||
<span className="flex-1">Title</span>
|
||||
<span className="hidden sm:block w-14 text-right">Plays</span>
|
||||
<span className="w-9 text-right">Time</span>
|
||||
<span className="w-7" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-0.5">
|
||||
{tracks.map((track, i) => (
|
||||
<div key={track.id} className="track-item">
|
||||
<TrackRow track={track} index={i}
|
||||
isActive={currentTrack?.id === track.id}
|
||||
onPlay={onPlay} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Show more */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={inView ? { opacity: 1 } : {}}
|
||||
transition={{ delay: 0.5 }}
|
||||
className="mt-8 text-center"
|
||||
>
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.04, borderColor: 'rgba(201,168,76,0.35)', color: 'var(--gold)' }}
|
||||
className="px-6 py-2.5 rounded-full text-sm text-secondary border border-dark-border transition-all duration-200"
|
||||
>
|
||||
Show More Tracks
|
||||
</motion.button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user