@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,428 +1,95 @@
|
|
|
1
1
|
# useFeedbackForm Hook
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
## Examples
|
|
98
|
-
|
|
99
|
-
### With Callbacks
|
|
100
|
-
|
|
101
|
-
```tsx
|
|
102
|
-
function FeedbackForm() {
|
|
103
|
-
const feedbackForm = useFeedbackForm({
|
|
104
|
-
onSubmit: async (data) => {
|
|
105
|
-
await api.submitFeedback(data);
|
|
106
|
-
Alert.alert('Success', 'Thank you for your feedback!');
|
|
107
|
-
},
|
|
108
|
-
onError: (error) => {
|
|
109
|
-
Alert.alert('Error', 'Failed to submit feedback');
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<View>
|
|
115
|
-
<FeedbackTypeSelector
|
|
116
|
-
selected={feedbackForm.feedbackType}
|
|
117
|
-
onSelect={feedbackForm.setFeedbackType}
|
|
118
|
-
/>
|
|
119
|
-
<StarRating
|
|
120
|
-
rating={feedbackForm.rating}
|
|
121
|
-
onRatingChange={feedbackForm.setRating}
|
|
122
|
-
/>
|
|
123
|
-
<TextInput
|
|
124
|
-
value={feedbackForm.message}
|
|
125
|
-
onChangeText={feedbackForm.setMessage}
|
|
126
|
-
/>
|
|
127
|
-
<Button
|
|
128
|
-
onPress={feedbackForm.submitFeedback}
|
|
129
|
-
disabled={!feedbackForm.canSubmit}
|
|
130
|
-
title="Submit"
|
|
131
|
-
/>
|
|
132
|
-
</View>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### With Custom Validation
|
|
138
|
-
|
|
139
|
-
```tsx
|
|
140
|
-
function ValidatedFeedbackForm() {
|
|
141
|
-
const { feedbackType, rating, message, submitFeedback, canSubmit } = useFeedbackForm({
|
|
142
|
-
validate: (data) => {
|
|
143
|
-
const errors = {};
|
|
144
|
-
|
|
145
|
-
if (!data.feedbackType) {
|
|
146
|
-
errors.feedbackType = 'Please select a feedback type';
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (data.rating === 0) {
|
|
150
|
-
errors.rating = 'Please provide a rating';
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (data.message.length < 10) {
|
|
154
|
-
errors.message = 'Message must be at least 10 characters';
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return errors;
|
|
158
|
-
},
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<View>
|
|
163
|
-
{/* Form fields */}
|
|
164
|
-
</View>
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### With Auto-Reset
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
function AutoResetFeedbackForm() {
|
|
173
|
-
const { submitFeedback, resetForm } = useFeedbackForm({
|
|
174
|
-
autoReset: true,
|
|
175
|
-
resetDelay: 2000, // Reset after 2 seconds
|
|
176
|
-
onSubmitSuccess: () => {
|
|
177
|
-
Alert.alert('Success', 'Feedback submitted!');
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
return (
|
|
182
|
-
<View>
|
|
183
|
-
<Button onPress={submitFeedback} title="Submit" />
|
|
184
|
-
</View>
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### With Character Limit
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
function LimitedFeedbackForm() {
|
|
193
|
-
const { message, setMessage, submitFeedback, canSubmit } = useFeedbackForm({
|
|
194
|
-
maxLength: 500,
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
const remainingChars = 500 - message.length;
|
|
198
|
-
|
|
199
|
-
return (
|
|
200
|
-
<View>
|
|
201
|
-
<TextInput
|
|
202
|
-
value={message}
|
|
203
|
-
onChangeText={setMessage}
|
|
204
|
-
placeholder="Your feedback..."
|
|
205
|
-
maxLength={500}
|
|
206
|
-
multiline
|
|
207
|
-
/>
|
|
208
|
-
|
|
209
|
-
<Text>
|
|
210
|
-
{remainingChars} characters remaining
|
|
211
|
-
</Text>
|
|
212
|
-
|
|
213
|
-
<Button
|
|
214
|
-
onPress={submitFeedback}
|
|
215
|
-
disabled={!canSubmit}
|
|
216
|
-
title="Submit"
|
|
217
|
-
/>
|
|
218
|
-
</View>
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### With Categories
|
|
224
|
-
|
|
225
|
-
```tsx
|
|
226
|
-
function CategorizedFeedbackForm() {
|
|
227
|
-
const categories = [
|
|
228
|
-
{ id: 'bug', label: 'Bug Report', icon: 'bug-outline' },
|
|
229
|
-
{ id: 'feature', label: 'Feature Request', icon: 'lightbulb-outline' },
|
|
230
|
-
{ id: 'general', label: 'General Feedback', icon: 'chatbubble-outline' },
|
|
231
|
-
];
|
|
232
|
-
|
|
233
|
-
const { feedbackType, setFeedbackType, submitFeedback } = useFeedbackForm();
|
|
234
|
-
|
|
235
|
-
return (
|
|
236
|
-
<View>
|
|
237
|
-
<Text style={styles.label}>Feedback Type</Text>
|
|
238
|
-
|
|
239
|
-
{categories.map((category) => (
|
|
240
|
-
<TouchableOpacity
|
|
241
|
-
key={category.id}
|
|
242
|
-
onPress={() => setFeedbackType(category.id as FeedbackType)}
|
|
243
|
-
style={[
|
|
244
|
-
styles.category,
|
|
245
|
-
feedbackType === category.id && styles.selectedCategory,
|
|
246
|
-
]}
|
|
247
|
-
>
|
|
248
|
-
<Ionicons
|
|
249
|
-
name={category.icon}
|
|
250
|
-
size={24}
|
|
251
|
-
color={feedbackType === category.id ? 'white' : 'black'}
|
|
252
|
-
/>
|
|
253
|
-
<Text>{category.label}</Text>
|
|
254
|
-
</TouchableOpacity>
|
|
255
|
-
))}
|
|
256
|
-
|
|
257
|
-
<Button onPress={submitFeedback} title="Submit" />
|
|
258
|
-
</View>
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
## Form Options
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
interface FeedbackFormOptions {
|
|
267
|
-
onSubmit?: (data: FeedbackData) => Promise<void>;
|
|
268
|
-
onSubmitSuccess?: () => void;
|
|
269
|
-
onError?: (error: Error) => void;
|
|
270
|
-
validate?: (data: FeedbackData) => ValidationErrors;
|
|
271
|
-
autoReset?: boolean;
|
|
272
|
-
resetDelay?: number;
|
|
273
|
-
maxLength?: number;
|
|
274
|
-
minRating?: number;
|
|
275
|
-
requireMessage?: boolean;
|
|
276
|
-
minMessageLength?: number;
|
|
277
|
-
}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## Feedback Types
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
type FeedbackType =
|
|
284
|
-
| 'bug' // Bug report
|
|
285
|
-
| 'feature' // Feature request
|
|
286
|
-
| 'improvement' // Improvement suggestion
|
|
287
|
-
| 'compliment' // Positive feedback
|
|
288
|
-
| 'complaint' // Complaint
|
|
289
|
-
| 'general'; // General feedback
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
## Validation
|
|
293
|
-
|
|
294
|
-
### Default Validation
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
const defaultValidation = {
|
|
298
|
-
// Feedback type is required
|
|
299
|
-
feedbackType: (value) => !value ? 'Required' : undefined,
|
|
300
|
-
|
|
301
|
-
// Rating must be at least 1
|
|
302
|
-
rating: (value) => value === 0 ? 'Required' : undefined,
|
|
303
|
-
|
|
304
|
-
// Message must be at least 10 characters
|
|
305
|
-
message: (value) => value.length < 10 ? 'Too short' : undefined,
|
|
306
|
-
};
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
### Custom Validation Rules
|
|
310
|
-
|
|
311
|
-
```tsx
|
|
312
|
-
function CustomValidatedForm() {
|
|
313
|
-
const { message, setMessage, canSubmit } = useFeedbackForm({
|
|
314
|
-
validate: (data) => {
|
|
315
|
-
const errors = {};
|
|
316
|
-
|
|
317
|
-
// Custom feedback type validation
|
|
318
|
-
if (!data.feedbackType) {
|
|
319
|
-
errors.feedbackType = 'Please select a type';
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Custom rating validation
|
|
323
|
-
if (data.rating < 3 && data.message.length < 50) {
|
|
324
|
-
errors.message = 'Low ratings require detailed explanation';
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// Custom message validation
|
|
328
|
-
if (data.message.includes('spam')) {
|
|
329
|
-
errors.message = 'Inappropriate content detected';
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
return errors;
|
|
333
|
-
},
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
return (
|
|
337
|
-
<View>
|
|
338
|
-
<TextInput
|
|
339
|
-
value={message}
|
|
340
|
-
onChangeText={setMessage}
|
|
341
|
-
placeholder="Your feedback..."
|
|
342
|
-
/>
|
|
343
|
-
<Button disabled={!canSubmit} title="Submit" />
|
|
344
|
-
</View>
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
## Error Handling
|
|
350
|
-
|
|
351
|
-
### Display Errors
|
|
352
|
-
|
|
353
|
-
```tsx
|
|
354
|
-
function FeedbackFormWithErrorDisplay() {
|
|
355
|
-
const { errors, submitFeedback, feedbackType } = useFeedbackForm();
|
|
356
|
-
|
|
357
|
-
return (
|
|
358
|
-
<View>
|
|
359
|
-
<FeedbackTypeSelector
|
|
360
|
-
selected={feedbackType}
|
|
361
|
-
onSelect={setFeedbackType}
|
|
362
|
-
/>
|
|
363
|
-
|
|
364
|
-
{errors.feedbackType && (
|
|
365
|
-
<Text style={styles.error}>{errors.feedbackType}</Text>
|
|
366
|
-
)}
|
|
367
|
-
|
|
368
|
-
{errors.rating && (
|
|
369
|
-
<Text style={styles.error}>{errors.rating}</Text>
|
|
370
|
-
)}
|
|
371
|
-
|
|
372
|
-
{errors.message && (
|
|
373
|
-
<Text style={styles.error}>{errors.message}</Text>
|
|
374
|
-
)}
|
|
375
|
-
|
|
376
|
-
<Button onPress={submitFeedback} title="Submit" />
|
|
377
|
-
</View>
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### Submission Errors
|
|
383
|
-
|
|
384
|
-
```tsx
|
|
385
|
-
function FeedbackFormWithErrorHandling() {
|
|
386
|
-
const { submitFeedback, error, isSubmitting } = useFeedbackForm({
|
|
387
|
-
onError: (error) => {
|
|
388
|
-
console.error('Submission error:', error);
|
|
389
|
-
Alert.alert(
|
|
390
|
-
'Submission Failed',
|
|
391
|
-
'Please check your connection and try again'
|
|
392
|
-
);
|
|
393
|
-
},
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
return (
|
|
397
|
-
<View>
|
|
398
|
-
{error && <Text style={styles.error}>{error}</Text>}
|
|
399
|
-
|
|
400
|
-
<Button
|
|
401
|
-
onPress={submitFeedback}
|
|
402
|
-
disabled={isSubmitting}
|
|
403
|
-
title={isSubmitting ? 'Submitting...' : 'Submit'}
|
|
404
|
-
/>
|
|
405
|
-
</View>
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
## Best Practices
|
|
411
|
-
|
|
412
|
-
1. **Validation**: Always validate form before submission
|
|
413
|
-
2. **Feedback**: Provide immediate feedback on errors
|
|
414
|
-
3. **Loading States**: Show loading indicator during submission
|
|
415
|
-
4. **Reset**: Reset form after successful submission
|
|
416
|
-
5. **Character Limits**: Enforce reasonable message length limits
|
|
417
|
-
6. **Clear Errors**: Display clear, actionable error messages
|
|
418
|
-
7. **Accessibility**: Ensure form is accessible to all users
|
|
419
|
-
|
|
420
|
-
## Related
|
|
421
|
-
|
|
422
|
-
- **FeedbackForm**: Feedback form component
|
|
423
|
-
- **FeedbackModal**: Feedback modal component
|
|
424
|
-
- **StarRating**: Star rating component
|
|
425
|
-
|
|
426
|
-
## License
|
|
427
|
-
|
|
428
|
-
MIT
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Custom hook for managing feedback form state, validation, and submission. Provides a complete form management solution with built-in validation, error handling, and submission workflows for collecting user feedback.
|
|
6
|
+
|
|
7
|
+
## File Paths
|
|
8
|
+
|
|
9
|
+
- **useFeedbackForm**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/hooks/useFeedbackForm.ts`
|
|
10
|
+
- **Feedback Components**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/components/`
|
|
11
|
+
- **Feedback Screen**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/screens/FeedbackScreen.tsx`
|
|
12
|
+
|
|
13
|
+
## Strategy
|
|
14
|
+
|
|
15
|
+
1. **Centralized State Management**: Consolidates all feedback form state (type, rating, message) and associated logic in one place, reducing prop drilling and simplifying component implementations.
|
|
16
|
+
|
|
17
|
+
2. **Validation Framework**: Implements comprehensive validation with both default rules and support for custom validation logic, ensuring feedback data meets quality standards before submission.
|
|
18
|
+
|
|
19
|
+
3. **User Experience Optimization**: Provides immediate validation feedback, loading states during submission, and optional auto-reset functionality to create smooth, responsive form interactions.
|
|
20
|
+
|
|
21
|
+
4. **Flexible Submission Handling**: Supports custom submission handlers, success callbacks, and error handling to integrate with various backend services and analytics platforms.
|
|
22
|
+
|
|
23
|
+
5. **Character Limit Enforcement**: Includes optional character limits with real-time remaining character counts, helping users provide appropriate-length feedback.
|
|
24
|
+
|
|
25
|
+
## Restrictions
|
|
26
|
+
|
|
27
|
+
### ❌ DO NOT
|
|
28
|
+
|
|
29
|
+
- Submit feedback without validation - always check canSubmit
|
|
30
|
+
- Reset the form manually without using resetForm function
|
|
31
|
+
- Bypass loading states during submission
|
|
32
|
+
- Ignore validation errors when displaying the form
|
|
33
|
+
- Allow submission of empty or invalid feedback
|
|
34
|
+
|
|
35
|
+
### ❌ NEVER
|
|
36
|
+
|
|
37
|
+
- Mutate form state directly outside of provided setters
|
|
38
|
+
- Submit the same feedback multiple times
|
|
39
|
+
- Store sensitive user information in feedback data
|
|
40
|
+
- Disable validation without proper justification
|
|
41
|
+
- Use the hook for non-feedback form purposes
|
|
42
|
+
|
|
43
|
+
### ❌ AVOID
|
|
44
|
+
|
|
45
|
+
- Overly complex custom validation rules
|
|
46
|
+
- Excessive character limits that frustrate users
|
|
47
|
+
- Blocking UI during submission without loading indicators
|
|
48
|
+
- Immediate auto-reset without showing success message
|
|
49
|
+
- Collecting unnecessary personal information
|
|
50
|
+
|
|
51
|
+
## Rules
|
|
52
|
+
|
|
53
|
+
### ✅ ALWAYS
|
|
54
|
+
|
|
55
|
+
- Validate form before submission using canSubmit
|
|
56
|
+
- Display validation errors clearly to users
|
|
57
|
+
- Show loading state during submission (isSubmitting)
|
|
58
|
+
- Provide clear error messages on submission failure
|
|
59
|
+
- Reset form after successful submission
|
|
60
|
+
|
|
61
|
+
### ✅ MUST
|
|
62
|
+
|
|
63
|
+
- Require at minimum: feedbackType and rating
|
|
64
|
+
- Validate message length when message is required
|
|
65
|
+
- Handle submission errors gracefully
|
|
66
|
+
- Provide feedback on successful submission
|
|
67
|
+
- Prevent submission while already submitting
|
|
68
|
+
|
|
69
|
+
### ✅ SHOULD
|
|
70
|
+
|
|
71
|
+
- Use character limits for message fields (500 chars recommended)
|
|
72
|
+
- Implement auto-reset with delay (2-3 seconds)
|
|
73
|
+
- Provide context-specific validation rules
|
|
74
|
+
- Include feedback type categorization
|
|
75
|
+
- Support anonymous feedback options
|
|
76
|
+
- Test validation with various input combinations
|
|
77
|
+
|
|
78
|
+
## AI Agent Guidelines
|
|
79
|
+
|
|
80
|
+
1. **Validation Strategy**: Implement validation that provides immediate feedback. Use the errors object to display inline validation messages next to relevant form fields rather than showing a single error message.
|
|
81
|
+
|
|
82
|
+
2. **Submission Flow**: Always check canSubmit before allowing submission. Disable the submit button when canSubmit is false or isSubmitting is true. Show a loading indicator during submission to prevent duplicate submissions.
|
|
83
|
+
|
|
84
|
+
3. **Error Handling**: Display clear, actionable error messages when submission fails. Use the onError callback to log errors for debugging while showing user-friendly messages. Allow users to retry after failed submissions.
|
|
85
|
+
|
|
86
|
+
4. **User Feedback**: Provide positive feedback after successful submission. Consider using auto-reset with a 2-3 second delay to show success messages before clearing the form. Track feedback submissions for analytics.
|
|
87
|
+
|
|
88
|
+
5. **Form UX**: Group related feedback types together. Use clear labels for feedback type options. Show character count for message fields. Consider progressive disclosure - only show message field after rating is selected.
|
|
89
|
+
|
|
90
|
+
## Reference
|
|
91
|
+
|
|
92
|
+
- **Hook Implementation**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/hooks/useFeedbackForm.ts`
|
|
93
|
+
- **Feedback Screen**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/screens/FeedbackScreen.tsx`
|
|
94
|
+
- **Feedback Components**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/presentation/components/`
|
|
95
|
+
- **Types**: Check FeedbackType and related types for all available options
|