First commit of the new app
This commit is contained in:
98
assets/components/reserva/DocumentoRow.tsx
Normal file
98
assets/components/reserva/DocumentoRow.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { LoadingSpinner } from '@/assets/components/LoadingSpinner';
|
||||
import { colors } from '@/assets/styles/colors';
|
||||
import { downloadDocumento, getLocalDocumentUri } from '@/assets/services/documentSync';
|
||||
import { Documento } from '@/assets/types';
|
||||
import styles from '@/styles/screens/reserva/detail.styles';
|
||||
import { FontAwesome } from '@expo/vector-icons';
|
||||
import CircleCheckIcon from '@/assets/icons/circle-check-solid.svg';
|
||||
import * as Sharing from 'expo-sharing';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Alert, Pressable, Text, View } from 'react-native';
|
||||
|
||||
type Props = {
|
||||
documento: Documento;
|
||||
isLast: boolean;
|
||||
};
|
||||
|
||||
const getDocumentExt = (path: string) => {
|
||||
const ext = path.split('.').pop()?.toUpperCase() ?? 'DOC';
|
||||
return ext.length > 4 ? 'DOC' : ext;
|
||||
};
|
||||
|
||||
export function DocumentoRow({ documento, isLast }: Props) {
|
||||
const [isDownloading, setIsDownloading] = useState(false);
|
||||
const [isDownloaded, setIsDownloaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!documento.idDocumento || !documento.caminhoFicheiro) return;
|
||||
getLocalDocumentUri(documento.idDocumento, documento.caminhoFicheiro).then((uri) => {
|
||||
setIsDownloaded(!!uri);
|
||||
});
|
||||
}, [documento.idDocumento, documento.caminhoFicheiro]);
|
||||
|
||||
const fileName =
|
||||
documento.nome || documento.caminhoFicheiro.split('/').pop() || '---';
|
||||
|
||||
const openLocalFile = async (uri: string) => {
|
||||
const canShare = await Sharing.isAvailableAsync();
|
||||
if (canShare) {
|
||||
await Sharing.shareAsync(uri, { UTI: '.pdf', mimeType: 'application/pdf' });
|
||||
} else {
|
||||
Alert.alert('Erro', 'Não é possível abrir este ficheiro neste dispositivo.');
|
||||
}
|
||||
};
|
||||
|
||||
const handlePress = async () => {
|
||||
if (!documento.idDocumento || !documento.caminhoFicheiro) return;
|
||||
|
||||
setIsDownloading(true);
|
||||
try {
|
||||
const localUri = await getLocalDocumentUri(documento.idDocumento, documento.caminhoFicheiro);
|
||||
|
||||
if (localUri) {
|
||||
await openLocalFile(localUri);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ficheiro não está local — fazer download agora
|
||||
const uri = await downloadDocumento({
|
||||
idDocumento: documento.idDocumento,
|
||||
caminhoFicheiro: documento.caminhoFicheiro,
|
||||
checksum: documento.checksum ?? '',
|
||||
nome: documento.nome,
|
||||
});
|
||||
|
||||
if (uri) {
|
||||
setIsDownloaded(true);
|
||||
await openLocalFile(uri);
|
||||
} else {
|
||||
Alert.alert('Erro', 'Não foi possível descarregar o documento. Verifica a tua ligação à internet.');
|
||||
}
|
||||
} finally {
|
||||
setIsDownloading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
onPress={handlePress}
|
||||
disabled={isDownloading}
|
||||
style={[styles.documentoRow, isLast && styles.documentoRowLast]}>
|
||||
<View style={styles.documentoBadge}>
|
||||
<Text style={styles.documentoBadgeText}>
|
||||
{getDocumentExt(documento.caminhoFicheiro)}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.documentoName} numberOfLines={1}>
|
||||
{fileName}
|
||||
</Text>
|
||||
{isDownloading ? (
|
||||
<LoadingSpinner size="small" />
|
||||
) : isDownloaded ? (
|
||||
<CircleCheckIcon width={16} height={16} fill="#13AE45" />
|
||||
) : (
|
||||
<FontAwesome name="download" size={16} color={colors.vermelho} />
|
||||
)}
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user