@umituz/react-native-settings 4.20.57 → 4.20.59
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/__tests__/setup.ts +1 -4
- 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 +99 -0
- 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 -442
- package/src/presentation/components/SettingsFooter/README.md +48 -427
- package/src/presentation/components/SettingsItemCard/README.md +153 -392
- 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/components/README.md +70 -295
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- 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,558 +1,84 @@
|
|
|
1
1
|
# Feedback 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
|
-
#### Props
|
|
88
|
-
|
|
89
|
-
| Prop | Type | Default | Description |
|
|
90
|
-
|------|------|---------|-------------|
|
|
91
|
-
| `visible` | `boolean` | **Required** | Modal visibility |
|
|
92
|
-
| `onClose` | `() => void` | **Required** | Close handler |
|
|
93
|
-
| `onSubmit` | `(data) => Promise<void>` | **Required** | Submit handler |
|
|
94
|
-
| `texts` | `FeedbackFormTexts` | `undefined` | Text configuration |
|
|
95
|
-
|
|
96
|
-
### SupportSection
|
|
97
|
-
|
|
98
|
-
Display support resources and contact information.
|
|
99
|
-
|
|
100
|
-
```tsx
|
|
101
|
-
import { SupportSection } from '@umituz/react-native-settings';
|
|
102
|
-
|
|
103
|
-
function MySupportSection() {
|
|
104
|
-
const supportItems = [
|
|
105
|
-
{
|
|
106
|
-
title: 'Help Center',
|
|
107
|
-
description: 'Browse our help articles',
|
|
108
|
-
onPress: () => navigation.navigate('HelpCenter'),
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
title: 'Contact Us',
|
|
112
|
-
description: 'Get in touch with our team',
|
|
113
|
-
onPress: () => Linking.openURL('mailto:support@example.com'),
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
title: 'Community',
|
|
117
|
-
description: 'Join our community forum',
|
|
118
|
-
onPress: () => Linking.openURL('https://community.example.com'),
|
|
119
|
-
},
|
|
120
|
-
];
|
|
121
|
-
|
|
122
|
-
return (
|
|
123
|
-
<SupportSection
|
|
124
|
-
title="Need Help?"
|
|
125
|
-
description="We're here to assist you"
|
|
126
|
-
items={supportItems}
|
|
127
|
-
/>
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
#### Props
|
|
133
|
-
|
|
134
|
-
| Prop | Type | Default | Description |
|
|
135
|
-
|------|------|---------|-------------|
|
|
136
|
-
| `title` | `string` | `undefined` | Section title |
|
|
137
|
-
| `description` | `string` | `undefined` | Section description |
|
|
138
|
-
| `items` | `SupportItem[]` | `[]` | Support items array |
|
|
139
|
-
|
|
140
|
-
## Hooks
|
|
141
|
-
|
|
142
|
-
### useFeedbackForm
|
|
143
|
-
|
|
144
|
-
Hook for managing feedback form state.
|
|
145
|
-
|
|
146
|
-
```tsx
|
|
147
|
-
import { useFeedbackForm } from '@umituz/react-native-settings';
|
|
148
|
-
|
|
149
|
-
function FeedbackManager() {
|
|
150
|
-
const {
|
|
151
|
-
formState,
|
|
152
|
-
setType,
|
|
153
|
-
setTitle,
|
|
154
|
-
setDescription,
|
|
155
|
-
setRating,
|
|
156
|
-
reset,
|
|
157
|
-
isValid,
|
|
158
|
-
} = useFeedbackForm({
|
|
159
|
-
type: 'general',
|
|
160
|
-
title: 'Default Title',
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
return (
|
|
164
|
-
<View>
|
|
165
|
-
<TextInput
|
|
166
|
-
value={formState.title}
|
|
167
|
-
onChangeText={setTitle}
|
|
168
|
-
placeholder="Title"
|
|
169
|
-
/>
|
|
170
|
-
<TextInput
|
|
171
|
-
value={formState.description}
|
|
172
|
-
onChangeText={setDescription}
|
|
173
|
-
placeholder="Description"
|
|
174
|
-
/>
|
|
175
|
-
<Button title="Submit" onPress={handleSubmit} disabled={!isValid} />
|
|
176
|
-
</View>
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
#### Return Value
|
|
182
|
-
|
|
183
|
-
| Property | Type | Description |
|
|
184
|
-
|----------|------|-------------|
|
|
185
|
-
| `formState` | `FeedbackFormState` | Current form state |
|
|
186
|
-
| `setType` | `(type) => void` | Set feedback type |
|
|
187
|
-
| `setTitle` | `(title) => void` | Set title |
|
|
188
|
-
| `setDescription` | `(desc) => void` | Set description |
|
|
189
|
-
| `setRating` | `(rating) => void` | Set rating (1-5) |
|
|
190
|
-
| `reset` | `() => void` | Reset form to initial state |
|
|
191
|
-
| `isValid` | `boolean` | Form validation status |
|
|
192
|
-
|
|
193
|
-
## Types
|
|
194
|
-
|
|
195
|
-
### FeedbackType
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
type FeedbackType = 'bug' | 'feature' | 'general' | 'ui' | 'performance';
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### FeedbackRating
|
|
202
|
-
|
|
203
|
-
```typescript
|
|
204
|
-
type FeedbackRating = 1 | 2 | 3 | 4 | 5;
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### FeedbackFormState
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
interface FeedbackFormState {
|
|
211
|
-
type: FeedbackType;
|
|
212
|
-
title: string;
|
|
213
|
-
description: string;
|
|
214
|
-
rating?: FeedbackRating;
|
|
215
|
-
}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### FeedbackFormTexts
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
interface FeedbackFormTexts {
|
|
222
|
-
ratingLabel: string;
|
|
223
|
-
descriptionPlaceholder: string;
|
|
224
|
-
submitButton: string;
|
|
225
|
-
submittingButton: string;
|
|
226
|
-
feedbackTypes: Array<{
|
|
227
|
-
type: FeedbackType;
|
|
228
|
-
label: string;
|
|
229
|
-
}>;
|
|
230
|
-
defaultTitle: (type: FeedbackType) => string;
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
## Examples
|
|
235
|
-
|
|
236
|
-
### Basic Feedback Form
|
|
237
|
-
|
|
238
|
-
```tsx
|
|
239
|
-
import { FeedbackForm } from '@umituz/react-native-settings';
|
|
240
|
-
|
|
241
|
-
function BasicFeedback() {
|
|
242
|
-
const handleSubmit = async (data) => {
|
|
243
|
-
console.log('Feedback submitted:', data);
|
|
244
|
-
// Send to backend
|
|
245
|
-
await fetch('/api/feedback', {
|
|
246
|
-
method: 'POST',
|
|
247
|
-
body: JSON.stringify(data),
|
|
248
|
-
});
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
const texts = {
|
|
252
|
-
ratingLabel: 'Rate your experience',
|
|
253
|
-
descriptionPlaceholder: 'What did you like or dislike?',
|
|
254
|
-
submitButton: 'Send Feedback',
|
|
255
|
-
submittingButton: 'Sending...',
|
|
256
|
-
feedbackTypes: [
|
|
257
|
-
{ type: 'general', label: 'General' },
|
|
258
|
-
{ type: 'bug', label: 'Bug Report' },
|
|
259
|
-
{ type: 'feature', label: 'Feature Request' },
|
|
260
|
-
],
|
|
261
|
-
defaultTitle: (type) => `${type} feedback`,
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
return (
|
|
265
|
-
<View style={{ padding: 20 }}>
|
|
266
|
-
<FeedbackForm onSubmit={handleSubmit} texts={texts} />
|
|
267
|
-
</View>
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Feedback Modal in Settings
|
|
273
|
-
|
|
274
|
-
```tsx
|
|
275
|
-
import { FeedbackModal } from '@umituz/react-native-settings';
|
|
276
|
-
|
|
277
|
-
function SettingsScreen() {
|
|
278
|
-
const [showFeedback, setShowFeedback] = useState(false);
|
|
279
|
-
|
|
280
|
-
return (
|
|
281
|
-
<ScreenLayout>
|
|
282
|
-
<Button
|
|
283
|
-
title="Send Feedback"
|
|
284
|
-
onPress={() => setShowFeedback(true)}
|
|
285
|
-
/>
|
|
286
|
-
|
|
287
|
-
<FeedbackModal
|
|
288
|
-
visible={showFeedback}
|
|
289
|
-
onClose={() => setShowFeedback(false)}
|
|
290
|
-
onSubmit={async (data) => {
|
|
291
|
-
await submitFeedback(data);
|
|
292
|
-
Alert.alert('Success', 'Thank you for your feedback!');
|
|
293
|
-
setShowFeedback(false);
|
|
294
|
-
}}
|
|
295
|
-
/>
|
|
296
|
-
</ScreenLayout>
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### Using the Hook
|
|
302
|
-
|
|
303
|
-
```tsx
|
|
304
|
-
import { useFeedbackForm } from '@umituz/react-native-settings';
|
|
305
|
-
|
|
306
|
-
function CustomFeedbackForm() {
|
|
307
|
-
const {
|
|
308
|
-
formState,
|
|
309
|
-
setType,
|
|
310
|
-
setTitle,
|
|
311
|
-
setDescription,
|
|
312
|
-
setRating,
|
|
313
|
-
reset,
|
|
314
|
-
isValid,
|
|
315
|
-
} = useFeedbackForm();
|
|
316
|
-
|
|
317
|
-
const handleSubmit = async () => {
|
|
318
|
-
if (!isValid) {
|
|
319
|
-
Alert.alert('Error', 'Please fill in all required fields');
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
await api.submitFeedback(formState);
|
|
324
|
-
reset();
|
|
325
|
-
Alert.alert('Success', 'Feedback submitted!');
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
return (
|
|
329
|
-
<View>
|
|
330
|
-
<Picker
|
|
331
|
-
selectedValue={formState.type}
|
|
332
|
-
onValueChange={setType}
|
|
333
|
-
>
|
|
334
|
-
<Picker.Item label="Bug" value="bug" />
|
|
335
|
-
<Picker.Item label="Feature" value="feature" />
|
|
336
|
-
<Picker.Item label="General" value="general" />
|
|
337
|
-
</Picker>
|
|
338
|
-
|
|
339
|
-
<StarRating
|
|
340
|
-
rating={formState.rating}
|
|
341
|
-
onRatingChange={setRating}
|
|
342
|
-
/>
|
|
343
|
-
|
|
344
|
-
<TextInput
|
|
345
|
-
value={formState.title}
|
|
346
|
-
onChangeText={setTitle}
|
|
347
|
-
placeholder="Title"
|
|
348
|
-
/>
|
|
349
|
-
|
|
350
|
-
<TextInput
|
|
351
|
-
value={formState.description}
|
|
352
|
-
onChangeText={setDescription}
|
|
353
|
-
placeholder="Description"
|
|
354
|
-
multiline
|
|
355
|
-
/>
|
|
356
|
-
|
|
357
|
-
<Button
|
|
358
|
-
title="Submit"
|
|
359
|
-
onPress={handleSubmit}
|
|
360
|
-
disabled={!isValid}
|
|
361
|
-
/>
|
|
362
|
-
</View>
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### Support Section
|
|
368
|
-
|
|
369
|
-
```tsx
|
|
370
|
-
import { SupportSection } from '@umituz/react-native-settings';
|
|
371
|
-
|
|
372
|
-
function HelpScreen() {
|
|
373
|
-
const supportItems = [
|
|
374
|
-
{
|
|
375
|
-
title: 'FAQ',
|
|
376
|
-
description: 'Frequently asked questions',
|
|
377
|
-
onPress: () => navigation.navigate('FAQ'),
|
|
378
|
-
iconName: 'help-circle',
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
title: 'Email Support',
|
|
382
|
-
description: 'support@example.com',
|
|
383
|
-
onPress: () => Linking.openURL('mailto:support@example.com'),
|
|
384
|
-
iconName: 'mail',
|
|
385
|
-
},
|
|
386
|
-
{
|
|
387
|
-
title: 'Live Chat',
|
|
388
|
-
description: 'Chat with our team',
|
|
389
|
-
onPress: () => openChat(),
|
|
390
|
-
iconName: 'message-circle',
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
title: 'Report Issue',
|
|
394
|
-
description: 'Report a bug or problem',
|
|
395
|
-
onPress: () => navigation.navigate('ReportIssue'),
|
|
396
|
-
iconName: 'alert-triangle',
|
|
397
|
-
},
|
|
398
|
-
];
|
|
399
|
-
|
|
400
|
-
return (
|
|
401
|
-
<ScrollView>
|
|
402
|
-
<SupportSection
|
|
403
|
-
title="Support Options"
|
|
404
|
-
items={supportItems}
|
|
405
|
-
/>
|
|
406
|
-
</ScrollView>
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### Complete Feedback Flow
|
|
412
|
-
|
|
413
|
-
```tsx
|
|
414
|
-
import { FeedbackForm, SupportSection } from '@umituz/react-native-settings';
|
|
415
|
-
|
|
416
|
-
function FeedbackScreen() {
|
|
417
|
-
const [submitted, setSubmitted] = useState(false);
|
|
418
|
-
|
|
419
|
-
if (submitted) {
|
|
420
|
-
return (
|
|
421
|
-
<View style={{ padding: 20, alignItems: 'center' }}>
|
|
422
|
-
<Icon name="check-circle" size={64} color="#10B981" />
|
|
423
|
-
<Text style={{ fontSize: 20, fontWeight: 'bold', marginTop: 16 }}>
|
|
424
|
-
Thank You!
|
|
425
|
-
</Text>
|
|
426
|
-
<Text style={{ marginTop: 8, textAlign: 'center' }}>
|
|
427
|
-
Your feedback helps us improve the app.
|
|
428
|
-
</Text>
|
|
429
|
-
|
|
430
|
-
<SupportSection
|
|
431
|
-
title="Need More Help?"
|
|
432
|
-
items={[
|
|
433
|
-
{
|
|
434
|
-
title: 'Contact Support',
|
|
435
|
-
description: 'Get direct assistance',
|
|
436
|
-
onPress: () => Linking.openURL('mailto:support@example.com'),
|
|
437
|
-
},
|
|
438
|
-
]}
|
|
439
|
-
/>
|
|
440
|
-
</View>
|
|
441
|
-
);
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
return (
|
|
445
|
-
<FeedbackForm
|
|
446
|
-
onSubmit={async (data) => {
|
|
447
|
-
await submitFeedback(data);
|
|
448
|
-
setSubmitted(true);
|
|
449
|
-
}}
|
|
450
|
-
texts={{
|
|
451
|
-
ratingLabel: 'How would you rate this app?',
|
|
452
|
-
descriptionPlaceholder: 'Tell us what you think...',
|
|
453
|
-
submitButton: 'Submit Feedback',
|
|
454
|
-
submittingButton: 'Sending...',
|
|
455
|
-
feedbackTypes: [
|
|
456
|
-
{ type: 'bug', label: 'Bug Report' },
|
|
457
|
-
{ type: 'feature', label: 'Feature Request' },
|
|
458
|
-
{ type: 'general', label: 'General' },
|
|
459
|
-
],
|
|
460
|
-
defaultTitle: (type) => `User ${type}`,
|
|
461
|
-
}}
|
|
462
|
-
/>
|
|
463
|
-
);
|
|
464
|
-
}
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
## Architecture
|
|
468
|
-
|
|
469
|
-
```
|
|
470
|
-
src/domains/feedback/
|
|
471
|
-
├── domain/
|
|
472
|
-
│ ├── entities/ # FeedbackEntity
|
|
473
|
-
│ └── repositories/ # IFeedbackRepository interface
|
|
474
|
-
├── presentation/
|
|
475
|
-
│ ├── components/
|
|
476
|
-
│ │ ├── FeedbackForm.tsx
|
|
477
|
-
│ │ ├── FeedbackModal.tsx
|
|
478
|
-
│ │ └── SupportSection.tsx
|
|
479
|
-
│ └── hooks/
|
|
480
|
-
│ └── useFeedbackForm.ts
|
|
481
|
-
└── index.ts # Public API exports
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
## Best Practices
|
|
485
|
-
|
|
486
|
-
1. **Categorize Feedback**: Use clear categories to help route feedback
|
|
487
|
-
2. **Keep it Simple**: Don't ask for too much information upfront
|
|
488
|
-
3. **Provide Context**: Explain why you're collecting feedback
|
|
489
|
-
4. **Follow Up**: Consider providing a way to track feedback status
|
|
490
|
-
5. **Validate Input**: Ensure required fields are filled before submission
|
|
491
|
-
6. **Handle Errors**: Show clear error messages for submission failures
|
|
492
|
-
7. **Confirmation**: Always show confirmation after successful submission
|
|
493
|
-
|
|
494
|
-
## Testing
|
|
495
|
-
|
|
496
|
-
```tsx
|
|
497
|
-
import { render, fireEvent, waitFor } from '@testing-library/react-native';
|
|
498
|
-
import { FeedbackForm } from '@umituz/react-native-settings';
|
|
499
|
-
|
|
500
|
-
describe('FeedbackForm', () => {
|
|
501
|
-
it('renders feedback type selector', () => {
|
|
502
|
-
const onSubmit = jest.fn();
|
|
503
|
-
const texts = {
|
|
504
|
-
ratingLabel: 'Rate',
|
|
505
|
-
descriptionPlaceholder: 'Describe',
|
|
506
|
-
submitButton: 'Submit',
|
|
507
|
-
submittingButton: 'Submitting',
|
|
508
|
-
feedbackTypes: [
|
|
509
|
-
{ type: 'bug', label: 'Bug' },
|
|
510
|
-
{ type: 'feature', label: 'Feature' },
|
|
511
|
-
],
|
|
512
|
-
defaultTitle: (t) => t,
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
const { getByText } = render(
|
|
516
|
-
<FeedbackForm onSubmit={onSubmit} texts={texts} />
|
|
517
|
-
);
|
|
518
|
-
|
|
519
|
-
expect(getByText('Bug')).toBeTruthy();
|
|
520
|
-
expect(getByText('Feature')).toBeTruthy();
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
it('submits form with correct data', async () => {
|
|
524
|
-
const onSubmit = jest.fn().mockResolvedValue(undefined);
|
|
525
|
-
const texts = {
|
|
526
|
-
ratingLabel: 'Rate',
|
|
527
|
-
descriptionPlaceholder: 'Describe',
|
|
528
|
-
submitButton: 'Submit',
|
|
529
|
-
submittingButton: 'Submitting',
|
|
530
|
-
feedbackTypes: [{ type: 'general', label: 'General' }],
|
|
531
|
-
defaultTitle: (t) => t,
|
|
532
|
-
};
|
|
533
|
-
|
|
534
|
-
const { getByText, getByPlaceholderText } = render(
|
|
535
|
-
<FeedbackForm onSubmit={onSubmit} texts={texts} />
|
|
536
|
-
);
|
|
537
|
-
|
|
538
|
-
const input = getByPlaceholderText('Describe');
|
|
539
|
-
fireEvent.changeText(input, 'Great app!');
|
|
540
|
-
|
|
541
|
-
const submitButton = getByText('Submit');
|
|
542
|
-
fireEvent.press(submitButton);
|
|
543
|
-
|
|
544
|
-
await waitFor(() => {
|
|
545
|
-
expect(onSubmit).toHaveBeenCalledWith(
|
|
546
|
-
expect.objectContaining({
|
|
547
|
-
description: 'Great app!',
|
|
548
|
-
type: 'general',
|
|
549
|
-
rating: 5,
|
|
550
|
-
})
|
|
551
|
-
);
|
|
552
|
-
});
|
|
553
|
-
});
|
|
554
|
-
});
|
|
555
|
-
```
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Provides components and utilities for collecting user feedback including feedback forms, modals, support sections, and categorization.
|
|
6
|
+
|
|
7
|
+
## File Paths
|
|
8
|
+
|
|
9
|
+
**Components:**
|
|
10
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/components/FeedbackForm.tsx`
|
|
11
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/components/FeedbackModal.tsx`
|
|
12
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/components/SupportSection.tsx`
|
|
13
|
+
|
|
14
|
+
**Hooks:**
|
|
15
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/hooks/useFeedbackForm.ts`
|
|
16
|
+
|
|
17
|
+
**Domain:**
|
|
18
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/domain/entities/FeedbackEntity.ts`
|
|
19
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/domain/repositories/IFeedbackRepository.ts`
|
|
20
|
+
|
|
21
|
+
**Index:**
|
|
22
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/index.ts`
|
|
23
|
+
|
|
24
|
+
## Strategy
|
|
25
|
+
|
|
26
|
+
1. **Form State Management**: Use useFeedbackForm hook for centralized form state and validation
|
|
27
|
+
2. **Type Categorization**: Categorize feedback by type (bug, feature, general, etc.) for better routing
|
|
28
|
+
3. **Star Rating Integration**: Integrate with Rating domain for 1-5 star ratings
|
|
29
|
+
4. **Repository Pattern**: Use IFeedbackRepository interface for abstracted feedback submission
|
|
30
|
+
5. **Validation First**: Always validate form state before submission to prevent invalid data
|
|
31
|
+
|
|
32
|
+
## Restrictions (Forbidden)
|
|
33
|
+
|
|
34
|
+
### DO NOT
|
|
35
|
+
- ❌ DO NOT submit feedback without validating required fields (type, title)
|
|
36
|
+
- ❌ DO NOT bypass the repository pattern when submitting feedback
|
|
37
|
+
- ❌ DO NOT use FeedbackForm without providing texts configuration
|
|
38
|
+
- ❌ DO NOT handle feedback submission manually when the hook provides everything needed
|
|
39
|
+
|
|
40
|
+
### NEVER
|
|
41
|
+
- ❌ NEVER use FeedbackForm without onSubmit handler
|
|
42
|
+
- ❌ NEVER submit feedback with empty or invalid form state
|
|
43
|
+
- ❌ NEVER skip error handling for feedback submission failures
|
|
44
|
+
- ❌ NEVER use feedback components without proper loading states
|
|
45
|
+
|
|
46
|
+
### AVOID
|
|
47
|
+
- ❌ AVOID creating custom feedback forms when FeedbackForm can be configured
|
|
48
|
+
- ❌ AVOID collecting too much information upfront - keep forms simple
|
|
49
|
+
- ❌ AVOID mixing feedback logic directly with UI components
|
|
50
|
+
- ❌ AVOID using FeedbackModal without handling close state
|
|
51
|
+
|
|
52
|
+
## Rules
|
|
53
|
+
|
|
54
|
+
### ALWAYS
|
|
55
|
+
- ✅ ALWAYS provide onSubmit handler when using FeedbackForm or FeedbackModal
|
|
56
|
+
- ✅ ALWAYS provide texts configuration with all required strings
|
|
57
|
+
- ✅ ALWAYS use useFeedbackForm hook for form state management
|
|
58
|
+
- ✅ ALWAYS validate form before submission (use isValid from hook)
|
|
59
|
+
- ✅ ALWAYS handle loading states during submission
|
|
60
|
+
|
|
61
|
+
### MUST
|
|
62
|
+
- ✅ MUST provide feedbackTypes array in texts configuration
|
|
63
|
+
- ✅ MUST handle submission errors gracefully with user feedback
|
|
64
|
+
- ✅ MUST show confirmation message after successful submission
|
|
65
|
+
- ✅ MUST include all required fields in form (type, title, description)
|
|
66
|
+
- ✅ MUST use TypeScript types from the domain (FeedbackType, FeedbackFormState)
|
|
67
|
+
|
|
68
|
+
### SHOULD
|
|
69
|
+
- ✅ SHOULD categorize feedback clearly to help route it correctly
|
|
70
|
+
- ✅ SHOULD provide context for why feedback is being collected
|
|
71
|
+
- ✅ SHOULD keep forms simple and don't ask for too much upfront
|
|
72
|
+
- ✅ SHOULD provide a way to track feedback status
|
|
73
|
+
- ✅ SHOULD include rating component for user satisfaction feedback
|
|
74
|
+
|
|
75
|
+
## AI Agent Guidelines
|
|
76
|
+
|
|
77
|
+
1. **Component Selection**: Use FeedbackForm for inline forms, FeedbackModal for modal-based collection, SupportSection for displaying support resources
|
|
78
|
+
2. **Hook Usage**: Always use useFeedbackForm for form state - never manage form state locally
|
|
79
|
+
3. **Configuration**: Always provide complete texts configuration including feedbackTypes array and defaultTitle function
|
|
80
|
+
4. **Validation**: Always check isValid from useFeedbackForm before enabling submission
|
|
81
|
+
5. **Error Handling**: Always handle both submission errors and success states with proper user feedback
|
|
556
82
|
|
|
557
83
|
## Related
|
|
558
84
|
|