Files
mariani_mobile/components/AddDocumentModal.tsx
leonardo 7c8ef45e5a feat: Update assets and improve code comments across multiple components
- Updated favicon and various image assets.
- Enhanced comments.
- Adjusted styles and functionality in several components for improved user experience.
- Updated package-lock.json to reflect dependency updates.
2026-02-06 12:56:34 +01:00

176 lines
8.0 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Modal, Text, TouchableOpacity, View, TextInput, ActivityIndicator } from 'react-native';
import { X, Upload, FileText, Trash2 } from 'lucide-react-native';
import * as DocumentPicker from 'expo-document-picker'; // TODO: Test on iOS environment
interface AddDocumentModalProps {
visible: boolean;
onClose: () => void;
onUpload: (file: DocumentPicker.DocumentPickerAsset, customTitle?: string) => Promise<void>;
isUploading?: boolean;
}
export default function AddDocumentModal({ visible, onClose, onUpload, isUploading = false }: AddDocumentModalProps) {
const [selectedFile, setSelectedFile] = useState<DocumentPicker.DocumentPickerAsset | null>(null);
const [customTitle, setCustomTitle] = useState('');
const [fileExtension, setFileExtension] = useState('');
// Reset of state when modal is closed
useEffect(() => {
if (!visible) {
setSelectedFile(null);
setCustomTitle('');
setFileExtension('');
}
}, [visible]);
// TODO: Need to handle multiple file selection?
const pickDocument = async () => {
try {
const result = await DocumentPicker.getDocumentAsync({
type: '*/*', // You can limit to 'application/pdf', 'image/*', etc.
copyToCacheDirectory: true,
});
if (result.canceled) return;
const asset = result.assets[0];
setSelectedFile(asset);
const lastDotIndex = asset.name.lastIndexOf('.');
if (lastDotIndex !== -1) {
setCustomTitle(asset.name.substring(0, lastDotIndex));
setFileExtension(asset.name.substring(lastDotIndex));
} else {
setCustomTitle(asset.name);
setFileExtension('');
}
} catch (err) {
console.error("Errore selezione file:", err);
}
};
const handleUpload = () => {
if (!selectedFile) return;
const fullTitle = customTitle ? `${customTitle}${fileExtension}` : selectedFile.name;
// If customTitle is empty, we use the original file name
onUpload(selectedFile, fullTitle);
};
const removeFile = () => {
setSelectedFile(null);
setCustomTitle('');
setFileExtension('');
};
// Format file size in a human-readable format
const formatSize = (size?: number) => {
if (!size) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(size) / Math.log(k));
return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
return (
<Modal
animationType="fade"
transparent={true}
visible={visible}
onRequestClose={onClose}
>
<View className="flex-1 justify-center items-center bg-black/50 px-6">
<View className="bg-white w-full rounded-[2rem] p-6 shadow-xl">
{/* Header */}
<View className="flex-row justify-between items-center mb-6">
<Text className="text-xl font-bold text-gray-800">Carica Documento</Text>
<TouchableOpacity onPress={onClose} className="p-2 bg-gray-50 rounded-full">
<X size={20} color="#374151" />
</TouchableOpacity>
</View>
<View className="gap-5">
{/* File Selection Area */}
{!selectedFile ? (
<TouchableOpacity
onPress={pickDocument}
className="h-64 border-2 border-dashed border-gray-300 rounded-2xl items-center justify-center bg-gray-50 active:bg-gray-100"
>
<View className="bg-white p-4 rounded-full shadow-sm mb-3">
<Upload size={32} color="#099499" />
</View>
<Text className="text-lg text-gray-600 font-medium">Tocca per selezionare un file</Text>
<Text className="text-gray-400 text-sm mt-1">PDF, Immagini, Word</Text>
</TouchableOpacity>
) : (
// Selected File View
<View className="bg-[#E6F4F4] p-4 rounded-2xl border border-[#099499]/20 flex-row items-center gap-4">
<View className="bg-white p-3 rounded-xl">
<FileText size={24} color="#099499" />
</View>
<View className="flex-1">
<Text className="text-gray-800 font-bold text-base" numberOfLines={1}>
{selectedFile.name}
</Text>
<Text className="text-gray-500 text-sm">
{formatSize(selectedFile.size)}
</Text>
</View>
<TouchableOpacity onPress={removeFile} className="p-2 bg-white rounded-lg">
<Trash2 size={18} color="#ef4444" />
</TouchableOpacity>
</View>
)}
{/* Rename field (Visible only if a file is selected) */}
{selectedFile && (
<View>
<Text className="text-gray-700 font-bold mb-2 ml-1 text-sm">Rinomina File</Text>
<View className="flex-row items-center w-full bg-gray-50 rounded-xl border border-gray-200 overflow-hidden">
<TextInput
value={customTitle}
onChangeText={setCustomTitle}
placeholder="Nome del file"
className="flex-1 p-4 text-gray-800 text-base"
/>
<Text className="px-4 text-gray-400 font-medium text-base flex items-center justify-center">
{fileExtension}
</Text>
</View>
</View>
)}
</View>
{/* Footer Buttons */}
<View className="flex-row gap-3 mt-8">
<TouchableOpacity
onPress={onClose}
className="flex-1 py-4 bg-gray-100 rounded-xl items-center"
disabled={isUploading}
>
<Text className="text-gray-600 font-bold text-base">Annulla</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={handleUpload}
disabled={!selectedFile || isUploading}
className={`flex-1 py-4 rounded-xl items-center flex-row justify-center gap-2 ${!selectedFile ? 'bg-gray-300' : 'bg-[#099499]'}`}
>
{isUploading ? (
<ActivityIndicator color="white" />
) : (
<>
<Upload size={20} color="white" />
<Text className="text-white font-bold text-base">Carica</Text>
</>
)}
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
);
}