- Improved error message handling in LoginScreen for invalid credentials. - Added new images: mariani-icon.png and mariani-splash.png. - Updated AddDocumentModal to handle file extensions and improve UI. - Enhanced CalendarWidget to support month change callbacks. - Introduced NfcScanModal for NFC tag scanning with animations. - Revamped QrScanModal to utilize camera for QR code scanning. - Removed mock data from data.ts and streamlined Office data. - Updated package dependencies for expo-camera and react-native-nfc-manager. - Added utility function to parse seconds to time format. - Refactored document upload logic to use FormData for server uploads.
101 lines
4.2 KiB
TypeScript
101 lines
4.2 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { View, Text, Modal, TouchableOpacity, Vibration, StyleSheet } from 'react-native';
|
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
import { CameraView, useCameraPermissions } from 'expo-camera';
|
|
import { X, ScanLine } from 'lucide-react-native';
|
|
|
|
interface QrScanModalProps {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
onScan: (data: string) => void;
|
|
}
|
|
|
|
export default function QrScanModal({ visible, onClose, onScan }: QrScanModalProps) {
|
|
const [permission, requestPermission] = useCameraPermissions();
|
|
const [scanned, setScanned] = useState(false);
|
|
|
|
// Gestione Permessi e Reset Stato
|
|
useEffect(() => {
|
|
if (visible) {
|
|
setScanned(false);
|
|
if (permission && !permission.granted && permission.canAskAgain) {
|
|
requestPermission();
|
|
}
|
|
}
|
|
}, [visible, permission]);
|
|
|
|
const handleBarCodeScanned = ({ type, data }: { type: string; data: string }) => {
|
|
if (scanned) return;
|
|
setScanned(true);
|
|
Vibration.vibrate();
|
|
console.log(`Bar code with type ${type} and data ${data} has been scanned!`);
|
|
onScan(data);
|
|
onClose();
|
|
};
|
|
|
|
if (!permission) {
|
|
return <View />;
|
|
}
|
|
|
|
if (!permission.granted && visible) {
|
|
requestPermission();
|
|
}
|
|
|
|
return (
|
|
<Modal
|
|
visible={visible}
|
|
animationType="slide"
|
|
presentationStyle="fullScreen"
|
|
onRequestClose={onClose}
|
|
>
|
|
<View className="flex-1 bg-black">
|
|
{/* Camera Full Screen */}
|
|
<CameraView
|
|
style={StyleSheet.absoluteFillObject}
|
|
facing="back"
|
|
onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
|
|
barcodeScannerSettings={{
|
|
barcodeTypes: ["qr"],
|
|
}}
|
|
/>
|
|
|
|
{/* Overlay Oscuro con "buco" trasparente (Simulato visivamente con bordi o opacity) */}
|
|
<View className="flex-1">
|
|
|
|
{/* Header Overlay */}
|
|
<SafeAreaView className="flex-1 bg-black/60 items-center pt-8">
|
|
<Text className="text-white text-xl font-bold">Scansiona QR Code</Text>
|
|
<Text className="text-gray-300 text-base mt-1">Inquadra il codice nel riquadro</Text>
|
|
</SafeAreaView>
|
|
|
|
{/* Area Centrale (Trasparente per la camera) */}
|
|
<View className="flex-row h-[400px]">
|
|
<View className="flex-1 bg-black/60" />
|
|
<View className="w-[400px] h-[400px] border-2 border-[#099499] bg-transparent relative justify-center items-center">
|
|
{/* Angoli decorativi */}
|
|
<View className="absolute top-0 left-0 w-6 h-6 border-l-4 border-t-4 border-[#099499]" />
|
|
<View className="absolute top-0 right-0 w-6 h-6 border-r-4 border-t-4 border-[#099499]" />
|
|
<View className="absolute bottom-0 left-0 w-6 h-6 border-l-4 border-b-4 border-[#099499]" />
|
|
<View className="absolute bottom-0 right-0 w-6 h-6 border-r-4 border-b-4 border-[#099499]" />
|
|
|
|
{/* Linea scansione animata o icona */}
|
|
{!scanned && <ScanLine color="#099499" size={40} className="opacity-50" />}
|
|
</View>
|
|
<View className="flex-1 bg-black/60" />
|
|
</View>
|
|
|
|
{/* Footer Overlay */}
|
|
<View className="flex-1 bg-black/60 items-center justify-end pb-12 px-6">
|
|
<TouchableOpacity
|
|
onPress={onClose}
|
|
className="bg-white/20 p-4 rounded-full"
|
|
>
|
|
<X color="white" size={32} />
|
|
</TouchableOpacity>
|
|
<Text className="text-white mt-4 font-medium">Chiudi</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</Modal>
|
|
);
|
|
} |