@oxyhq/services
Version:
315 lines (311 loc) • 11.3 kB
JavaScript
"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 _sonner = require("../../lib/sonner");
var _index = require("../components/index.js");
var _useI18n = require("../hooks/useI18n.js");
var _useThemeStyles = require("../hooks/useThemeStyles.js");
var _OxyContext = require("../context/OxyContext.js");
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 FAQScreen = ({
onClose,
theme,
goBack
}) => {
const {
oxyServices
} = (0, _OxyContext.useOxy)();
const {
t
} = (0, _useI18n.useI18n)();
const themeStyles = (0, _useThemeStyles.useThemeStyles)(theme || 'light');
const [faqs, setFaqs] = (0, _react.useState)([]);
const [isLoading, setIsLoading] = (0, _react.useState)(true);
const [searchQuery, setSearchQuery] = (0, _react.useState)('');
const [expandedIds, setExpandedIds] = (0, _react.useState)(new Set());
const [selectedCategory, setSelectedCategory] = (0, _react.useState)(null);
// Load FAQs from API
(0, _react.useEffect)(() => {
const loadFAQs = async () => {
try {
setIsLoading(true);
const data = await oxyServices.getFAQs();
setFaqs(data);
} catch (error) {
_sonner.toast.error(t('faq.loadError') || 'Failed to load FAQs');
} finally {
setIsLoading(false);
}
};
loadFAQs();
}, [oxyServices, t]);
// Get unique categories
const categories = (0, _react.useMemo)(() => {
const cats = [...new Set(faqs.map(f => f.category))];
return cats.sort();
}, [faqs]);
// Filter FAQs based on search and category
const filteredFaqs = (0, _react.useMemo)(() => {
let result = faqs;
if (selectedCategory) {
result = result.filter(f => f.category === selectedCategory);
}
if (searchQuery.trim()) {
const query = searchQuery.toLowerCase();
result = result.filter(f => f.question.toLowerCase().includes(query) || f.answer.toLowerCase().includes(query));
}
return result;
}, [faqs, searchQuery, selectedCategory]);
const toggleExpanded = (0, _react.useCallback)(id => {
setExpandedIds(prev => {
const next = new Set(prev);
if (next.has(id)) {
next.delete(id);
} else {
next.add(id);
}
return next;
});
}, []);
const styles = (0, _react.useMemo)(() => createStyles(themeStyles), [themeStyles]);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.container, {
backgroundColor: themeStyles.backgroundColor
}],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index.Header, {
title: t('faq.title') || 'FAQ',
onBack: goBack || onClose,
variant: "minimal",
elevation: "subtle"
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: styles.searchContainer,
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.searchInputWrapper, {
backgroundColor: themeStyles.secondaryBackgroundColor,
borderColor: themeStyles.borderColor
}],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: "search",
size: 20,
color: themeStyles.mutedTextColor,
style: styles.searchIcon
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
style: [styles.searchInput, {
color: themeStyles.textColor
}],
placeholder: t('faq.searchPlaceholder') || 'Search FAQs...',
placeholderTextColor: themeStyles.mutedTextColor,
value: searchQuery,
onChangeText: setSearchQuery,
accessibilityLabel: "Search FAQs"
}), searchQuery.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
onPress: () => setSearchQuery(''),
accessibilityRole: "button",
accessibilityLabel: "Clear search",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: "close-circle",
size: 20,
color: themeStyles.mutedTextColor
})
})]
})
}), categories.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
horizontal: true,
showsHorizontalScrollIndicator: false,
style: styles.categoriesContainer,
contentContainerStyle: styles.categoriesContent,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
style: [styles.categoryChip, !selectedCategory && styles.categoryChipActive, {
backgroundColor: !selectedCategory ? themeStyles.primaryColor : themeStyles.secondaryBackgroundColor
}],
onPress: () => setSelectedCategory(null),
accessibilityRole: "button",
accessibilityLabel: "Show all categories",
accessibilityState: {
selected: !selectedCategory
},
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.categoryChipText, {
color: !selectedCategory ? '#FFFFFF' : themeStyles.textColor
}],
children: t('faq.allCategories') || 'All'
})
}), categories.map(cat => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
style: [styles.categoryChip, selectedCategory === cat && styles.categoryChipActive, {
backgroundColor: selectedCategory === cat ? themeStyles.primaryColor : themeStyles.secondaryBackgroundColor
}],
onPress: () => setSelectedCategory(cat),
accessibilityRole: "button",
accessibilityLabel: `Filter by ${cat}`,
accessibilityState: {
selected: selectedCategory === cat
},
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.categoryChipText, {
color: selectedCategory === cat ? '#FFFFFF' : themeStyles.textColor
}],
children: cat
})
}, cat))]
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
style: styles.content,
showsVerticalScrollIndicator: false,
children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.LoadingState, {
message: t('faq.loading') || 'Loading FAQs...',
color: themeStyles.textColor
}) : filteredFaqs.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.EmptyState, {
message: searchQuery ? t('faq.noResults') || 'No FAQs match your search' : t('faq.empty') || 'No FAQs available',
textColor: themeStyles.textColor
}) : filteredFaqs.map((faq, index) => {
const isExpanded = expandedIds.has(faq.id);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.faqItem, {
backgroundColor: themeStyles.secondaryBackgroundColor,
borderColor: themeStyles.borderColor
}, index === 0 && styles.faqItemFirst],
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
style: styles.faqQuestion,
onPress: () => toggleExpanded(faq.id),
accessibilityRole: "button",
accessibilityLabel: faq.question,
accessibilityHint: isExpanded ? 'Collapse answer' : 'Expand answer',
accessibilityState: {
expanded: isExpanded
},
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.faqQuestionText, {
color: themeStyles.textColor
}],
children: faq.question
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: isExpanded ? 'chevron-up' : 'chevron-down',
size: 20,
color: themeStyles.mutedTextColor
})]
}), isExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.faqAnswer, {
borderTopColor: themeStyles.borderColor
}],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.faqAnswerText, {
color: themeStyles.mutedTextColor
}],
children: faq.answer
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: styles.faqCategory,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: "pricetag-outline",
size: 14,
color: themeStyles.primaryColor
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.faqCategoryText, {
color: themeStyles.primaryColor
}],
children: faq.category
})]
})]
})]
}, faq.id);
})
})]
});
};
const createStyles = themeStyles => _reactNative.StyleSheet.create({
container: {
flex: 1
},
searchContainer: {
paddingHorizontal: 16,
paddingVertical: 12
},
searchInputWrapper: {
flexDirection: 'row',
alignItems: 'center',
borderRadius: 12,
borderWidth: 1,
paddingHorizontal: 12,
height: 44
},
searchIcon: {
marginRight: 8
},
searchInput: {
flex: 1,
fontSize: 16,
..._reactNative.Platform.select({
web: {
outlineStyle: 'none'
}
})
},
categoriesContainer: {
maxHeight: 50
},
categoriesContent: {
paddingHorizontal: 16,
gap: 8
},
categoryChip: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
marginRight: 8
},
categoryChipActive: {},
categoryChipText: {
fontSize: 14,
fontWeight: '500'
},
content: {
flex: 1,
padding: 16
},
faqItem: {
borderRadius: 12,
borderWidth: 1,
marginBottom: 12,
overflow: 'hidden'
},
faqItemFirst: {
marginTop: 0
},
faqQuestion: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
padding: 16
},
faqQuestionText: {
flex: 1,
fontSize: 16,
fontWeight: '600',
marginRight: 12
},
faqAnswer: {
padding: 16,
paddingTop: 12,
borderTopWidth: 1
},
faqAnswerText: {
fontSize: 14,
lineHeight: 22
},
faqCategory: {
flexDirection: 'row',
alignItems: 'center',
marginTop: 12
},
faqCategoryText: {
fontSize: 12,
marginLeft: 6,
fontWeight: '500'
}
});
var _default = exports.default = FAQScreen;
//# sourceMappingURL=FAQScreen.js.map