Initial commit: Meshkee dashboards monorepo.
Includes business, customer, and super-admin apps with shared packages and production deploy scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { ChevronLeft, ChevronRight, Plus } from 'lucide-react'
|
||||
import { useRef } from 'react'
|
||||
import type { WebsiteSliderSlide } from '../types/websiteSlider'
|
||||
import { Tooltip } from './Tooltip'
|
||||
import { WebsiteSliderSlideCard } from './WebsiteSliderSlideCard'
|
||||
import styles from './WebsiteSliderGallery.module.css'
|
||||
|
||||
interface WebsiteSliderGalleryProps {
|
||||
slides: WebsiteSliderSlide[]
|
||||
onAddSlide: () => void
|
||||
onRemoveSlide: (slide: WebsiteSliderSlide) => void
|
||||
}
|
||||
|
||||
export function WebsiteSliderGallery({
|
||||
slides,
|
||||
onAddSlide,
|
||||
onRemoveSlide,
|
||||
}: WebsiteSliderGalleryProps) {
|
||||
const trackRef = useRef<HTMLDivElement>(null)
|
||||
const showNav = slides.length > 0
|
||||
|
||||
function scrollBy(direction: -1 | 1) {
|
||||
const track = trackRef.current
|
||||
if (!track) return
|
||||
const amount = Math.max(track.clientWidth * 0.75, 280)
|
||||
track.scrollBy({ left: direction * amount, behavior: 'smooth' })
|
||||
}
|
||||
|
||||
return (
|
||||
<section className={styles.section}>
|
||||
{showNav && (
|
||||
<div className={styles.header}>
|
||||
<div className={styles.headerActions}>
|
||||
<Tooltip label="Scroll left">
|
||||
<button
|
||||
type="button"
|
||||
className={styles.navBtn}
|
||||
onClick={() => scrollBy(-1)}
|
||||
aria-label="Scroll left"
|
||||
>
|
||||
<ChevronLeft size={18} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip label="Scroll right">
|
||||
<button
|
||||
type="button"
|
||||
className={styles.navBtn}
|
||||
onClick={() => scrollBy(1)}
|
||||
aria-label="Scroll right"
|
||||
>
|
||||
<ChevronRight size={18} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={styles.trackWrap}>
|
||||
<div className={styles.track} ref={trackRef}>
|
||||
<div className={`${styles.slideSlot} ${styles.slideSlotAdd}`}>
|
||||
<Tooltip label="Add slide">
|
||||
<button
|
||||
type="button"
|
||||
className={styles.addCard}
|
||||
onClick={onAddSlide}
|
||||
aria-label="Add slide"
|
||||
>
|
||||
<span className={styles.addIcon}>
|
||||
<Plus size={28} />
|
||||
</span>
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
{slides.map((slide) => (
|
||||
<div key={slide.id} className={styles.slideSlot}>
|
||||
<WebsiteSliderSlideCard slide={slide} onRemove={() => onRemoveSlide(slide)} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user