import { View, Text, FlatList, TouchableOpacity, RefreshControl, ScrollView, StyleSheet, Animated, } from 'react-native' import { SafeAreaView } from 'react-native-safe-area-context' import { useState, useEffect, useRef, useCallback } from 'react' import { useRouter } from 'expo-router' import { useFocusEffect } from 'expo-router' import { useNewsList } from '@/hooks/useNews' import { NewsCard } from '@/components/news/NewsCard' import { EmptyState } from '@/components/ui/EmptyState' import { LoadingSpinner } from '@/components/ui/LoadingSpinner' import { useNewsReadStore } from '@/store/news.store' function SkeletonCard() { const anim = useRef(new Animated.Value(0.4)).current useEffect(() => { Animated.loop( Animated.sequence([ Animated.timing(anim, { toValue: 1, duration: 800, useNativeDriver: true }), Animated.timing(anim, { toValue: 0.4, duration: 800, useNativeDriver: true }), ]) ).start() }, []) return ( ) } const skeletonStyles = StyleSheet.create({ card: { backgroundColor: '#FFFFFF', borderRadius: 12, padding: 16, marginBottom: 10, marginHorizontal: 16 }, badge: { height: 20, width: 80, borderRadius: 10, backgroundColor: '#E2E8F0', marginBottom: 12 }, titleLine: { height: 16, borderRadius: 8, backgroundColor: '#E2E8F0', width: '85%', marginBottom: 8 }, titleLineShort: { height: 16, borderRadius: 8, backgroundColor: '#E2E8F0', width: '55%', marginBottom: 12 }, metaLine: { height: 12, borderRadius: 6, backgroundColor: '#F1F5F9', width: '40%' }, }) const FILTERS = [ { value: undefined, label: 'Alle' }, { value: 'Wichtig', label: 'Wichtig' }, { value: 'Pruefung', label: 'Pruefung' }, { value: 'Foerderung', label: 'Foerderung' }, { value: 'Veranstaltung', label: 'Veranstaltung' }, ] export default function NewsScreen() { const router = useRouter() const [kategorie, setKategorie] = useState(undefined) const [showSkeleton, setShowSkeleton] = useState(true) // Fetch all news (without category filter) to compute per-category unread counts const { data: allData, refetch: refetchAll, isRefetching: isRefetchingAll } = useNewsList(undefined) const { data, isLoading, refetch, isRefetching } = useNewsList(kategorie) const localReadIds = useNewsReadStore((s) => s.readIds) useFocusEffect( useCallback(() => { setShowSkeleton(true) const t = setTimeout(() => setShowSkeleton(false), 800) return () => clearTimeout(t) }, []) ) // Compute unread count per category (combining server isRead + local store) function getUnreadCount(filterValue: string | undefined) { const source = allData ?? [] const filtered = filterValue === undefined ? source : source.filter((n) => n.kategorie === filterValue) return filtered.filter((n) => !n.isRead && !localReadIds.has(n.id)).length } return ( Aktuelles {FILTERS.map((opt) => { const active = kategorie === opt.value const count = getUnreadCount(opt.value) return ( setKategorie(opt.value)} style={[styles.chip, active && styles.chipActive]} activeOpacity={0.85} > {opt.label} {count > 0 && ( {count} )} ) })} {showSkeleton ? ( {[1,2,3,4].map((i) => )} ) : ( item.id} contentContainerStyle={styles.list} initialNumToRender={10} maxToRenderPerBatch={10} windowSize={5} refreshControl={ } renderItem={({ item }) => ( router.push(`/(app)/news/${item.id}` as never)} /> )} ListEmptyComponent={ } /> )} ) } const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: '#F8FAFC', }, header: { backgroundColor: '#FFFFFF', paddingHorizontal: 20, paddingTop: 14, paddingBottom: 0, }, titleRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14, }, screenTitle: { fontSize: 28, fontWeight: '800', color: '#0F172A', letterSpacing: -0.5, }, filterScroll: { paddingBottom: 14, gap: 8, paddingRight: 20, }, chip: { flexDirection: 'row', alignItems: 'center', gap: 5, paddingHorizontal: 14, paddingVertical: 7, borderRadius: 99, borderWidth: 1, borderColor: '#E2E8F0', backgroundColor: '#FFFFFF', }, chipActive: { backgroundColor: '#003B7E', borderColor: '#003B7E', }, chipLabel: { fontSize: 13, fontWeight: '600', color: '#64748B', }, chipLabelActive: { color: '#FFFFFF', }, chipBadge: { backgroundColor: '#003B7E', borderRadius: 99, minWidth: 18, height: 18, paddingHorizontal: 5, alignItems: 'center', justifyContent: 'center', }, chipBadgeActive: { backgroundColor: '#FFFFFF', }, chipBadgeText: { fontSize: 10, fontWeight: '700', color: '#FFFFFF', }, chipBadgeTextActive: { color: '#003B7E', }, divider: { height: 1, backgroundColor: '#E2E8F0', }, list: { padding: 16, gap: 10, paddingBottom: 30, }, })