194 lines
5.6 KiB
TypeScript

import React from 'react';
import { View, Text, TextInput, TouchableOpacity, Alert } from 'react-native';
import { useAppTheme } from '@theme';
import Svg, { Path } from 'react-native-svg';
import { pick, types, errorCodes } from '@react-native-documents/picker';
import { getStyles } from './KycDocumentCard.styles';
export interface KycDocument {
id: string;
name: string;
idNumber: string;
fileName: string | null;
fileUri?: string | null;
fileType?: string | null;
status?: string;
}
interface KycDocumentCardProps {
document: KycDocument;
index: number;
onUpdate?: (updatedFields: Partial<KycDocument>) => void;
onRemove?: () => void;
readOnly?: boolean;
}
const UploadIcon = ({ size = 18, color = '#666' }) => (
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
<Path
d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"
stroke={color}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</Svg>
);
export const KycDocumentCard: React.FC<KycDocumentCardProps> = ({
document,
index,
onUpdate,
onRemove,
readOnly = false,
}) => {
const { colors } = useAppTheme();
const styles = getStyles(colors);
const handleSelectFile = async () => {
if (readOnly) return;
try {
const [result] = await pick({
type: [types.pdf, types.images],
allowMultiSelection: false,
});
onUpdate?.({
fileName: result.name ?? `document_${Date.now()}`,
fileUri: result.uri,
fileType: result.type ?? 'application/octet-stream',
});
} catch (err: any) {
if (err?.code === errorCodes.OPERATION_CANCELED) {
// User dismissed the picker — no action needed
return;
}
Alert.alert('File Picker Error', err?.message ?? 'Failed to open document picker.');
}
};
const renderStatusBadge = (status?: string) => {
if (!status) return null;
const normalized = status.toLowerCase();
let bgColor = '#FFF9E6';
let textColor = '#B27B00';
let label = status;
if (normalized === 'verified' || normalized === 'approved') {
bgColor = '#E6F4EA';
textColor = '#137333';
label = 'Verified';
} else if (normalized === 'rejected' || normalized === 'failed') {
bgColor = '#FCE8E6';
textColor = '#C5221F';
label = 'Rejected';
} else if (normalized === 'pending' || normalized === 'submitted' || normalized === 'under_review') {
bgColor = '#FFF9E6';
textColor = '#B27B00';
label = 'Pending';
}
return (
<View
style={{
backgroundColor: bgColor,
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 4,
alignSelf: 'center',
}}
>
<Text
style={{
color: textColor,
fontSize: 10,
fontWeight: 'bold',
textTransform: 'uppercase',
}}
>
{label}
</Text>
</View>
);
};
return (
<View style={styles.cardContainer}>
<View style={styles.headerRow}>
<Text style={styles.docNumberText}>Document {index + 1}</Text>
{readOnly && renderStatusBadge(document.status)}
{!readOnly && onRemove && (
<TouchableOpacity
style={styles.removeButton}
onPress={onRemove}
activeOpacity={0.7}
>
<Text style={styles.removeButtonText}>Remove</Text>
</TouchableOpacity>
)}
</View>
{/* Document Name / Type */}
<View style={styles.fieldContainer}>
<Text style={styles.label}>Document Name / Type</Text>
<TextInput
style={styles.input}
placeholder="e.g. National ID or Trade License"
placeholderTextColor={colors.placeholder}
value={document.name}
onChangeText={(text) => onUpdate?.({ name: text })}
autoCapitalize="sentences"
editable={!readOnly}
/>
</View>
{/* Document Identification Number */}
<View style={styles.fieldContainer}>
<Text style={styles.label}>Document Identification Number</Text>
<TextInput
style={styles.input}
placeholder="e.g. GSTIN/Aadhar/ID code"
placeholderTextColor={colors.placeholder}
value={document.idNumber}
onChangeText={(text) => onUpdate?.({ idNumber: text })}
autoCapitalize="characters"
editable={!readOnly}
/>
</View>
{/* Document Attachment */}
<View style={styles.fieldContainer}>
<Text style={styles.label}>Document Attachment File (JPG, PNG, PDF)</Text>
<TouchableOpacity
style={[
styles.uploadBox,
document.fileName ? styles.uploadBoxActive : null,
readOnly ? { borderStyle: 'solid', opacity: 0.8 } : null,
]}
onPress={handleSelectFile}
activeOpacity={0.8}
disabled={readOnly}
>
<Text
style={[
styles.uploadText,
document.fileName ? styles.fileNameText : null,
]}
numberOfLines={1}
>
{document.fileName ? document.fileName : 'SELECT DOCUMENT FILE...'}
</Text>
{!readOnly && <UploadIcon color={document.fileName ? colors.primary : colors.textSecondary} />}
</TouchableOpacity>
{!readOnly && (
<Text style={styles.helperText}>
Supported: pdf, png, jpg, or jpeg under 200kb only.
</Text>
)}
</View>
</View>
);
};
export default KycDocumentCard;