'use client' import { useCallback, useEffect, useRef, useState } from 'react' import { motion } from 'motion/react' import { Inbox, GraduationCap, Bell, Sparkles, Layers, ChevronLeft, ChevronRight } from 'lucide-react' import { useLanguage } from '@/lib/i18n' import { cn } from '@/lib/utils' export interface DashboardActionStripProps { inboxCount: number dueFlashcards: number reminderCount: number discoveryCount: number themeCount: number inboxPulse?: number onInbox: () => void onReview: () => void onReminders: () => void onDiscoveries: () => void onThemes: () => void prefersReducedMotion?: boolean } function updateOverflow(el: HTMLDivElement) { const max = el.scrollWidth - el.clientWidth if (max <= 4) return { canPrev: false, canNext: false } const pos = Math.abs(el.scrollLeft) return { canPrev: pos > 6, canNext: pos < max - 6, } } export function DashboardActionStrip({ inboxCount, dueFlashcards, reminderCount, discoveryCount, themeCount, inboxPulse = 0, onInbox, onReview, onReminders, onDiscoveries, onThemes, prefersReducedMotion, }: DashboardActionStripProps) { const { t, language } = useLanguage() const scrollerRef = useRef(null) const [canPrev, setCanPrev] = useState(false) const [canNext, setCanNext] = useState(false) const isRtl = language === 'fa' || language === 'ar' const numberLocale = language === 'fa' ? 'fa-IR' : language === 'zh' ? 'zh-CN' : language const refreshOverflow = useCallback(() => { const el = scrollerRef.current if (!el) return const next = updateOverflow(el) setCanPrev(next.canPrev) setCanNext(next.canNext) }, []) useEffect(() => { const el = scrollerRef.current if (!el) return refreshOverflow() const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(refreshOverflow) : null ro?.observe(el) el.addEventListener('scroll', refreshOverflow, { passive: true }) window.addEventListener('resize', refreshOverflow) return () => { ro?.disconnect() el.removeEventListener('scroll', refreshOverflow) window.removeEventListener('resize', refreshOverflow) } }, [refreshOverflow, inboxCount, dueFlashcards, reminderCount, discoveryCount, themeCount]) const scrollByPage = (direction: 1 | -1) => { const el = scrollerRef.current if (!el) return const delta = Math.max(el.clientWidth * 0.7, 140) * direction const left = isRtl ? -delta : delta el.scrollBy({ left, behavior: prefersReducedMotion ? 'auto' : 'smooth' }) } const items = [ { key: 'inbox', icon: Inbox, label: t('homeDashboard.inbox'), value: inboxCount, onClick: onInbox, accent: inboxCount > 0, pulse: inboxPulse > 0, }, { key: 'review', icon: GraduationCap, label: t('homeDashboard.review'), value: dueFlashcards, onClick: onReview, accent: dueFlashcards > 0, }, { key: 'reminders', icon: Bell, label: t('homeDashboard.reminders'), value: reminderCount, onClick: onReminders, accent: reminderCount > 0, }, { key: 'discoveries', icon: Sparkles, label: t('homeDashboard.aiFound'), value: discoveryCount, onClick: onDiscoveries, accent: discoveryCount > 0, }, { key: 'themes', icon: Layers, label: t('homeDashboard.themes'), value: themeCount, onClick: onThemes, accent: themeCount > 0, }, ] const chevronBtn = 'absolute top-1/2 z-10 flex h-11 w-11 -translate-y-1/2 items-center justify-center rounded-full border border-border/40 bg-[#F9F8F6]/95 dark:bg-[#0D0D0D]/95 text-foreground shadow-sm hover:bg-brand-accent/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-accent' return (
{canPrev && ( )} {canNext && ( )}
{items.map(item => { const Icon = item.icon const Wrapper = item.pulse && !prefersReducedMotion ? motion.button : 'button' const motionProps = item.pulse && !prefersReducedMotion ? { animate: { scale: [1, 1.03, 1] }, transition: { duration: 0.45 }, } : {} return ( { e.currentTarget.scrollIntoView({ inline: 'nearest', block: 'nearest', behavior: prefersReducedMotion ? 'auto' : 'smooth', }) }} {...motionProps} className={`snap-start shrink-0 flex min-h-11 min-w-[128px] items-center gap-2.5 px-3.5 py-2.5 rounded-xl border transition-colors text-start ${ item.accent ? 'border-brand-accent/30 bg-brand-accent/[0.06] hover:border-brand-accent/50 hover:bg-brand-accent/10 shadow-sm' : 'border-border/25 bg-white/60 dark:bg-zinc-900/40 hover:border-border/50' }`} >

{item.value.toLocaleString(numberLocale)}

{item.label}

) })}
) }