Files
info-target-mobile/screens/announcements/ui/AnnouncementDetail.tsx
Samandar Turgunboyev 124798419b fitst commit
2026-01-28 18:26:50 +05:00

126 lines
4.5 KiB
TypeScript

import { Ionicons } from '@expo/vector-icons';
import BottomSheet, { BottomSheetScrollView } from '@gorhom/bottom-sheet';
import { useQuery } from '@tanstack/react-query';
import { ResizeMode, Video } from 'expo-av';
import React, { useMemo, useRef } from 'react';
import { Dimensions, Image, ScrollView, StyleSheet, Text, View } from 'react-native';
import { announcement_api } from '../lib/api';
const { width, height } = Dimensions.get('window');
export default function AnnouncementDetailSheet({ id }: { id: number }) {
const bottomSheetRef = useRef<BottomSheet>(null);
// Sheet sizes
const snapPoints = useMemo(() => [height * 0.3, height * 0.7], []);
const { data, isLoading, isError } = useQuery({
queryKey: ['announcement_detail', id],
queryFn: () => announcement_api.detail(id),
enabled: !!id,
});
const announcement = data?.data?.data;
const files = announcement?.files || [];
return (
<BottomSheet
ref={bottomSheetRef}
index={0}
snapPoints={snapPoints}
handleIndicatorStyle={{ backgroundColor: '#94a3b8' }}
backgroundStyle={{ backgroundColor: '#0f172a', borderRadius: 24 }}
>
<BottomSheetScrollView contentContainerStyle={styles.contentContainer}>
{isLoading && <Text style={styles.loading}>Yuklanmoqda...</Text>}
{isError && <Text style={styles.error}>Xatolik yuz berdi</Text>}
{announcement && (
<>
{/* Carousel */}
{files.length > 0 && (
<ScrollView
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
style={styles.carousel}
>
{files.map((file) => {
const isVideo = file.file?.endsWith('.mp4');
return (
<View key={file.id} style={styles.mediaContainer}>
{isVideo ? (
<Video
source={{ uri: file.file }}
style={styles.media}
useNativeControls
resizeMode={ResizeMode.CONTAIN}
/>
) : (
<Image source={{ uri: file.file }} style={styles.media} />
)}
</View>
);
})}
</ScrollView>
)}
{/* Title */}
<Text style={styles.title}>{announcement.title}</Text>
{/* Meta */}
<View style={styles.metaRow}>
<View style={styles.metaItem}>
<Ionicons name="calendar-outline" size={16} color="#94a3b8" />
<Text style={styles.metaText}>
{new Date(announcement.created_at).toLocaleDateString()}
</Text>
</View>
<View style={styles.metaItem}>
<Ionicons name="eye-outline" size={16} color="#94a3b8" />
<Text style={styles.metaText}>{announcement.total_view_count} ko'rildi</Text>
</View>
</View>
{/* Status */}
{/* <View style={styles.statusBadge}>
<Text style={styles.statusText}>
{announcement.status === 'pending' && 'Kutilmoqda'}
{announcement.status === 'paid' && "To'langan"}
{announcement.status === 'verified' && 'Tasdiqlangan'}
{announcement.status === 'canceled' && 'Bekor qilingan'}
</Text>
</View> */}
{/* Description */}
<Text style={styles.desc}>{announcement.description}</Text>
</>
)}
</BottomSheetScrollView>
</BottomSheet>
);
}
const styles = StyleSheet.create({
contentContainer: { padding: 20, gap: 12 },
carousel: { marginBottom: 12 },
mediaContainer: { width: width - 40, height: 200, marginRight: 12 },
media: { width: '100%', height: '100%', borderRadius: 16 },
title: { fontSize: 18, fontWeight: '700', color: '#f1f5f9' },
metaRow: { flexDirection: 'row', gap: 16, marginVertical: 8 },
metaItem: { flexDirection: 'row', alignItems: 'center', gap: 6 },
metaText: { color: '#94a3b8', fontSize: 14 },
statusBadge: {
alignSelf: 'flex-start',
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 12,
backgroundColor: '#2563eb',
marginBottom: 12,
},
statusText: { color: '#f1f5f9', fontWeight: '600' },
desc: { color: '#cbd5f5', fontSize: 14, lineHeight: 20 },
loading: { color: '#cbd5f5', fontSize: 16 },
error: { color: '#ef4444', fontSize: 16 },
});