{s.title}
{s.body}
'use client' import { useEffect, useState } from 'react' import Link from 'next/link' export type DeckSlide = { kicker: string index: string title: React.ReactNode body: string format: React.ReactNode link?: { href: string; label: string } meta?: React.ReactNode } const V1_SLIDES: DeckSlide[] = [ { kicker: 'دليل حصري · المستوى المتوسط', index: '01', title: 'ابنِ وكيلك الأول دون فوضى', body: 'خريطة عملية لتقسيم المهام، اختيار الأدوات، وضبط ذاكرة الوكيل قبل كتابة الكود.', format: <>فيديو · 28 دقيقة>, link: { href: '/posts/agent-loop-stop-condition', label: 'شاهد المعاينة ←' }, }, { kicker: 'مقال تطبيقي · للمبتدئين', index: '02', title: 'كيف تختار نموذجاً لمهمتك؟', body: 'مقارنة منهجية حسب الجودة، التكلفة، السرعة، والخصوصية — من دون ضجيج تسويقي.', format: <>قراءة · 12 دقيقة>, link: { href: '/posts/article-agent-guide', label: 'ابدأ القراءة ←' }, }, { kicker: 'مسار متقدم · للأعضاء', index: '03', title: <>من RAG إلى إجابة موثوقة>, body: 'صمّم الاسترجاع، اختبر المصادر، وافهم أين تنهار الإجابة قبل أن تصل إلى المستخدم.', format: <>سلسلة · 4 أجزاء>, link: { href: '/subscription', label: 'شاهد للأعضاء ←' }, }, ] const DOT_LABELS = ['الشريحة الأولى', 'الشريحة الثانية', 'الشريحة الثالثة'] /* Featured content carousel. Manual selection pauses rotation until resumed. */ export default function CatalogDeck({ slides = V1_SLIDES }: { slides?: DeckSlide[] }) { const [activeSlide, setActiveSlide] = useState(0) const [ready, setReady] = useState(false) const [playing, setPlaying] = useState(true) const [hovered, setHovered] = useState(false) const [focused, setFocused] = useState(false) const current = slides.length ? activeSlide % slides.length : 0 const advancing = ready && playing && !hovered && !focused && slides.length > 1 useEffect(() => { try { const stored = Number(localStorage.getItem('midad-slide')) if (Number.isInteger(stored) && stored >= 0) setActiveSlide(stored) } catch { /* Persistence is optional. */ } const motion = window.matchMedia('(prefers-reduced-motion: reduce)') if (motion.matches) setPlaying(false) const onMotion = () => { if (motion.matches) setPlaying(false) } motion.addEventListener('change', onMotion) setReady(true) return () => motion.removeEventListener('change', onMotion) }, []) useEffect(() => { if (!ready) return try { localStorage.setItem('midad-slide', String(current)) } catch { /* optional persistence */ } }, [current, ready]) useEffect(() => { if (!advancing) return const timer = setTimeout(() => setActiveSlide(index => (index + 1) % slides.length), 6500) return () => clearTimeout(timer) }, [advancing, current, slides.length]) function selectSlide(index: number) { setActiveSlide((index + slides.length) % slides.length) setPlaying(false) } if (!slides.length) return null return (
{s.body}