import { useTheme } from '@/components/ThemeContext'; import { Ionicons } from '@expo/vector-icons'; import { BottomSheetBackdrop, BottomSheetModal, BottomSheetScrollView } from '@gorhom/bottom-sheet'; import { useQuery } from '@tanstack/react-query'; import { ResizeMode, Video } from 'expo-av'; import { LinearGradient } from 'expo-linear-gradient'; import { Package, PlayCircle } from 'lucide-react-native'; import React, { useCallback, useRef, useState } from 'react'; import { Dimensions, Image, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'; import { announcement_api } from '../lib/api'; import { AnnouncementListBodyRes } from '../lib/type'; const { width, height } = Dimensions.get('window'); const cardWidth = (width - 44) / 2; export default function AnnouncementCard({ announcement, }: { announcement: AnnouncementListBodyRes; }) { const [sheetOpen, setSheetOpen] = useState(false); const bottomSheetRef = useRef(null); const file = announcement.files?.[0]?.file; const isVideo = file?.endsWith('.mp4'); const { isDark } = useTheme(); const theme = { cardBg: isDark ? '#1e293b' : '#ffffff', cardBorder: isDark ? '#334155' : '#e2e8f0', mediaBg: isDark ? '#0f172a' : '#f1f5f9', text: isDark ? '#f1f5f9' : '#0f172a', textSecondary: isDark ? '#cbd5e1' : '#64748b', textTertiary: isDark ? '#94a3b8' : '#94a3b8', sheetBg: isDark ? '#0f172a' : '#ffffff', indicator: isDark ? '#94a3b8' : '#cbd5e1', shadow: isDark ? '#000' : '#64748b', error: '#ef4444', placeholder: isDark ? '#cbd5e1' : '#94a3b8', }; const renderBackdrop = useCallback( (props: any) => ( ), [] ); const openSheet = () => { bottomSheetRef.current?.present(); setSheetOpen(true); }; const { data, isLoading, isError } = useQuery({ queryKey: ['announcement_detail', announcement.id], queryFn: () => announcement_api.detail(announcement.id), enabled: sheetOpen, }); const detail = data?.data?.data; const files = detail?.files || []; return ( <> {/* Card */} {file ? ( <> {isVideo && ( )} ) : ( )} {announcement.title} {announcement.description} {new Date(announcement.created_at).toLocaleDateString('uz-UZ')} {isLoading && ( Yuklanmoqda... )} {isError && Xatolik yuz berdi} {detail && ( <> {/* Media carousel */} {files.length > 0 && ( {files.map((f) => { const fileIsVideo = f.file?.endsWith('.mp4'); return ( {fileIsVideo ? ( ); })} )} {/* Title */} {detail.title} {/* Meta */} {new Date(detail.created_at).toLocaleDateString()} {detail.total_view_count} ko'rildi {/* Description */} {detail.description} )} ); } const styles = StyleSheet.create({ card: { width: cardWidth, borderRadius: 16, overflow: 'hidden', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 8, elevation: 3, marginBottom: 16, }, mediaContainer: { width: '100%', height: 160, position: 'relative', }, image: { width: '100%', height: '100%' }, videoIconOverlay: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.25)', }, placeholder: { flex: 1, alignItems: 'center', justifyContent: 'center' }, gradient: { position: 'absolute', bottom: 0, left: 0, right: 0, height: 60 }, content: { padding: 12 }, title: { fontSize: 15, fontWeight: '700', marginBottom: 4 }, desc: { fontSize: 13, marginBottom: 6 }, footer: { flexDirection: 'row', alignItems: 'center', gap: 4 }, date: { fontSize: 12 }, // BottomSheet styles sheetContent: { padding: 20, gap: 12 }, carousel: { marginBottom: 12 }, sheetMediaContainer: { width: width - 40, height: 200, marginRight: 12 }, media: { width: '100%', height: '100%', borderRadius: 16 }, sheetTitle: { fontSize: 18, fontWeight: '700' }, metaRow: { flexDirection: 'row', gap: 16, marginVertical: 8 }, metaItem: { flexDirection: 'row', alignItems: 'center', gap: 6 }, metaText: { fontSize: 14 }, sheetDesc: { fontSize: 14, lineHeight: 20 }, loading: { fontSize: 16 }, error: { fontSize: 16 }, });