@oxyhq/services
Version:
310 lines (306 loc) • 9.79 kB
JavaScript
"use strict";
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, ScrollView, TextInput, Platform } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { toast } from '../../lib/sonner';
import { Header, LoadingState, EmptyState } from "../components/index.js";
import { useI18n } from "../hooks/useI18n.js";
import { useThemeStyles } from "../hooks/useThemeStyles.js";
import { useOxy } from "../context/OxyContext.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const FAQScreen = ({
onClose,
theme,
goBack
}) => {
const {
oxyServices
} = useOxy();
const {
t
} = useI18n();
const themeStyles = useThemeStyles(theme || 'light');
const [faqs, setFaqs] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
const [expandedIds, setExpandedIds] = useState(new Set());
const [selectedCategory, setSelectedCategory] = useState(null);
// Load FAQs from API
useEffect(() => {
const loadFAQs = async () => {
try {
setIsLoading(true);
const data = await oxyServices.getFAQs();
setFaqs(data);
} catch (error) {
toast.error(t('faq.loadError') || 'Failed to load FAQs');
} finally {
setIsLoading(false);
}
};
loadFAQs();
}, [oxyServices, t]);
// Get unique categories
const categories = useMemo(() => {
const cats = [...new Set(faqs.map(f => f.category))];
return cats.sort();
}, [faqs]);
// Filter FAQs based on search and category
const filteredFaqs = 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 = useCallback(id => {
setExpandedIds(prev => {
const next = new Set(prev);
if (next.has(id)) {
next.delete(id);
} else {
next.add(id);
}
return next;
});
}, []);
const styles = useMemo(() => createStyles(themeStyles), [themeStyles]);
return /*#__PURE__*/_jsxs(View, {
style: [styles.container, {
backgroundColor: themeStyles.backgroundColor
}],
children: [/*#__PURE__*/_jsx(Header, {
title: t('faq.title') || 'FAQ',
onBack: goBack || onClose,
variant: "minimal",
elevation: "subtle"
}), /*#__PURE__*/_jsx(View, {
style: styles.searchContainer,
children: /*#__PURE__*/_jsxs(View, {
style: [styles.searchInputWrapper, {
backgroundColor: themeStyles.secondaryBackgroundColor,
borderColor: themeStyles.borderColor
}],
children: [/*#__PURE__*/_jsx(Ionicons, {
name: "search",
size: 20,
color: themeStyles.mutedTextColor,
style: styles.searchIcon
}), /*#__PURE__*/_jsx(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__*/_jsx(TouchableOpacity, {
onPress: () => setSearchQuery(''),
accessibilityRole: "button",
accessibilityLabel: "Clear search",
children: /*#__PURE__*/_jsx(Ionicons, {
name: "close-circle",
size: 20,
color: themeStyles.mutedTextColor
})
})]
})
}), categories.length > 0 && /*#__PURE__*/_jsxs(ScrollView, {
horizontal: true,
showsHorizontalScrollIndicator: false,
style: styles.categoriesContainer,
contentContainerStyle: styles.categoriesContent,
children: [/*#__PURE__*/_jsx(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__*/_jsx(Text, {
style: [styles.categoryChipText, {
color: !selectedCategory ? '#FFFFFF' : themeStyles.textColor
}],
children: t('faq.allCategories') || 'All'
})
}), categories.map(cat => /*#__PURE__*/_jsx(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__*/_jsx(Text, {
style: [styles.categoryChipText, {
color: selectedCategory === cat ? '#FFFFFF' : themeStyles.textColor
}],
children: cat
})
}, cat))]
}), /*#__PURE__*/_jsx(ScrollView, {
style: styles.content,
showsVerticalScrollIndicator: false,
children: isLoading ? /*#__PURE__*/_jsx(LoadingState, {
message: t('faq.loading') || 'Loading FAQs...',
color: themeStyles.textColor
}) : filteredFaqs.length === 0 ? /*#__PURE__*/_jsx(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__*/_jsxs(View, {
style: [styles.faqItem, {
backgroundColor: themeStyles.secondaryBackgroundColor,
borderColor: themeStyles.borderColor
}, index === 0 && styles.faqItemFirst],
children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
style: styles.faqQuestion,
onPress: () => toggleExpanded(faq.id),
accessibilityRole: "button",
accessibilityLabel: faq.question,
accessibilityHint: isExpanded ? 'Collapse answer' : 'Expand answer',
accessibilityState: {
expanded: isExpanded
},
children: [/*#__PURE__*/_jsx(Text, {
style: [styles.faqQuestionText, {
color: themeStyles.textColor
}],
children: faq.question
}), /*#__PURE__*/_jsx(Ionicons, {
name: isExpanded ? 'chevron-up' : 'chevron-down',
size: 20,
color: themeStyles.mutedTextColor
})]
}), isExpanded && /*#__PURE__*/_jsxs(View, {
style: [styles.faqAnswer, {
borderTopColor: themeStyles.borderColor
}],
children: [/*#__PURE__*/_jsx(Text, {
style: [styles.faqAnswerText, {
color: themeStyles.mutedTextColor
}],
children: faq.answer
}), /*#__PURE__*/_jsxs(View, {
style: styles.faqCategory,
children: [/*#__PURE__*/_jsx(Ionicons, {
name: "pricetag-outline",
size: 14,
color: themeStyles.primaryColor
}), /*#__PURE__*/_jsx(Text, {
style: [styles.faqCategoryText, {
color: themeStyles.primaryColor
}],
children: faq.category
})]
})]
})]
}, faq.id);
})
})]
});
};
const createStyles = themeStyles => 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,
...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'
}
});
export default FAQScreen;
//# sourceMappingURL=FAQScreen.js.map