feat: add confirmation modal for file deletion and improve error handling
This commit is contained in:
+77
-32
@@ -3,7 +3,7 @@ import React, { useState } from "react";
|
|||||||
import ThemedBackground from "@/src/components/themed/ThemedBackground";
|
import ThemedBackground from "@/src/components/themed/ThemedBackground";
|
||||||
import CustomImagePicker from "@/src/components/ImagePicker";
|
import CustomImagePicker from "@/src/components/ImagePicker";
|
||||||
import { ImagePickerSuccessResult } from "expo-image-picker";
|
import { ImagePickerSuccessResult } from "expo-image-picker";
|
||||||
import { View, StyleSheet, Alert, FlatList, Text, ActivityIndicator, TouchableOpacity, Linking, Platform } from "react-native";
|
import { View, StyleSheet, ActivityIndicator, FlatList, Text, TouchableOpacity, Linking, Modal } from "react-native";
|
||||||
import { S3File, RestService } from "@/src/services/RestService";
|
import { S3File, RestService } from "@/src/services/RestService";
|
||||||
import ThemedButton from "@/src/components/themed/ThemedButton";
|
import ThemedButton from "@/src/components/themed/ThemedButton";
|
||||||
import { useTheme } from "@/src/context/ThemeProvider";
|
import { useTheme } from "@/src/context/ThemeProvider";
|
||||||
@@ -16,6 +16,7 @@ export default function ImageScreen() {
|
|||||||
const [files, setFiles] = useState<S3File[]>([]);
|
const [files, setFiles] = useState<S3File[]>([]);
|
||||||
const [showFiles, setShowFiles] = useState(false);
|
const [showFiles, setShowFiles] = useState(false);
|
||||||
const [loadingFiles, setLoadingFiles] = useState(false);
|
const [loadingFiles, setLoadingFiles] = useState(false);
|
||||||
|
const [deletingFile, setDeletingFile] = useState<string | null>(null);
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
|
|
||||||
const { primary, onSurface, outline, error } = theme.colors;
|
const { primary, onSurface, outline, error } = theme.colors;
|
||||||
@@ -28,11 +29,10 @@ export default function ImageScreen() {
|
|||||||
setFiles(response.data);
|
setFiles(response.data);
|
||||||
setShowFiles(true);
|
setShowFiles(true);
|
||||||
} else {
|
} else {
|
||||||
Alert.alert("Fehler", "Dateien konnten nicht abgerufen werden");
|
console.error("Fehler beim Abrufen der Dateien");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Fehler beim Abrufen der Dateien:", error);
|
console.error("Fehler beim Abrufen der Dateien:", error);
|
||||||
Alert.alert("Fehler", "Dateien konnten nicht abgerufen werden");
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoadingFiles(false);
|
setLoadingFiles(false);
|
||||||
}
|
}
|
||||||
@@ -60,14 +60,13 @@ export default function ImageScreen() {
|
|||||||
const response = await new RestService(token).uploadFile(formData);
|
const response = await new RestService(token).uploadFile(formData);
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
Alert.alert("Erfolg", "Datei erfolgreich hochgeladen");
|
console.log("Datei erfolgreich hochgeladen");
|
||||||
fetchStoredFiles();
|
fetchStoredFiles();
|
||||||
} else {
|
} else {
|
||||||
Alert.alert("Fehler", "Upload fehlgeschlagen");
|
console.error("Upload fehlgeschlagen");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Fehler beim Hochladen der Datei:", error);
|
console.error("Fehler beim Hochladen der Datei:", error);
|
||||||
Alert.alert("Fehler", "Upload fehlgeschlagen");
|
|
||||||
} finally {
|
} finally {
|
||||||
setUploading(false);
|
setUploading(false);
|
||||||
}
|
}
|
||||||
@@ -76,7 +75,6 @@ export default function ImageScreen() {
|
|||||||
|
|
||||||
const onFailure = (error: Error) => {
|
const onFailure = (error: Error) => {
|
||||||
console.error("Error picking image", error);
|
console.error("Error picking image", error);
|
||||||
Alert.alert("Fehler", "Bildauswahl fehlgeschlagen");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCanceled = () => {
|
const onCanceled = () => {
|
||||||
@@ -116,47 +114,40 @@ export default function ImageScreen() {
|
|||||||
if (canOpen) {
|
if (canOpen) {
|
||||||
await Linking.openURL(url);
|
await Linking.openURL(url);
|
||||||
} else {
|
} else {
|
||||||
Alert.alert("Fehler", "Diese URL kann nicht geöffnet werden");
|
console.error("Diese URL kann nicht geöffnet werden:", url);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Alert.alert("Fehler", "Datei-URL konnte nicht abgerufen werden");
|
console.error("Datei-URL konnte nicht abgerufen werden");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Fehler beim Abrufen der Datei-URL:", error);
|
console.error("Fehler beim Abrufen der Datei-URL:", error);
|
||||||
Alert.alert("Fehler", "Datei-URL konnte nicht abgerufen werden");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteFile = async (objectKey: string) => {
|
const deleteFile = async (objectKey: string) => {
|
||||||
Alert.alert(
|
|
||||||
"Datei löschen",
|
|
||||||
"Möchtest du diese Datei wirklich löschen?",
|
|
||||||
[
|
|
||||||
{
|
|
||||||
text: "Abbrechen",
|
|
||||||
style: "cancel"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Löschen",
|
|
||||||
style: "destructive",
|
|
||||||
onPress: async () => {
|
|
||||||
try {
|
try {
|
||||||
const response = await new RestService(token).deleteFile(objectKey);
|
const response = await new RestService(token).deleteFile(objectKey);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
Alert.alert("Erfolg", "Datei erfolgreich gelöscht");
|
console.log("Datei erfolgreich gelöscht");
|
||||||
// Liste aktualisieren
|
|
||||||
fetchStoredFiles();
|
fetchStoredFiles();
|
||||||
} else {
|
} else {
|
||||||
Alert.alert("Fehler", "Datei konnte nicht gelöscht werden");
|
console.error("Datei konnte nicht gelöscht werden");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Fehler beim Löschen der Datei:", error);
|
console.error("Fehler beim Löschen der Datei:", error);
|
||||||
Alert.alert("Fehler", "Datei konnte nicht gelöscht werden");
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
]
|
const confirmDeleteFile = (objectKey: string) => {
|
||||||
);
|
setDeletingFile(objectKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelDelete = () => {
|
||||||
|
setDeletingFile(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmCancelDelete = () => {
|
||||||
|
setDeletingFile(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -223,7 +214,7 @@ export default function ImageScreen() {
|
|||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[styles.fileButton, { backgroundColor: error }]}
|
style={[styles.fileButton, { backgroundColor: error }]}
|
||||||
onPress={() => deleteFile(item.key)}
|
onPress={() => confirmDeleteFile(item.key)}
|
||||||
>
|
>
|
||||||
<MaterialIcons name="delete" size={24} color="white" />
|
<MaterialIcons name="delete" size={24} color="white" />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
@@ -238,6 +229,38 @@ export default function ImageScreen() {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
animationType="slide"
|
||||||
|
transparent={true}
|
||||||
|
visible={!!deletingFile}
|
||||||
|
onRequestClose={cancelDelete}
|
||||||
|
>
|
||||||
|
<View style={styles.modalContainer}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
<Text style={styles.modalText}>
|
||||||
|
Sind Sie sicher, dass Sie diese Datei löschen möchten?
|
||||||
|
</Text>
|
||||||
|
<View style={styles.modalButtons}>
|
||||||
|
<ThemedButton
|
||||||
|
onPress={() => {
|
||||||
|
if (deletingFile) {
|
||||||
|
deleteFile(deletingFile);
|
||||||
|
setDeletingFile(null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
title="Ja, löschen"
|
||||||
|
mode="contained"
|
||||||
|
/>
|
||||||
|
<ThemedButton
|
||||||
|
onPress={cancelDelete}
|
||||||
|
title="Abbrechen"
|
||||||
|
mode="outlined"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
</View>
|
</View>
|
||||||
</ThemedBackground>
|
</ThemedBackground>
|
||||||
);
|
);
|
||||||
@@ -286,5 +309,27 @@ const styles = StyleSheet.create({
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginLeft: 8,
|
marginLeft: 8,
|
||||||
}
|
},
|
||||||
|
modalContainer: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
},
|
||||||
|
modalContent: {
|
||||||
|
width: '80%',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 20,
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
modalText: {
|
||||||
|
marginBottom: 15,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
modalButtons: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user