import React, { useMemo, useState } from 'react'; import { FlatList, ScrollView, StyleSheet, View } from 'react-native'; import { useLocalSearchParams, useRouter } from 'expo-router'; import { useQuery } from '@tanstack/react-query'; import { api, DocCategory, Document } from '@/api'; import { useT } from '@/i18n'; import { AppBar } from '@/components/AppBar'; import { Chip, EmptyState, IconButton, Loading } from '@/components/ui'; import { DocumentRow } from '@/components/domain'; import { colors, spacing } from '@/theme'; type StatusFilter = 'all' | 'attention' | 'valid' | 'expiring' | 'expired'; const STATUSES: StatusFilter[] = ['all', 'attention', 'valid', 'expiring', 'expired']; export default function DocumentsScreen() { const { propertyId, category, status: initialStatus } = useLocalSearchParams<{ propertyId: string; category?: string; status?: string; }>(); const pid = Number(propertyId); const router = useRouter(); const t = useT(); // Links can preselect a filter (e.g. the "needs attention" banner). const [status, setStatus] = useState( STATUSES.includes(initialStatus as StatusFilter) ? (initialStatus as StatusFilter) : 'all', ); const docsQuery = useQuery({ queryKey: ['documents', pid], queryFn: () => api.documents.listByProperty(pid) }); const propertyQuery = useQuery({ queryKey: ['property', pid], queryFn: () => api.properties.get(pid) }); const catsQuery = useQuery({ queryKey: ['categories'], queryFn: () => api.reference.categories() }); const categories: DocCategory[] = catsQuery.data ?? []; const catName = (slug: string) => categories.find((c) => c.slug === slug)?.name ?? slug; const inCategory = useMemo( () => ((docsQuery.data ?? []) as Document[]).filter((d) => !category || d.category === category), [docsQuery.data, category], ); const counts = useMemo(() => { const c = { all: inCategory.length, attention: 0, valid: 0, expiring: 0, expired: 0 }; for (const d of inCategory) { if (d.expiryStatus === 'valid') c.valid += 1; else if (d.expiryStatus === 'expiring') c.expiring += 1; else if (d.expiryStatus === 'expired') c.expired += 1; } c.attention = c.expiring + c.expired; return c; }, [inCategory]); const visible = useMemo(() => { if (status === 'all') return inCategory; if (status === 'attention') { return inCategory.filter((d) => d.expiryStatus === 'expiring' || d.expiryStatus === 'expired'); } return inCategory.filter((d) => d.expiryStatus === status); }, [inCategory, status]); const title = category ? catName(category) : t('documents.allTitle'); const subtitle = `${propertyQuery.data?.name ?? ''} ยท ${t('properties.docCount', { count: inCategory.length })}`; return ( router.push('/search')} />} /> setStatus('all')} /> setStatus('attention')} /> setStatus('valid')} /> setStatus('expiring')} /> setStatus('expired')} /> {docsQuery.isLoading ? ( ) : ( String(d.id)} contentContainerStyle={styles.list} renderItem={({ item }) => ( router.push(`/document/${item.id}?propertyId=${pid}`)} /> )} ListEmptyComponent={ } /> )} ); } const styles = StyleSheet.create({ chips: { gap: 8, paddingHorizontal: spacing[4], paddingVertical: spacing[2] }, list: { padding: spacing[4], paddingTop: spacing[2], paddingBottom: spacing[9] }, });