@umituz/react-native-settings 4.20.58 → 4.20.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
- package/.github/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +63 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +84 -0
- package/AI_AGENT_GUIDELINES.md +367 -0
- package/ARCHITECTURE.md +246 -0
- package/CHANGELOG.md +67 -0
- package/CODE_OF_CONDUCT.md +75 -0
- package/CONTRIBUTING.md +107 -0
- package/DOCUMENTATION_MIGRATION.md +319 -0
- package/DOCUMENTATION_TEMPLATE.md +155 -0
- package/LICENSE +21 -0
- package/README.md +321 -498
- package/SECURITY.md +98 -0
- package/SETTINGS_SCREEN_GUIDE.md +185 -0
- package/TESTING.md +358 -0
- package/package.json +13 -2
- package/src/application/README.md +85 -271
- package/src/domains/about/README.md +85 -440
- package/src/domains/about/presentation/hooks/README.md +93 -348
- package/src/domains/appearance/README.md +95 -584
- package/src/domains/appearance/hooks/README.md +95 -303
- package/src/domains/appearance/infrastructure/services/README.md +83 -397
- package/src/domains/appearance/presentation/components/README.md +95 -489
- package/src/domains/cloud-sync/README.md +73 -439
- package/src/domains/cloud-sync/presentation/components/README.md +95 -493
- package/src/domains/dev/README.md +71 -457
- package/src/domains/disclaimer/README.md +77 -411
- package/src/domains/disclaimer/presentation/components/README.md +95 -392
- package/src/domains/faqs/README.md +86 -574
- package/src/domains/feedback/README.md +79 -553
- package/src/domains/feedback/presentation/hooks/README.md +93 -426
- package/src/domains/legal/README.md +88 -537
- package/src/domains/rating/README.md +73 -440
- package/src/domains/rating/presentation/components/README.md +95 -475
- package/src/domains/video-tutorials/README.md +77 -470
- package/src/domains/video-tutorials/presentation/components/README.md +95 -431
- package/src/infrastructure/README.md +78 -425
- package/src/infrastructure/repositories/README.md +88 -420
- package/src/infrastructure/services/README.md +74 -460
- package/src/presentation/components/README.md +97 -480
- package/src/presentation/components/SettingsErrorBoundary/README.md +48 -436
- package/src/presentation/components/SettingsFooter/README.md +48 -427
- package/src/presentation/components/SettingsItemCard/README.md +152 -391
- package/src/presentation/components/SettingsItemCard/STRATEGY.md +164 -0
- package/src/presentation/components/SettingsSection/README.md +47 -401
- package/src/presentation/hooks/README.md +95 -389
- package/src/presentation/hooks/mutations/README.md +99 -376
- package/src/presentation/hooks/queries/README.md +111 -353
- package/src/presentation/navigation/README.md +70 -502
- package/src/presentation/navigation/SettingsStackNavigator.tsx +2 -0
- package/src/presentation/navigation/components/README.md +70 -295
- package/src/presentation/navigation/components/wrappers/SettingsScreenWrapper.tsx +3 -0
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/types.ts +1 -0
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- package/src/presentation/screens/SettingsScreen.tsx +4 -2
- package/src/presentation/screens/components/SettingsContent/README.md +53 -382
- package/src/presentation/screens/components/SettingsHeader/README.md +48 -303
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +47 -359
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +81 -176
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +40 -297
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +47 -451
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +45 -361
- package/src/presentation/screens/hooks/README.md +64 -354
- package/src/presentation/screens/types/README.md +79 -409
- package/src/presentation/screens/utils/README.md +65 -255
|
@@ -1,579 +1,91 @@
|
|
|
1
1
|
# FAQs Domain
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
Component for rendering a single FAQ category with questions.
|
|
91
|
-
|
|
92
|
-
```tsx
|
|
93
|
-
import { FAQCategory } from '@umituz/react-native-settings';
|
|
94
|
-
|
|
95
|
-
function MyFAQCategory() {
|
|
96
|
-
const category = {
|
|
97
|
-
id: 'general',
|
|
98
|
-
title: 'General Questions',
|
|
99
|
-
questions: [
|
|
100
|
-
{
|
|
101
|
-
id: 'q1',
|
|
102
|
-
question: 'What is this?',
|
|
103
|
-
answer: 'Answer here...',
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const isExpanded = { q1: true };
|
|
109
|
-
const onToggle = (id) => console.log('Toggle:', id);
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
<FAQCategory
|
|
113
|
-
category={category}
|
|
114
|
-
isExpanded={isExpanded}
|
|
115
|
-
onToggleItem={onToggle}
|
|
116
|
-
/>
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
#### Props
|
|
122
|
-
|
|
123
|
-
| Prop | Type | Default | Description |
|
|
124
|
-
|------|------|---------|-------------|
|
|
125
|
-
| `category` | `FAQCategory` | **Required** | Category data |
|
|
126
|
-
| `isExpanded` | `Record<string, boolean>` | **Required** | Expansion state |
|
|
127
|
-
| `onToggleItem` | `(id) => void` | **Required** | Toggle handler |
|
|
128
|
-
| `styles` | `FAQCategoryStyles` | `undefined` | Custom styles |
|
|
129
|
-
|
|
130
|
-
### FAQItem
|
|
131
|
-
|
|
132
|
-
Individual FAQ item with expandable answer.
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
import { FAQItem } from '@umituz/react-native-settings';
|
|
136
|
-
|
|
137
|
-
function MyFAQItem() {
|
|
138
|
-
return (
|
|
139
|
-
<FAQItem
|
|
140
|
-
question="What is your return policy?"
|
|
141
|
-
answer="You can return items within 30 days of purchase."
|
|
142
|
-
isExpanded={true}
|
|
143
|
-
onToggle={() => console.log('Toggle')}
|
|
144
|
-
/>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
#### Props
|
|
150
|
-
|
|
151
|
-
| Prop | Type | Default | Description |
|
|
152
|
-
|------|------|---------|-------------|
|
|
153
|
-
| `question` | `string` | **Required** | Question text |
|
|
154
|
-
| `answer` | `string` | **Required** | Answer text |
|
|
155
|
-
| `isExpanded` | `boolean` | **Required** | Expansion state |
|
|
156
|
-
| `onToggle` | `() => void` | **Required** | Toggle handler |
|
|
157
|
-
|
|
158
|
-
### FAQSearchBar
|
|
159
|
-
|
|
160
|
-
Search input component for filtering FAQs.
|
|
161
|
-
|
|
162
|
-
```tsx
|
|
163
|
-
import { FAQSearchBar } from '@umituz/react-native-settings';
|
|
164
|
-
|
|
165
|
-
function MyFAQSearch() {
|
|
166
|
-
const [query, setQuery] = useState('');
|
|
167
|
-
|
|
168
|
-
return (
|
|
169
|
-
<FAQSearchBar
|
|
170
|
-
value={query}
|
|
171
|
-
onChangeText={setQuery}
|
|
172
|
-
placeholder="Search questions..."
|
|
173
|
-
/>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
#### Props
|
|
179
|
-
|
|
180
|
-
| Prop | Type | Default | Description |
|
|
181
|
-
|------|------|---------|-------------|
|
|
182
|
-
| `value` | `string` | **Required** | Search query |
|
|
183
|
-
| `onChangeText` | `(text) => void` | **Required** | Text change handler |
|
|
184
|
-
| `placeholder` | `string` | **Required** | Placeholder text |
|
|
185
|
-
| `styles` | `FAQSearchBarStyles` | `undefined` | Custom styles |
|
|
186
|
-
|
|
187
|
-
### FAQEmptyState
|
|
188
|
-
|
|
189
|
-
Empty state component for no search results.
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
import { FAQEmptyState } from '@umituz/react-native-settings';
|
|
193
|
-
|
|
194
|
-
function MyEmptyState() {
|
|
195
|
-
return (
|
|
196
|
-
<FAQEmptyState
|
|
197
|
-
title="No FAQs Found"
|
|
198
|
-
message="We couldn't find any FAQs matching your search."
|
|
199
|
-
iconName="search"
|
|
200
|
-
/>
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
#### Props
|
|
206
|
-
|
|
207
|
-
| Prop | Type | Default | Description |
|
|
208
|
-
|------|------|---------|-------------|
|
|
209
|
-
| `title` | `string` | **Required** | Empty state title |
|
|
210
|
-
| `message` | `string` | **Required** | Empty state message |
|
|
211
|
-
| `iconName` | `string` | `undefined` | Custom icon name |
|
|
212
|
-
| `styles` | `FAQEmptyStateStyles` | `undefined` | Custom styles |
|
|
213
|
-
|
|
214
|
-
## Hooks
|
|
215
|
-
|
|
216
|
-
### useFAQSearch
|
|
217
|
-
|
|
218
|
-
Hook for managing FAQ search state and filtering.
|
|
219
|
-
|
|
220
|
-
```tsx
|
|
221
|
-
import { useFAQSearch } from '@umituz/react-native-settings';
|
|
222
|
-
|
|
223
|
-
function FAQSearchComponent() {
|
|
224
|
-
const categories = [ /* FAQ categories */ ];
|
|
225
|
-
|
|
226
|
-
const {
|
|
227
|
-
searchQuery,
|
|
228
|
-
setSearchQuery,
|
|
229
|
-
filteredCategories,
|
|
230
|
-
hasResults,
|
|
231
|
-
} = useFAQSearch(categories);
|
|
232
|
-
|
|
233
|
-
return (
|
|
234
|
-
<View>
|
|
235
|
-
<TextInput
|
|
236
|
-
value={searchQuery}
|
|
237
|
-
onChangeText={setSearchQuery}
|
|
238
|
-
placeholder="Search..."
|
|
239
|
-
/>
|
|
240
|
-
{hasResults ? (
|
|
241
|
-
<FAQList categories={filteredCategories} />
|
|
242
|
-
) : (
|
|
243
|
-
<Text>No results</Text>
|
|
244
|
-
)}
|
|
245
|
-
</View>
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
#### Return Value
|
|
251
|
-
|
|
252
|
-
| Property | Type | Description |
|
|
253
|
-
|----------|------|-------------|
|
|
254
|
-
| `searchQuery` | `string` | Current search query |
|
|
255
|
-
| `setSearchQuery` | `(query) => void` | Set search query |
|
|
256
|
-
| `filteredCategories` | `FAQCategory[]` | Filtered categories |
|
|
257
|
-
| `hasResults` | `boolean` | Whether search has results |
|
|
258
|
-
|
|
259
|
-
### useFAQExpansion
|
|
260
|
-
|
|
261
|
-
Hook for managing FAQ item expansion state.
|
|
262
|
-
|
|
263
|
-
```tsx
|
|
264
|
-
import { useFAQExpansion } from '@umituz/react-native-settings';
|
|
265
|
-
|
|
266
|
-
function FAQExpansionComponent() {
|
|
267
|
-
const { isExpanded, toggleExpansion } = useFAQExpansion();
|
|
268
|
-
|
|
269
|
-
return (
|
|
270
|
-
<FAQItem
|
|
271
|
-
question="Question"
|
|
272
|
-
answer="Answer"
|
|
273
|
-
isExpanded={isExpanded['q1']}
|
|
274
|
-
onToggle={() => toggleExpansion('q1')}
|
|
275
|
-
/>
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
#### Return Value
|
|
281
|
-
|
|
282
|
-
| Property | Type | Description |
|
|
283
|
-
|----------|------|-------------|
|
|
284
|
-
| `isExpanded` | `Record<string, boolean>` | Expansion state map |
|
|
285
|
-
| `toggleExpansion` | `(id) => void` | Toggle item expansion |
|
|
286
|
-
|
|
287
|
-
## Types
|
|
288
|
-
|
|
289
|
-
### FAQCategory
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
interface FAQCategory {
|
|
293
|
-
id: string;
|
|
294
|
-
title: string;
|
|
295
|
-
questions: FAQItem[];
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### FAQItem
|
|
300
|
-
|
|
301
|
-
```typescript
|
|
302
|
-
interface FAQItem {
|
|
303
|
-
id: string;
|
|
304
|
-
question: string;
|
|
305
|
-
answer: string;
|
|
306
|
-
}
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
### FAQScreenStyles
|
|
310
|
-
|
|
311
|
-
```typescript
|
|
312
|
-
interface FAQScreenStyles {
|
|
313
|
-
container?: ViewStyle;
|
|
314
|
-
header?: ViewStyle;
|
|
315
|
-
title?: TextStyle;
|
|
316
|
-
content?: ViewStyle;
|
|
317
|
-
searchBar?: FAQSearchBarStyles;
|
|
318
|
-
emptyState?: FAQEmptyStateStyles;
|
|
319
|
-
category?: FAQCategoryStyles;
|
|
320
|
-
}
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
## Examples
|
|
324
|
-
|
|
325
|
-
### Basic FAQ Screen
|
|
326
|
-
|
|
327
|
-
```tsx
|
|
328
|
-
import React from 'react';
|
|
329
|
-
import { FAQScreen } from '@umituz/react-native-settings';
|
|
330
|
-
|
|
331
|
-
const FAQ_DATA = [
|
|
332
|
-
{
|
|
333
|
-
id: 'getting-started',
|
|
334
|
-
title: 'Getting Started',
|
|
335
|
-
questions: [
|
|
336
|
-
{
|
|
337
|
-
id: 'gs1',
|
|
338
|
-
question: 'How do I create an account?',
|
|
339
|
-
answer: 'Tap the "Sign Up" button and enter your email and password.',
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
id: 'gs2',
|
|
343
|
-
question: 'Is the app free to use?',
|
|
344
|
-
answer: 'Yes, the basic features are completely free. Premium features require a subscription.',
|
|
345
|
-
},
|
|
346
|
-
],
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
id: 'features',
|
|
350
|
-
title: 'Features',
|
|
351
|
-
questions: [
|
|
352
|
-
{
|
|
353
|
-
id: 'f1',
|
|
354
|
-
question: 'Can I use the app offline?',
|
|
355
|
-
answer: 'Yes, you can access cached content offline. Some features require internet.',
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
id: 'f2',
|
|
359
|
-
question: 'How do I sync my data?',
|
|
360
|
-
answer: 'Data syncs automatically when you\'re connected to the internet.',
|
|
361
|
-
},
|
|
362
|
-
],
|
|
363
|
-
},
|
|
364
|
-
];
|
|
365
|
-
|
|
366
|
-
export default function FAQScreenExample() {
|
|
367
|
-
return (
|
|
368
|
-
<FAQScreen
|
|
369
|
-
categories={FAQ_DATA}
|
|
370
|
-
searchPlaceholder="Search for answers..."
|
|
371
|
-
emptySearchTitle="No FAQs found"
|
|
372
|
-
emptySearchMessage="Try searching with different keywords"
|
|
373
|
-
headerTitle="Help & FAQs"
|
|
374
|
-
/>
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
### Custom Styled FAQ Screen
|
|
380
|
-
|
|
381
|
-
```tsx
|
|
382
|
-
import { FAQScreen } from '@umituz/react-native-settings';
|
|
383
|
-
import { StyleSheet } from 'react-native';
|
|
384
|
-
|
|
385
|
-
const customStyles = {
|
|
386
|
-
container: {
|
|
387
|
-
backgroundColor: '#F5F5F5',
|
|
388
|
-
},
|
|
389
|
-
header: {
|
|
390
|
-
padding: 24,
|
|
391
|
-
},
|
|
392
|
-
category: {
|
|
393
|
-
marginBottom: 16,
|
|
394
|
-
},
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
function CustomStyledFAQ() {
|
|
398
|
-
return (
|
|
399
|
-
<FAQScreen
|
|
400
|
-
categories={FAQ_DATA}
|
|
401
|
-
searchPlaceholder="Type your question..."
|
|
402
|
-
emptySearchTitle="No results"
|
|
403
|
-
emptySearchMessage="We couldn't find an answer"
|
|
404
|
-
headerTitle="FAQ"
|
|
405
|
-
styles={customStyles}
|
|
406
|
-
/>
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### Using Individual Components
|
|
412
|
-
|
|
413
|
-
```tsx
|
|
414
|
-
import { FAQCategory, FAQItem } from '@umituz/react-native-settings';
|
|
415
|
-
|
|
416
|
-
function CustomFAQSection() {
|
|
417
|
-
const [expanded, setExpanded] = useState({});
|
|
418
|
-
|
|
419
|
-
const toggleItem = (id) => {
|
|
420
|
-
setExpanded(prev => ({
|
|
421
|
-
...prev,
|
|
422
|
-
[id]: !prev[id],
|
|
423
|
-
}));
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
return (
|
|
427
|
-
<ScrollView>
|
|
428
|
-
<FAQCategory
|
|
429
|
-
category={{
|
|
430
|
-
id: 'general',
|
|
431
|
-
title: 'General',
|
|
432
|
-
questions: [
|
|
433
|
-
{
|
|
434
|
-
id: 'q1',
|
|
435
|
-
question: 'Question 1?',
|
|
436
|
-
answer: 'Answer 1',
|
|
437
|
-
},
|
|
438
|
-
],
|
|
439
|
-
}}
|
|
440
|
-
isExpanded={expanded}
|
|
441
|
-
onToggleItem={toggleItem}
|
|
442
|
-
/>
|
|
443
|
-
</ScrollView>
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
### Using Search Hook
|
|
449
|
-
|
|
450
|
-
```tsx
|
|
451
|
-
import { useFAQSearch } from '@umituz/react-native-settings';
|
|
452
|
-
|
|
453
|
-
function CustomFAQSearch() {
|
|
454
|
-
const categories = [/* FAQ data */];
|
|
455
|
-
const {
|
|
456
|
-
searchQuery,
|
|
457
|
-
setSearchQuery,
|
|
458
|
-
filteredCategories,
|
|
459
|
-
hasResults,
|
|
460
|
-
} = useFAQSearch(categories);
|
|
461
|
-
|
|
462
|
-
return (
|
|
463
|
-
<View>
|
|
464
|
-
<TextInput
|
|
465
|
-
value={searchQuery}
|
|
466
|
-
onChangeText={setSearchQuery}
|
|
467
|
-
placeholder="Search..."
|
|
468
|
-
style={{ padding: 16, backgroundColor: '#FFF' }}
|
|
469
|
-
/>
|
|
470
|
-
|
|
471
|
-
{!hasResults && searchQuery ? (
|
|
472
|
-
<View style={{ padding: 32, alignItems: 'center' }}>
|
|
473
|
-
<Text>No FAQs found for "{searchQuery}"</Text>
|
|
474
|
-
</View>
|
|
475
|
-
) : (
|
|
476
|
-
filteredCategories.map(cat => (
|
|
477
|
-
<FAQCategory
|
|
478
|
-
key={cat.id}
|
|
479
|
-
category={cat}
|
|
480
|
-
isExpanded={expanded}
|
|
481
|
-
onToggleItem={toggleItem}
|
|
482
|
-
/>
|
|
483
|
-
))
|
|
484
|
-
)}
|
|
485
|
-
</View>
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
## Architecture
|
|
491
|
-
|
|
492
|
-
```
|
|
493
|
-
src/domains/faqs/
|
|
494
|
-
├── domain/
|
|
495
|
-
│ ├── entities/
|
|
496
|
-
│ │ └── FAQEntity.ts # FAQ types and interfaces
|
|
497
|
-
│ └── services/
|
|
498
|
-
│ └── FAQSearchService.ts # Search logic
|
|
499
|
-
├── presentation/
|
|
500
|
-
│ ├── screens/
|
|
501
|
-
│ │ └── FAQScreen.tsx
|
|
502
|
-
│ ├── components/
|
|
503
|
-
│ │ ├── FAQCategory.tsx
|
|
504
|
-
│ │ ├── FAQItem.tsx
|
|
505
|
-
│ │ ├── FAQSearchBar.tsx
|
|
506
|
-
│ │ └── FAQEmptyState.tsx
|
|
507
|
-
│ └── hooks/
|
|
508
|
-
│ ├── useFAQSearch.ts
|
|
509
|
-
│ └── useFAQExpansion.ts
|
|
510
|
-
└── index.ts # Public API exports
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
## Best Practices
|
|
514
|
-
|
|
515
|
-
1. **Organize by Category**: Group related questions together
|
|
516
|
-
2. **Clear Answers**: Keep answers concise and easy to understand
|
|
517
|
-
3. **Searchable Content**: Use clear keywords in questions and answers
|
|
518
|
-
4. **Keep Updated**: Regularly update FAQs based on user feedback
|
|
519
|
-
5. **Multiple Languages**: Provide FAQs in all supported languages
|
|
520
|
-
6. **Visual Hierarchy**: Use proper spacing and typography
|
|
521
|
-
7. **Performance**: Optimize for large FAQ lists with pagination
|
|
522
|
-
|
|
523
|
-
## Testing
|
|
524
|
-
|
|
525
|
-
```tsx
|
|
526
|
-
import { render, fireEvent } from '@testing-library/react-native';
|
|
527
|
-
import { FAQScreen } from '@umituz/react-native-settings';
|
|
528
|
-
|
|
529
|
-
describe('FAQScreen', () => {
|
|
530
|
-
const categories = [
|
|
531
|
-
{
|
|
532
|
-
id: 'test',
|
|
533
|
-
title: 'Test Category',
|
|
534
|
-
questions: [
|
|
535
|
-
{
|
|
536
|
-
id: 'q1',
|
|
537
|
-
question: 'Test Question?',
|
|
538
|
-
answer: 'Test Answer',
|
|
539
|
-
},
|
|
540
|
-
],
|
|
541
|
-
},
|
|
542
|
-
];
|
|
543
|
-
|
|
544
|
-
it('renders FAQ categories', () => {
|
|
545
|
-
const { getByText } = render(
|
|
546
|
-
<FAQScreen
|
|
547
|
-
categories={categories}
|
|
548
|
-
searchPlaceholder="Search"
|
|
549
|
-
emptySearchTitle="No results"
|
|
550
|
-
emptySearchMessage="Try again"
|
|
551
|
-
headerTitle="FAQ"
|
|
552
|
-
/>
|
|
553
|
-
);
|
|
554
|
-
|
|
555
|
-
expect(getByText('Test Category')).toBeTruthy();
|
|
556
|
-
expect(getByText('Test Question?')).toBeTruthy();
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
it('filters FAQs by search query', () => {
|
|
560
|
-
const { getByPlaceholderText, queryByText } = render(
|
|
561
|
-
<FAQScreen
|
|
562
|
-
categories={categories}
|
|
563
|
-
searchPlaceholder="Search"
|
|
564
|
-
emptySearchTitle="No results"
|
|
565
|
-
emptySearchMessage="Try again"
|
|
566
|
-
headerTitle="FAQ"
|
|
567
|
-
/>
|
|
568
|
-
);
|
|
569
|
-
|
|
570
|
-
const searchInput = getByPlaceholderText('Search');
|
|
571
|
-
fireEvent.changeText(searchInput, 'nonexistent');
|
|
572
|
-
|
|
573
|
-
expect(queryByText('Test Question?')).toBeNull();
|
|
574
|
-
});
|
|
575
|
-
});
|
|
576
|
-
```
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Provides comprehensive FAQ (Frequently Asked Questions) management with search functionality, categorization, and expandable items.
|
|
6
|
+
|
|
7
|
+
## File Paths
|
|
8
|
+
|
|
9
|
+
**Screens:**
|
|
10
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/presentation/screens/FAQScreen.tsx`
|
|
11
|
+
|
|
12
|
+
**Components:**
|
|
13
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/presentation/components/FAQCategory.tsx`
|
|
14
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/presentation/components/FAQItem.tsx`
|
|
15
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/presentation/components/FAQSearchBar.tsx`
|
|
16
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/presentation/components/FAQEmptyState.tsx`
|
|
17
|
+
|
|
18
|
+
**Hooks:**
|
|
19
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/presentation/hooks/useFAQSearch.ts`
|
|
20
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/presentation/hooks/useFAQExpansion.ts`
|
|
21
|
+
|
|
22
|
+
**Services:**
|
|
23
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/domain/services/FAQSearchService.ts`
|
|
24
|
+
|
|
25
|
+
**Entities:**
|
|
26
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/domain/entities/FAQEntity.ts`
|
|
27
|
+
|
|
28
|
+
**Index:**
|
|
29
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/faqs/index.ts`
|
|
30
|
+
|
|
31
|
+
## Strategy
|
|
32
|
+
|
|
33
|
+
1. **Search Optimization**: Use useFAQSearch hook with FAQSearchService for efficient search across all FAQs
|
|
34
|
+
2. **State Management**: Use useFAQExpansion hook to manage expansion state without prop drilling
|
|
35
|
+
3. **Categorization**: Organize FAQs by category for better navigation and user experience
|
|
36
|
+
4. **Performance**: Implement efficient search and rendering to handle large FAQ lists
|
|
37
|
+
5. **Empty States**: Always provide empty state UI when search returns no results
|
|
38
|
+
|
|
39
|
+
## Restrictions (Forbidden)
|
|
40
|
+
|
|
41
|
+
### DO NOT
|
|
42
|
+
- ❌ DO NOT implement custom search logic when useFAQSearch provides everything needed
|
|
43
|
+
- ❌ DO NOT manage expansion state locally when useFAQExpansion hook is available
|
|
44
|
+
- ❌ DO NOT use FAQScreen without providing all required props (categories, searchPlaceholder, emptySearchTitle, emptySearchMessage, headerTitle)
|
|
45
|
+
- ❌ DO NOT bypass FAQSearchService for search functionality
|
|
46
|
+
|
|
47
|
+
### NEVER
|
|
48
|
+
- ❌ NEVER use FAQCategory without managing expansion state properly
|
|
49
|
+
- ❌ NEVER implement FAQ search without handling empty states
|
|
50
|
+
- ❌ NEVER mix FAQ data directly with components - always use proper data structures
|
|
51
|
+
- ❌ NEVER create custom FAQ items when FAQItem component can be used
|
|
52
|
+
|
|
53
|
+
### AVOID
|
|
54
|
+
- ❌ AVOID creating complex nested search logic - use the provided search service
|
|
55
|
+
- ❌ AVOID hardcoding FAQ data in components - always pass as props
|
|
56
|
+
- ❌ AVOID using FAQScreen without proper categorization
|
|
57
|
+
- ❌ AVOID creating custom search implementations
|
|
58
|
+
|
|
59
|
+
## Rules
|
|
60
|
+
|
|
61
|
+
### ALWAYS
|
|
62
|
+
- ✅ ALWAYS provide complete categories array with id, title, and questions
|
|
63
|
+
- ✅ ALWAYS use useFAQSearch hook for search functionality
|
|
64
|
+
- ✅ ALWAYS use useFAQExpansion hook for managing expansion state
|
|
65
|
+
- ✅ ALWAYS provide empty state configuration (emptySearchTitle, emptySearchMessage)
|
|
66
|
+
- ✅ ALWAYS organize FAQs into logical categories
|
|
67
|
+
|
|
68
|
+
### MUST
|
|
69
|
+
- ✅ MUST provide searchPlaceholder, emptySearchTitle, emptySearchMessage, and headerTitle to FAQScreen
|
|
70
|
+
- ✅ MUST include unique id for each FAQ category and item
|
|
71
|
+
- ✅ MUST handle empty search results gracefully with FAQEmptyState
|
|
72
|
+
- ✅ MUST provide clear and concise answers in FAQ items
|
|
73
|
+
- ✅ MUST use FAQCategory and FAQItem components for consistency
|
|
74
|
+
|
|
75
|
+
### SHOULD
|
|
76
|
+
- ✅ SHOULD keep answers concise and easy to understand
|
|
77
|
+
- ✅ SHOULD use clear keywords in questions and answers for better search
|
|
78
|
+
- ✅ SHOULD regularly update FAQs based on user feedback
|
|
79
|
+
- ✅ SHOULD provide FAQs in all supported languages
|
|
80
|
+
- ✅ SHOULD use proper visual hierarchy with good spacing and typography
|
|
81
|
+
|
|
82
|
+
## AI Agent Guidelines
|
|
83
|
+
|
|
84
|
+
1. **Hook Usage**: Always use useFAQSearch for search functionality and useFAQExpansion for expansion state
|
|
85
|
+
2. **Data Structure**: Always structure FAQ data with categories containing id, title, and questions array
|
|
86
|
+
3. **Component Selection**: Use FAQScreen for full screens, FAQCategory for sections, FAQItem for individual items
|
|
87
|
+
4. **Search Implementation**: Always use the provided search service - never implement custom search
|
|
88
|
+
5. **Empty States**: Always provide proper empty state UI when no search results are found
|
|
577
89
|
|
|
578
90
|
## Related
|
|
579
91
|
|