import React, { useCallback, useState, useEffect } from 'react'; import { View, Text, StyleSheet, FlatList, TouchableOpacity, Image, Modal, ActivityIndicator, Dimensions, Animated } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; import ScannedDataBox from '../components/ScannedDataBox'; import { Ionicons } from '@expo/vector-icons'; import { RootState, AppDispatch } from '../store'; import { QRCodeType } from '../types'; import { toggleBookmark, deleteQRCode, setScannedHistories } from '../reducers/qrCodesReducer'; import useFetchUserAttributes from '../hooks/useFetchUserAttributes'; import { getScannedHistories } from '../api/qrCodeAPI'; const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); const HistoryScreen: React.FC = () => { const dispatch = useDispatch(); const histories = useSelector((state: RootState) => state.qrCodes.histories); const { userAttributes } = useFetchUserAttributes(); const [showBookmarks, setShowBookmarks] = useState(false); const [qrCodeToDelete, setQrCodeToDelete] = useState(null); const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false); const [historiesLoading, setHistoriesLoading] = useState(false); const [historiesError, setHistoriesError] = useState(null); const [selectedQrCodeId, setSelectedQrCodeId] = useState(null); const [isModalVisible, setIsModalVisible] = useState(false); // Modal for ScannedDataBox const fetchHistories = useCallback(async () => { if (!userAttributes?.sub) return; try { setHistoriesLoading(true); const historiesData = await getScannedHistories(); dispatch(setScannedHistories(historiesData)); } catch (error: any) { setHistoriesError(error.message); } finally { setHistoriesLoading(false); } }, [userAttributes?.sub, dispatch]); useEffect(() => { if (userAttributes?.sub) { fetchHistories(); } }, [userAttributes?.sub, fetchHistories]); const handleDeleteQrCode = useCallback((qrCodeId: string) => { if (userAttributes?.sub) { dispatch(deleteQRCode({ userId: userAttributes.sub, qrCodeId })); setIsDeleteModalVisible(false); } }, [dispatch, userAttributes]); const handleSelectQrCodeForView = (item: QRCodeType) => { setSelectedQrCodeId(item.data.id || null); setIsModalVisible(true); // Show ScannedDataBox Modal }; const clearSelectedQrCodeData = () => { setSelectedQrCodeId(null); setIsModalVisible(false); // Close ScannedDataBox Modal }; const filteredQrCodes = showBookmarks ? histories.filter((qr) => qr.bookmarked) : histories; return ( { setShowBookmarks(false); clearSelectedQrCodeData(); }}> History { setShowBookmarks(true); clearSelectedQrCodeData(); }}> Bookmarks {historiesLoading && } {!historiesLoading && filteredQrCodes.length === 0 && ( {showBookmarks ? 'No bookmarks available' : 'No history available'} )} ( handleSelectQrCodeForView(item)} style={styles.itemContent}> {item.data.contents} {new Date(item.data.createdAt).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'})} dispatch(toggleBookmark({ userId: userAttributes.sub, qrCode: item}))}> { setQrCodeToDelete(item.data.id); setIsDeleteModalVisible(true); }}> )} keyExtractor={(item, index) => index.toString()} contentContainerStyle={styles.flatListContent} /> {/* Modal for ScannedDataBox */} {/* The greyspace outside, made clickable to close the modal */} {/* Ensure ScannedDataBox does not render another modal */} {/* Modal to confirm deletion */} setIsDeleteModalVisible(false)} > Are you sure? If bookmarked, this will be removed from both History and Bookmarks. handleDeleteQrCode(qrCodeToDelete!)}> Yes, Delete setIsDeleteModalVisible(false)}> No, Keep It ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f8f0fc', padding: 20, paddingTop: screenHeight * 0.05, }, headerContainer: { flexDirection: 'row', justifyContent: 'space-around', marginBottom: 20, }, headerTextActive: { fontSize: screenWidth * 0.06, fontWeight: 'bold', color: '#ff69b4', }, headerTextInactive: { fontSize: screenWidth * 0.06, fontWeight: 'bold', color: '#ccc', }, itemContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', backgroundColor: '#ffe6f0', padding: screenWidth * 0.025, borderRadius: screenWidth * 0.025, marginBottom: screenWidth * 0.025, }, itemLeft: { flex: 1, marginRight: 2, }, itemContent: { flexDirection: 'row', alignItems: 'center', }, itemRight: { flexDirection: 'row', alignItems: 'center', }, textContainer: { flex: 1, marginLeft: 0, }, dataText: { fontSize: screenWidth * 0.03, color: '#000', marginBottom: screenWidth * 0.02, }, dateText: { fontSize: screenWidth * 0.03, color: '#666', marginLeft: screenWidth * 0.02, flex: 1, }, scanIcon: { width: screenWidth * 0.1, height: screenWidth * 0.1, }, flatListContent: { paddingBottom: screenHeight * 0.1, }, emptyMessage: { textAlign: 'center', fontSize: screenWidth * 0.04, color: '#ff69b4', marginVertical: screenHeight * 0.02, }, modalOverlay: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0, 0, 0, 0.5)', }, modalOverlayTouchable: { flex: 1, justifyContent: 'center', }, modalContainer: { marginHorizontal: '5%', borderRadius: screenWidth * 0.025, backgroundColor: 'white', padding: screenWidth * 0.025, elevation: 5, }, modalContent: { width: '80%', backgroundColor: 'white', borderRadius: screenWidth * 0.025, padding: screenWidth * 0.05, alignItems: 'center', }, modalTitle: { fontSize: screenWidth * 0.05, fontWeight: 'bold', marginBottom: screenHeight * 0.01, }, modalText: { color: '#ff69b4', fontSize: screenWidth * 0.04, marginBottom: screenHeight * 0.02, textAlign: 'center', }, modalButtons: { flexDirection: 'row', justifyContent: 'space-between', width: '100%', }, modalButton: { flex: 1, alignItems: 'center', padding: screenWidth * 0.025, }, modalButtonText: { fontSize: screenWidth * 0.04, color: '#000', }, scannedDataBoxModalOverlay: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0, 0, 0, 0.5)', }, scannedDataBoxModalContainer: { marginHorizontal: '5%', borderRadius: screenWidth * 0.025, backgroundColor: 'white', padding: screenWidth * 0.025, elevation: 5, }, }); export default HistoryScreen;