UNPKG

@oxyhq/services

Version:

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

207 lines (202 loc) • 7.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _vectorIcons = require("@expo/vector-icons"); 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 FAQ_KEYS = ['what', 'earn', 'lose', 'use', 'transfer', 'support']; /** * KarmaFAQScreen - Optimized for performance * * Performance optimizations implemented: * - useMemo for theme calculations (only recalculates when theme changes) * - useMemo for filtered FAQs (only recalculates when search changes) * - useCallback for event handlers to prevent unnecessary re-renders * - React.memo wrapper to prevent re-renders when props haven't changed */ const KarmaFAQScreen = ({ goBack, theme }) => { const { t } = (0, _useI18n.useI18n)(); const [expanded, setExpanded] = (0, _react.useState)(0); const [search, setSearch] = (0, _react.useState)(''); // Memoize theme-related calculations to prevent unnecessary recalculations const themeStyles = (0, _react.useMemo)(() => { const isDarkTheme = theme === 'dark'; return { isDarkTheme, backgroundColor: isDarkTheme ? '#121212' : '#FFFFFF', textColor: isDarkTheme ? '#FFFFFF' : '#000000', cardColor: isDarkTheme ? '#23232b' : '#f7f7fa', primaryColor: '#d169e5', inputBg: isDarkTheme ? '#23232b' : '#f2f2f7', inputBorder: isDarkTheme ? '#444' : '#e0e0e0' }; }, [theme]); // Memoize filtered FAQs to prevent filtering on every render const faqs = (0, _react.useMemo)(() => FAQ_KEYS.map(key => ({ q: t(`karma.faq.items.${key}.q`) || '', a: t(`karma.faq.items.${key}.a`) || '' })), [t]); const filteredFaqs = (0, _react.useMemo)(() => { if (!search.trim()) return faqs; const searchLower = search.toLowerCase(); return faqs.filter(faq => faq.q.toLowerCase().includes(searchLower) || faq.a.toLowerCase().includes(searchLower)); }, [search, faqs]); // Memoize toggle handler to prevent recreation on every render const handleToggle = (0, _react.useCallback)(idx => { _reactNative.LayoutAnimation.configureNext(_reactNative.LayoutAnimation.Presets.easeInEaseOut); setExpanded(prev => prev === idx ? null : idx); }, []); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.container, { backgroundColor: themeStyles.backgroundColor }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Header, { title: t('karma.faq.title') || 'Karma FAQ', subtitle: t('karma.faq.subtitle') || 'Frequently asked questions about karma', subtitleVariant: "muted", theme: theme, onBack: goBack, elevation: "subtle" }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.searchBar, { backgroundColor: themeStyles.inputBg, borderColor: themeStyles.inputBorder }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "search-outline", size: 20, color: themeStyles.primaryColor, style: { marginRight: 8 } }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, { style: [styles.searchInput, { color: themeStyles.textColor }], placeholder: t('karma.faq.search') || 'Search FAQ...', placeholderTextColor: themeStyles.isDarkTheme ? '#aaa' : '#888', value: search, onChangeText: setSearch, returnKeyType: "search" })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, { contentContainerStyle: styles.contentContainer, children: filteredFaqs.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.noResults, { color: themeStyles.textColor }], children: t('karma.faq.noResults', { query: search }) || `No FAQ items found matching "${search}"` }) : filteredFaqs.map((faq, idx) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, { style: [styles.card, { backgroundColor: themeStyles.cardColor }], onPress: () => handleToggle(idx), activeOpacity: 0.7, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.questionRow, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.question, { color: themeStyles.textColor }], children: faq.q }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: expanded === idx ? 'chevron-up' : 'chevron-down', size: 20, color: themeStyles.primaryColor })] }), expanded === idx && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.answer, { color: themeStyles.textColor }], children: faq.a })] }, idx)) })] }); }; const styles = _reactNative.StyleSheet.create({ container: { flex: 1 }, title: { fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold', fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined, fontSize: 38, margin: 24, marginBottom: 12, textAlign: 'center' }, searchBar: { flexDirection: 'row', alignItems: 'center', borderRadius: 16, borderWidth: 1, marginHorizontal: 24, marginBottom: 12, paddingHorizontal: 12, height: 44 }, searchInput: { flex: 1, fontSize: 16, height: 44 }, contentContainer: { padding: 24, paddingTop: 20, paddingBottom: 40 }, card: { borderRadius: 18, padding: 20, marginBottom: 18, shadowOpacity: 0.08, shadowOffset: { width: 0, height: 2 }, shadowRadius: 8, elevation: 2 }, questionRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }, question: { fontSize: 17, fontWeight: 'bold', flex: 1 }, answer: { fontSize: 16, lineHeight: 22, marginTop: 8 }, paragraph: { fontSize: 16, marginBottom: 12 }, noResults: { fontSize: 16, marginTop: 32, textAlign: 'center', opacity: 0.7 } }); var _default = exports.default = /*#__PURE__*/_react.default.memo(KarmaFAQScreen); //# sourceMappingURL=KarmaFAQScreen.js.map