269 lines
8.7 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import {
View,
Text,
ScrollView,
TouchableOpacity,
Modal,
Image,
ActivityIndicator,
SafeAreaView,
} from 'react-native';
import Pdf from 'react-native-pdf';
import { useAppTheme } from '@theme';
import { ScreenHeader } from '@components';
import { ClipboardIcon, CloseIcon, ChevronRightIcon } from '@icons';
import { useNavigation } from '@react-navigation/native';
import { getFullUrl, isPdf } from '@utils/helper';
import { getStyles } from './documentsScreen.styles';
import { KycDocUploadResponseDocument } from '@interfaces';
import { formatDate } from '@utils/formatters';
import { useAppDispatch, useAppSelector } from '@store';
import { fetchMyKyc } from '../kycScreen';
export const DocumentsScreen: React.FC = () => {
const { colors } = useAppTheme();
const styles = getStyles(colors);
const navigation = useNavigation();
const dispatch = useAppDispatch();
const [selectedDoc, setSelectedDoc] =
useState<KycDocUploadResponseDocument | null>(null);
const [isModalLoading, setIsModalLoading] = useState<boolean>(true);
const { myKycResponse } = useAppSelector(state => state.kyc);
useEffect(() => {
dispatch(fetchMyKyc());
}, []);
const getStatusBadgeConfig = (status: string) => {
switch (status?.toUpperCase()) {
case 'APPROVED':
case 'VERIFIED':
return {
bg: colors.successLight,
text: colors.success,
label: 'APPROVED',
};
case 'PENDING':
return {
bg: colors.warningLight,
text: colors.warning,
label: 'PENDING',
};
case 'REJECTED':
return {
bg: colors.errorLight,
text: colors.error,
label: 'REJECTED',
};
default:
return {
bg: colors.primaryLight,
text: colors.primary,
label: status?.toUpperCase() || 'ACTIVE',
};
}
};
const handleOpenDocModal = (doc: KycDocUploadResponseDocument) => {
setIsModalLoading(true);
setSelectedDoc(doc);
};
const approvedCount = myKycResponse?.documents?.filter(
d => d.status === 'APPROVED',
).length;
return (
<View style={styles.container}>
{/* Screen Header */}
<ScreenHeader
title="My Documents"
showBack={true}
onBack={() => navigation.goBack()}
/>
<ScrollView
contentContainerStyle={styles.scrollContainer}
showsVerticalScrollIndicator={false}
>
{/* Document Status Overview Banner */}
<View style={styles.summaryCard}>
<View style={styles.summaryLeft}>
<Text style={styles.summaryTitle}>Document Verification</Text>
<Text style={styles.summarySub}>
{approvedCount} of {myKycResponse?.documents?.length} Documents
Verified
</Text>
</View>
<View style={styles.summaryBadge}>
<Text style={styles.summaryBadgeText}>
{approvedCount === myKycResponse?.documents?.length
? 'VERIFIED'
: 'PENDING'}
</Text>
</View>
</View>
<Text style={styles.sectionTitle}>Uploaded Documents</Text>
{myKycResponse?.documents?.length === 0 ? (
<View style={styles.emptyContainer}>
<ClipboardIcon size={48} color={colors.placeholder} />
<Text style={styles.emptyTitle}>No Documents Found</Text>
<Text style={styles.emptySub}>
Your uploaded documents will appear here.
</Text>
</View>
) : (
myKycResponse?.documents?.map(doc => {
const statusConfig = getStatusBadgeConfig(doc.status);
const formattedDocName =
doc.documentType === 'Pan' ? 'PAN Card' : doc.documentType;
return (
<TouchableOpacity
key={doc.id}
style={styles.docCard}
activeOpacity={0.7}
onPress={() => handleOpenDocModal(doc)}
>
{/* Header Row */}
<View style={styles.cardHeader}>
<View style={styles.cardHeaderLeft}>
<View style={styles.iconContainer}>
<ClipboardIcon size={22} color={colors.primary} />
</View>
<View style={styles.docTypeContainer}>
<Text style={styles.docTitle} numberOfLines={1}>
{formattedDocName}
</Text>
<Text style={styles.docNumber}>
Doc #: {doc.documentNumber}
</Text>
</View>
</View>
<View
style={[
styles.statusBadge,
{ backgroundColor: statusConfig.bg },
]}
>
<Text
style={[styles.statusText, { color: statusConfig.text }]}
>
{statusConfig.label}
</Text>
</View>
</View>
{/* Details Section */}
<View style={styles.detailsRow}>
<View style={styles.detailItem}>
<Text style={styles.detailLabel}>Uploaded On</Text>
<Text style={styles.detailValue}>
{formatDate(doc.createdAt)}
</Text>
</View>
{doc.verifiedAt && (
<View style={styles.detailItem}>
<Text style={styles.detailLabel}>Verified On</Text>
<Text style={styles.detailValue}>
{formatDate(doc.verifiedAt)}
</Text>
</View>
)}
</View>
<View style={styles.divider} />
{/* View Button Footer */}
<View style={styles.viewButton}>
<Text style={styles.viewButtonText}>View Document</Text>
<ChevronRightIcon size={16} color={colors.primary} />
</View>
</TouchableOpacity>
);
})
)}
</ScrollView>
{/* Full Screen View Modal */}
<Modal
visible={!!selectedDoc}
animationType="slide"
statusBarTranslucent
onRequestClose={() => setSelectedDoc(null)}
>
<SafeAreaView style={styles.modalContainer}>
{/* Modal Header */}
<View style={styles.modalHeader}>
<View style={styles.modalHeaderInfo}>
<Text style={styles.modalTitle} numberOfLines={1}>
{selectedDoc?.documentType === 'Pan'
? 'PAN Card'
: selectedDoc?.documentType}{' '}
Preview
</Text>
<Text style={styles.modalSubtitle} numberOfLines={1}>
{selectedDoc?.fileName}
</Text>
</View>
<TouchableOpacity
style={styles.closeButton}
activeOpacity={0.7}
onPress={() => setSelectedDoc(null)}
>
<CloseIcon size={20} color={colors.text} />
</TouchableOpacity>
</View>
{/* Modal Body / Viewer */}
<View style={styles.viewerContainer}>
{isModalLoading && (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={colors.primary} />
<Text style={styles.loadingText}>Loading file preview...</Text>
</View>
)}
{selectedDoc &&
isPdf(selectedDoc.fileName || selectedDoc.fileUrl) ? (
<Pdf
trustAllCerts={false}
source={{
uri: getFullUrl(selectedDoc.fileUrl),
cache: true,
}}
onLoadComplete={() => setIsModalLoading(false)}
onError={error => {
setIsModalLoading(false);
console.log('PDF Load Error:', error);
}}
style={styles.pdfViewer}
/>
) : (
selectedDoc && (
<Image
source={{ uri: getFullUrl(selectedDoc.fileUrl) }}
style={styles.imageViewer}
resizeMode="contain"
onLoadStart={() => setIsModalLoading(true)}
onLoadEnd={() => setIsModalLoading(false)}
onError={() => setIsModalLoading(false)}
/>
)
)}
</View>
</SafeAreaView>
</Modal>
</View>
);
};
export default DocumentsScreen;