import { useState, useMemo } from 'react'; import { Filter, ChevronDown, Search, X } from 'lucide-react'; import { type Achievement } from '../data'; import { useData } from '../context/DataContext'; import AchievementCard from './AchievementCard'; import AchievementModal from './AchievementModal'; import { useLang } from '../context/LanguageContext'; const INITIAL_COUNT = 3; const LOAD_MORE_COUNT = 3; export default function AchievementGrid() { const { t } = useLang(); const { achievements, loading, error, refetch } = useData(); const [searchQuery, setSearchQuery] = useState(''); const [filterLevel, setFilterLevel] = useState(''); const [filterCategory, setFilterCategory] = useState(''); const [filterYear, setFilterYear] = useState(''); const [visibleCount, setVisibleCount] = useState(INITIAL_COUNT); const [selectedAchievement, setSelectedAchievement] = useState(null); // Derive unique categories and years from data const categories = useMemo( () => [...new Set(achievements.map((a) => a.category))].sort(), [achievements] ); const years = useMemo( () => [...new Set(achievements.map((a) => a.year))].sort((a: number, b: number) => b - a), [achievements] ); // Filter + search logic const filtered = useMemo(() => { const q = searchQuery.toLowerCase().trim(); return achievements.filter((a) => { const matchSearch = !q || a.title.toLowerCase().includes(q) || a.team.toLowerCase().includes(q) || a.category.toLowerCase().includes(q) || a.competition.toLowerCase().includes(q); const matchLevel = !filterLevel || a.level === filterLevel; const matchCategory = !filterCategory || a.category === filterCategory; const matchYear = !filterYear || String(a.year) === filterYear; return matchSearch && matchLevel && matchCategory && matchYear; }); }, [searchQuery, filterLevel, filterCategory, filterYear, achievements]); const visible = filtered.slice(0, visibleCount); const hasMore = visibleCount < filtered.length; const isFiltered = searchQuery || filterLevel || filterCategory || filterYear; const resetFilters = () => { setSearchQuery(''); setFilterLevel(''); setFilterCategory(''); setFilterYear(''); setVisibleCount(INITIAL_COUNT); }; const handleFilterChange = (setter: (v: string) => void) => (v: string) => { setter(v); setVisibleCount(INITIAL_COUNT); }; const handleLoadMore = () => setVisibleCount((prev) => prev + LOAD_MORE_COUNT); const handleShowLess = () => { setVisibleCount(INITIAL_COUNT); document.getElementById('achievement-grid-section')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }; return ( <> {/* Achievement Modal */} setSelectedAchievement(null)} />
{/* Section header */}

{t.achievement.sectionTitle}

{t.achievement.sectionDesc}

{/* Filter + Search Section */}
{/* Row 1: Label + Reset */}
{t.achievement.filterTitle}
{isFiltered && ( )}
{/* Row 2: Search bar */}
{ setSearchQuery(e.target.value); setVisibleCount(INITIAL_COUNT); }} placeholder={t.achievement.searchPlaceholder} className="w-full bg-slate-50 text-slate-700 text-sm rounded py-2 pl-9 pr-4 border border-slate-200 focus:outline-none focus:ring-2 focus:ring-primary-gold" /> {searchQuery && ( )}
{/* Row 3: Dropdowns */}
{/* Level Filter */}
{/* Category Filter */}
{/* Year Filter */}
{/* Results count */} {isFiltered && (

{t.achievement.showing}{' '} {filtered.length}{' '} {t.achievement.matching}

)} {/* Grid */} {loading ? (
{[1, 2, 3].map((n) => (
))}
) : error ? (

Gagal memuat data

{error}

) : visible.length === 0 ? (

{t.achievement.noData}

{t.achievement.noDataSub}

) : (
{visible.map((achievement) => (
setSelectedAchievement(a)} />
))}
)} {/* Load More / Show Less */}
{hasMore && ( )} {!hasMore && visible.length > 0 && filtered.length > INITIAL_COUNT && (

{t.achievement.showing} {filtered.length} {t.achievement.allShown}

)} {visibleCount > INITIAL_COUNT && visible.length > 0 && ( )}
); }