UNPKG

@oxyhq/services

Version:

Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀

258 lines (253 loc) • 10.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _OxyContext = require("../context/OxyContext"); var _sonner = require("../../lib/sonner"); var _confirmAction = require("../utils/confirmAction"); var _components = require("../components"); var _useI18n = require("../hooks/useI18n"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const HistoryViewScreen = ({ onClose, theme, goBack }) => { const { user } = (0, _OxyContext.useOxy)(); const { t } = (0, _useI18n.useI18n)(); const [history, setHistory] = (0, _react.useState)([]); const [isLoading, setIsLoading] = (0, _react.useState)(true); const [isDeleting, setIsDeleting] = (0, _react.useState)(false); // Helper to get storage const getStorage = async () => { const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative'; if (isReactNative) { try { const asyncStorageModule = await Promise.resolve().then(() => _interopRequireWildcard(require('@react-native-async-storage/async-storage'))); const storage = asyncStorageModule.default; return { getItem: storage.getItem.bind(storage), setItem: storage.setItem.bind(storage), removeItem: storage.removeItem.bind(storage) }; } catch (error) { console.error('AsyncStorage not available:', error); throw new Error('AsyncStorage is required in React Native environment'); } } else { // Use localStorage for web return { getItem: async key => { if (typeof window !== 'undefined' && window.localStorage) { return window.localStorage.getItem(key); } return null; }, setItem: async (key, value) => { if (typeof window !== 'undefined' && window.localStorage) { window.localStorage.setItem(key, value); } }, removeItem: async key => { if (typeof window !== 'undefined' && window.localStorage) { window.localStorage.removeItem(key); } } }; } }; // Load history from storage _react.default.useEffect(() => { const loadHistory = async () => { try { setIsLoading(true); // In a real implementation, this would fetch from API or local storage // For now, we'll use a mock implementation const storage = await getStorage(); const historyKey = `history_${user?.id || 'guest'}`; const stored = await storage.getItem(historyKey); if (stored) { const parsed = JSON.parse(stored); setHistory(parsed.map(item => ({ ...item, timestamp: new Date(item.timestamp) }))); } else { setHistory([]); } } catch (error) { setHistory([]); } finally { setIsLoading(false); } }; loadHistory(); }, [user?.id]); const handleDeleteLast15Minutes = (0, _react.useCallback)(async () => { (0, _confirmAction.confirmAction)(t('history.deleteLast15Minutes.confirm') || 'Delete last 15 minutes of history?', async () => { try { setIsDeleting(true); const fifteenMinutesAgo = new Date(Date.now() - 15 * 60 * 1000); const filtered = history.filter(item => item.timestamp < fifteenMinutesAgo); setHistory(filtered); // Save to storage const storage = await getStorage(); const historyKey = `history_${user?.id || 'guest'}`; await storage.setItem(historyKey, JSON.stringify(filtered)); _sonner.toast.success(t('history.deleteLast15Minutes.success') || 'Last 15 minutes deleted'); } catch (error) { console.error('Failed to delete history:', error); _sonner.toast.error(t('history.deleteLast15Minutes.error') || 'Failed to delete history'); } finally { setIsDeleting(false); } }); }, [history, user?.id, t]); const handleClearAll = (0, _react.useCallback)(async () => { (0, _confirmAction.confirmAction)(t('history.clearAll.confirm') || 'Clear all history? This cannot be undone.', async () => { try { setIsDeleting(true); setHistory([]); // Clear from storage const storage = await getStorage(); const historyKey = `history_${user?.id || 'guest'}`; await storage.removeItem(historyKey); _sonner.toast.success(t('history.clearAll.success') || 'History cleared'); } catch (error) { console.error('Failed to clear history:', error); _sonner.toast.error(t('history.clearAll.error') || 'Failed to clear history'); } finally { setIsDeleting(false); } }); }, [user?.id, t]); const themeStyles = (0, _react.useMemo)(() => { const isDarkTheme = theme === 'dark'; return { textColor: isDarkTheme ? '#FFFFFF' : '#000000', backgroundColor: isDarkTheme ? '#121212' : '#FFFFFF', secondaryBackgroundColor: isDarkTheme ? '#222222' : '#F5F5F5', borderColor: isDarkTheme ? '#444444' : '#E0E0E0' }; }, [theme]); const formatTime = date => { const now = new Date(); const diff = now.getTime() - date.getTime(); const minutes = Math.floor(diff / 60000); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (minutes < 1) return t('history.justNow') || 'Just now'; if (minutes < 60) return `${minutes} ${t('history.minutesAgo') || 'minutes ago'}`; if (hours < 24) return `${hours} ${t('history.hoursAgo') || 'hours ago'}`; if (days < 7) return `${days} ${t('history.daysAgo') || 'days ago'}`; return date.toLocaleDateString(); }; return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.container, { backgroundColor: themeStyles.backgroundColor }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Header, { title: t('history.title') || 'History', theme: theme, onBack: goBack || onClose, variant: "minimal", elevation: "subtle" }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, { style: styles.content, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Section, { title: t('history.actions') || 'Actions', theme: theme, isFirst: true, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, { items: [{ id: 'delete-last-15', icon: 'time-outline', iconColor: '#FF9500', title: t('history.deleteLast15Minutes.title') || 'Delete Last 15 Minutes', subtitle: t('history.deleteLast15Minutes.subtitle') || 'Remove recent history entries', onPress: handleDeleteLast15Minutes, disabled: isDeleting || history.length === 0 }, { id: 'clear-all', icon: 'trash-outline', iconColor: '#FF3B30', title: t('history.clearAll.title') || 'Clear All History', subtitle: t('history.clearAll.subtitle') || 'Remove all history entries', onPress: handleClearAll, disabled: isDeleting || history.length === 0 }], theme: theme }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Section, { title: t('history.recent') || 'Recent History', theme: theme, children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.loadingContainer, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, { size: "large", color: themeStyles.textColor }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.loadingText, { color: themeStyles.textColor }], children: t('history.loading') || 'Loading history...' })] }) : history.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.emptyContainer, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.emptyText, { color: themeStyles.textColor }], children: t('history.empty') || 'No history yet' }) }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, { items: history.map(item => ({ id: item.id, icon: item.type === 'search' ? 'search' : 'globe', iconColor: item.type === 'search' ? '#007AFF' : '#32D74B', title: item.query, subtitle: formatTime(item.timestamp) })), theme: theme }) })] })] }); }; const styles = _reactNative.StyleSheet.create({ container: { flex: 1 }, content: { flex: 1, padding: 16 }, loadingContainer: { padding: 40, alignItems: 'center', justifyContent: 'center' }, loadingText: { marginTop: 12, fontSize: 16 }, emptyContainer: { padding: 40, alignItems: 'center', justifyContent: 'center' }, emptyText: { fontSize: 16, textAlign: 'center' } }); var _default = exports.default = /*#__PURE__*/_react.default.memo(HistoryViewScreen); //# sourceMappingURL=HistoryViewScreen.js.map