proagents 1.6.17 → 1.6.19

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.
Files changed (185) hide show
  1. package/.claude/settings.local.json +169 -0
  2. package/.proagents/AGENTS.md +2 -0
  3. package/.proagents/AI_INSTRUCTIONS.md +13 -0
  4. package/.proagents/ANTIGRAVITY.md +2 -0
  5. package/.proagents/BOLT.md +2 -0
  6. package/.proagents/CHATGPT.md +2 -0
  7. package/.proagents/CLAUDE.md +2 -0
  8. package/.proagents/GEMINI.md +2 -0
  9. package/.proagents/GROQ.md +2 -0
  10. package/.proagents/KIRO.md +2 -0
  11. package/.proagents/LOVABLE.md +2 -0
  12. package/.proagents/PROAGENTS.md +2 -0
  13. package/.proagents/REPLIT.md +2 -0
  14. package/.proagents/prompts/00-project-setup.md +878 -0
  15. package/.proagents/prompts/04-planning.md +38 -0
  16. package/.proagents/prompts/12-rnd.md +957 -0
  17. package/.proagents/workflow-modes/entry-modes.md +27 -0
  18. package/.proagents/worklog/_context.template.md +47 -0
  19. package/COMMANDS.md +654 -0
  20. package/README.md +16 -24
  21. package/package.json +2 -7
  22. package/.proagents/ai-models/README.md +0 -141
  23. package/.proagents/ai-models/cost-management.md +0 -362
  24. package/.proagents/ai-models/fallbacks.md +0 -342
  25. package/.proagents/ai-models/model-config.md +0 -318
  26. package/.proagents/ai-models/task-routing.md +0 -503
  27. package/.proagents/ai-training/README.md +0 -155
  28. package/.proagents/ai-training/continuous-learning.md +0 -413
  29. package/.proagents/ai-training/domain-knowledge.md +0 -378
  30. package/.proagents/ai-training/pattern-learning.md +0 -455
  31. package/.proagents/ai-training/training-data.md +0 -337
  32. package/.proagents/ai-training/user-preferences.md +0 -346
  33. package/.proagents/approval-workflows/README.md +0 -146
  34. package/.proagents/approval-workflows/approval-config.md +0 -332
  35. package/.proagents/approval-workflows/approval-stages.md +0 -503
  36. package/.proagents/approval-workflows/emergency-bypass.md +0 -351
  37. package/.proagents/approval-workflows/examples.md +0 -859
  38. package/.proagents/approval-workflows/notifications.md +0 -320
  39. package/.proagents/compliance/README.md +0 -206
  40. package/.proagents/compliance/access-control.md +0 -310
  41. package/.proagents/compliance/audit-logging.md +0 -444
  42. package/.proagents/compliance/compliance-frameworks.md +0 -429
  43. package/.proagents/compliance/reports.md +0 -491
  44. package/.proagents/compliance/retention-policies.md +0 -454
  45. package/.proagents/config-versioning/README.md +0 -120
  46. package/.proagents/config-versioning/changelog.md +0 -300
  47. package/.proagents/config-versioning/rollback.md +0 -283
  48. package/.proagents/config-versioning/versioning.md +0 -330
  49. package/.proagents/contract-testing/README.md +0 -223
  50. package/.proagents/contract-testing/contract-testing.md +0 -614
  51. package/.proagents/contract-testing/pact-integration.md +0 -507
  52. package/.proagents/contract-testing/schema-validation.md +0 -565
  53. package/.proagents/dependency-management/README.md +0 -140
  54. package/.proagents/dependency-management/automation.md +0 -363
  55. package/.proagents/dependency-management/compatibility.md +0 -319
  56. package/.proagents/dependency-management/security-scanning.md +0 -413
  57. package/.proagents/dependency-management/update-policies.md +0 -374
  58. package/.proagents/disaster-recovery/README.md +0 -247
  59. package/.proagents/disaster-recovery/automation.md +0 -366
  60. package/.proagents/disaster-recovery/backup-recovery.md +0 -571
  61. package/.proagents/disaster-recovery/incident-response.md +0 -565
  62. package/.proagents/disaster-recovery/rollback-procedures.md +0 -499
  63. package/.proagents/disaster-recovery/runbooks.md +0 -603
  64. package/.proagents/disaster-recovery/scenarios.md +0 -892
  65. package/.proagents/disaster-recovery/testing.md +0 -438
  66. package/.proagents/environments/README.md +0 -244
  67. package/.proagents/environments/configuration.md +0 -437
  68. package/.proagents/environments/promotion.md +0 -434
  69. package/.proagents/environments/setup.md +0 -420
  70. package/.proagents/examples/README.md +0 -55
  71. package/.proagents/examples/backend-nodejs/README.md +0 -188
  72. package/.proagents/examples/backend-nodejs/complete-conversation.md +0 -601
  73. package/.proagents/examples/backend-nodejs/proagents.config.yaml +0 -415
  74. package/.proagents/examples/backend-nodejs/workflow-example.md +0 -909
  75. package/.proagents/examples/fullstack-nextjs/README.md +0 -155
  76. package/.proagents/examples/fullstack-nextjs/complete-conversation.md +0 -604
  77. package/.proagents/examples/fullstack-nextjs/proagents.config.yaml +0 -287
  78. package/.proagents/examples/fullstack-nextjs/workflow-example.md +0 -553
  79. package/.proagents/examples/mobile-react-native/README.md +0 -171
  80. package/.proagents/examples/mobile-react-native/complete-conversation.md +0 -825
  81. package/.proagents/examples/mobile-react-native/proagents.config.yaml +0 -330
  82. package/.proagents/examples/mobile-react-native/workflow-example.md +0 -723
  83. package/.proagents/examples/web-frontend-react/README.md +0 -125
  84. package/.proagents/examples/web-frontend-react/complete-conversation.md +0 -556
  85. package/.proagents/examples/web-frontend-react/proagents.config.yaml +0 -183
  86. package/.proagents/examples/web-frontend-react/workflow-example.md +0 -603
  87. package/.proagents/existing-projects/README.md +0 -65
  88. package/.proagents/existing-projects/challenges.md +0 -861
  89. package/.proagents/existing-projects/coexistence-mode.md +0 -483
  90. package/.proagents/existing-projects/compatibility-assessment.md +0 -541
  91. package/.proagents/existing-projects/gradual-adoption.md +0 -515
  92. package/.proagents/existing-projects/migration-strategies.md +0 -788
  93. package/.proagents/existing-projects/pattern-reconciliation.md +0 -489
  94. package/.proagents/existing-projects/team-onboarding.md +0 -617
  95. package/.proagents/existing-projects/technical-debt-handling.md +0 -644
  96. package/.proagents/feature-flags/README.md +0 -263
  97. package/.proagents/feature-flags/ab-testing.md +0 -413
  98. package/.proagents/feature-flags/configuration.md +0 -420
  99. package/.proagents/feature-flags/kill-switches.md +0 -444
  100. package/.proagents/feature-flags/rollout-strategies.md +0 -392
  101. package/.proagents/history.log +0 -12
  102. package/.proagents/i18n/README.md +0 -133
  103. package/.proagents/i18n/extraction.md +0 -433
  104. package/.proagents/i18n/tms-integration.md +0 -332
  105. package/.proagents/i18n/translation-workflow.md +0 -413
  106. package/.proagents/i18n/validation.md +0 -355
  107. package/.proagents/logging/README.md +0 -276
  108. package/.proagents/logging/aggregation.md +0 -475
  109. package/.proagents/logging/log-levels.md +0 -376
  110. package/.proagents/logging/sensitive-data.md +0 -423
  111. package/.proagents/logging/structured-logging.md +0 -406
  112. package/.proagents/metrics/README.md +0 -69
  113. package/.proagents/metrics/code-quality-kpis.md +0 -461
  114. package/.proagents/metrics/deployment-metrics.md +0 -517
  115. package/.proagents/metrics/developer-productivity.md +0 -368
  116. package/.proagents/metrics/learning-effectiveness.md +0 -478
  117. package/.proagents/migrations/README.md +0 -77
  118. package/.proagents/migrations/from-claude-projects.md +0 -313
  119. package/.proagents/migrations/from-cursor-rules.md +0 -345
  120. package/.proagents/migrations/from-custom-workflows.md +0 -410
  121. package/.proagents/monitoring/README.md +0 -308
  122. package/.proagents/monitoring/alerting.md +0 -449
  123. package/.proagents/monitoring/dashboards.md +0 -454
  124. package/.proagents/monitoring/health-checks.md +0 -436
  125. package/.proagents/monitoring/metrics.md +0 -434
  126. package/.proagents/multi-project/README.md +0 -170
  127. package/.proagents/multi-project/coordinated-deploy.md +0 -510
  128. package/.proagents/multi-project/cross-project-deps.md +0 -395
  129. package/.proagents/multi-project/unified-changelog.md +0 -477
  130. package/.proagents/multi-project/walkthroughs/monorepo-setup.md +0 -787
  131. package/.proagents/multi-project/workspace-config.md +0 -408
  132. package/.proagents/notifications/README.md +0 -151
  133. package/.proagents/notifications/channels.md +0 -457
  134. package/.proagents/notifications/preferences.md +0 -415
  135. package/.proagents/notifications/routing.md +0 -449
  136. package/.proagents/notifications/scheduling.md +0 -425
  137. package/.proagents/notifications/templates.md +0 -446
  138. package/.proagents/offline-mode/README.md +0 -145
  139. package/.proagents/offline-mode/caching.md +0 -344
  140. package/.proagents/offline-mode/offline-operations.md +0 -312
  141. package/.proagents/offline-mode/queue-specifications.md +0 -679
  142. package/.proagents/offline-mode/sync.md +0 -475
  143. package/.proagents/parallel-features/README.md +0 -85
  144. package/.proagents/parallel-features/conflict-detection.md +0 -226
  145. package/.proagents/parallel-features/dependency-management.md +0 -392
  146. package/.proagents/parallel-features/merge-coordination.md +0 -506
  147. package/.proagents/parallel-features/tracking-system.md +0 -416
  148. package/.proagents/performance/README.md +0 -59
  149. package/.proagents/performance/bundle-analysis.md +0 -375
  150. package/.proagents/performance/load-testing.md +0 -563
  151. package/.proagents/performance/runtime-metrics.md +0 -489
  152. package/.proagents/performance/web-vitals.md +0 -425
  153. package/.proagents/plugins/README.md +0 -139
  154. package/.proagents/plugins/creating-plugins.md +0 -504
  155. package/.proagents/plugins/plugin-api.md +0 -467
  156. package/.proagents/plugins/plugin-registry.md +0 -276
  157. package/.proagents/reporting/README.md +0 -158
  158. package/.proagents/reporting/dashboards.md +0 -366
  159. package/.proagents/reporting/exports.md +0 -524
  160. package/.proagents/reporting/quality-metrics.md +0 -385
  161. package/.proagents/reporting/templates/README.md +0 -56
  162. package/.proagents/reporting/templates/dashboard-config.json +0 -187
  163. package/.proagents/reporting/templates/metrics-queries.md +0 -427
  164. package/.proagents/reporting/templates/react-dashboard.tsx +0 -544
  165. package/.proagents/reporting/templates/widgets.md +0 -451
  166. package/.proagents/reporting/velocity-metrics.md +0 -340
  167. package/.proagents/reverse-engineering/README.md +0 -151
  168. package/.proagents/reverse-engineering/architecture-extraction.md +0 -325
  169. package/.proagents/reverse-engineering/code-analysis.md +0 -377
  170. package/.proagents/reverse-engineering/dependency-mapping.md +0 -567
  171. package/.proagents/reverse-engineering/diagram-generation.md +0 -586
  172. package/.proagents/reverse-engineering/documentation-generation.md +0 -468
  173. package/.proagents/reverse-engineering/pattern-detection.md +0 -569
  174. package/.proagents/reverse-engineering/quality-assessment.md +0 -733
  175. package/.proagents/secrets/README.md +0 -278
  176. package/.proagents/secrets/access-control.md +0 -443
  177. package/.proagents/secrets/rotation.md +0 -403
  178. package/.proagents/secrets/scanning.md +0 -487
  179. package/.proagents/secrets/storage.md +0 -394
  180. package/.proagents/webhooks/README.md +0 -126
  181. package/.proagents/webhooks/endpoints.md +0 -298
  182. package/.proagents/webhooks/events.md +0 -316
  183. package/.proagents/webhooks/payloads.md +0 -325
  184. package/.proagents/webhooks/reliability.md +0 -363
  185. package/.proagents/webhooks/security.md +0 -380
@@ -1,825 +0,0 @@
1
- # Complete Conversation: React Native Notification Settings
2
-
3
- A full walkthrough of building a notification settings screen in a React Native application.
4
-
5
- ---
6
-
7
- ## Feature Request
8
-
9
- **User:** I need to add a notification settings screen where users can control push notifications, in-app alerts, and notification sounds. It should work on both iOS and Android.
10
-
11
- ---
12
-
13
- ## Phase 0: Initialization
14
-
15
- **AI:** I'll help you build a notification settings feature for your React Native app. Let me analyze your codebase first.
16
-
17
- ```
18
- Starting ProAgents workflow...
19
- Mode: Full Workflow
20
- Feature: Notification Settings Screen
21
- Branch: feature/notification-settings
22
- Platform: iOS + Android
23
- ```
24
-
25
- ---
26
-
27
- ## Phase 1: Codebase Analysis
28
-
29
- **AI:** I've analyzed your React Native project. Here's what I found:
30
-
31
- ### Project Structure
32
- ```
33
- src/
34
- ├── screens/
35
- │ ├── HomeScreen.tsx
36
- │ ├── ProfileScreen.tsx
37
- │ └── SettingsScreen.tsx
38
- ├── components/
39
- │ ├── ui/
40
- │ │ ├── Button.tsx
41
- │ │ ├── Switch.tsx
42
- │ │ └── Card.tsx
43
- │ └── common/
44
- ├── navigation/
45
- │ ├── RootNavigator.tsx
46
- │ └── types.ts
47
- ├── hooks/
48
- │ ├── useAuth.ts
49
- │ └── useStorage.ts
50
- ├── services/
51
- │ ├── api.ts
52
- │ └── notifications.ts
53
- ├── stores/
54
- │ └── userStore.ts
55
- └── utils/
56
- └── platform.ts
57
- ```
58
-
59
- ### Patterns Detected
60
- - **Framework:** React Native 0.72 (Expo managed)
61
- - **Navigation:** React Navigation 6
62
- - **State:** Zustand for global state
63
- - **Storage:** AsyncStorage for persistence
64
- - **Styling:** StyleSheet with custom theme
65
- - **Testing:** Jest + React Native Testing Library
66
-
67
- ### Existing Conventions
68
- - Functional components with TypeScript
69
- - Custom hooks for reusable logic
70
- - Platform-specific code uses `Platform.select()`
71
- - All screens follow consistent layout pattern
72
-
73
- **Checkpoint: Analysis Complete**
74
- Proceed with these patterns? [Yes/Modify]
75
-
76
- **User:** Yes, proceed.
77
-
78
- ---
79
-
80
- ## Phase 2: Requirements
81
-
82
- **AI:** Let me clarify the notification settings requirements.
83
-
84
- ### Feature Requirements
85
-
86
- **1. Push Notifications**
87
- - Master toggle for all push notifications
88
- - Category toggles (messages, updates, promotions)
89
- - Quiet hours configuration
90
-
91
- **2. In-App Alerts**
92
- - Badge count toggle
93
- - In-app banner toggle
94
- - Vibration toggle
95
-
96
- **3. Sound Settings**
97
- - Notification sound toggle
98
- - Sound selection (platform native picker)
99
- - Volume control
100
-
101
- **4. Platform Considerations**
102
- - iOS: Request notification permissions
103
- - Android: Channel management
104
- - Both: Deep link to system settings
105
-
106
- ### Technical Requirements
107
- - Persist settings locally with AsyncStorage
108
- - Sync settings with backend API
109
- - Handle permission states gracefully
110
- - Support offline mode
111
-
112
- **User:** Perfect, that covers everything I need.
113
-
114
- ---
115
-
116
- ## Phase 3: Design
117
-
118
- **AI:** Based on your existing UI patterns, here's the design:
119
-
120
- ### Screen Layout
121
- ```
122
- ┌─────────────────────────────┐
123
- │ ← Notification Settings │
124
- ├─────────────────────────────┤
125
- │ │
126
- │ ┌─────────────────────────┐ │
127
- │ │ Push Notifications │ │
128
- │ │ ─────────────────────── │ │
129
- │ │ Enable All [===] │ │
130
- │ │ Messages [===] │ │
131
- │ │ Updates [===] │ │
132
- │ │ Promotions [ = ] │ │
133
- │ └─────────────────────────┘ │
134
- │ │
135
- │ ┌─────────────────────────┐ │
136
- │ │ In-App Alerts │ │
137
- │ │ ─────────────────────── │ │
138
- │ │ Show Badges [===] │ │
139
- │ │ Show Banners [===] │ │
140
- │ │ Vibration [===] │ │
141
- │ └─────────────────────────┘ │
142
- │ │
143
- │ ┌─────────────────────────┐ │
144
- │ │ Sounds │ │
145
- │ │ ─────────────────────── │ │
146
- │ │ Enable Sound [===] │ │
147
- │ │ Sound: Default [>] │ │
148
- │ └─────────────────────────┘ │
149
- │ │
150
- │ [Open System Settings] │
151
- │ │
152
- └─────────────────────────────┘
153
- ```
154
-
155
- ### Component Hierarchy
156
- ```tsx
157
- <NotificationSettingsScreen>
158
- <ScrollView>
159
- <SettingsSection title="Push Notifications">
160
- <SettingsToggle />
161
- <SettingsToggle />
162
- </SettingsSection>
163
- <SettingsSection title="In-App Alerts">
164
- <SettingsToggle />
165
- </SettingsSection>
166
- <SettingsSection title="Sounds">
167
- <SettingsToggle />
168
- <SettingsLink />
169
- </SettingsSection>
170
- <SystemSettingsButton />
171
- </ScrollView>
172
- </NotificationSettingsScreen>
173
- ```
174
-
175
- **Checkpoint: Design Complete**
176
- Ready to implement? [Yes/Modify]
177
-
178
- **User:** Yes.
179
-
180
- ---
181
-
182
- ## Phase 4: Implementation Plan
183
-
184
- **AI:** Here's the implementation plan:
185
-
186
- ### Files to Create
187
- 1. `src/screens/NotificationSettingsScreen.tsx`
188
- 2. `src/components/settings/SettingsSection.tsx`
189
- 3. `src/components/settings/SettingsToggle.tsx`
190
- 4. `src/components/settings/SettingsLink.tsx`
191
- 5. `src/hooks/useNotificationSettings.ts`
192
- 6. `src/services/notificationSettings.ts`
193
- 7. `src/types/notifications.ts`
194
- 8. `__tests__/screens/NotificationSettingsScreen.test.tsx`
195
- 9. `__tests__/hooks/useNotificationSettings.test.ts`
196
-
197
- ### Files to Modify
198
- 1. `src/navigation/RootNavigator.tsx` - Add new screen
199
- 2. `src/navigation/types.ts` - Add route types
200
- 3. `src/screens/SettingsScreen.tsx` - Add navigation link
201
-
202
- ### Implementation Order
203
- 1. Types and interfaces
204
- 2. Service layer (API + storage)
205
- 3. Custom hook
206
- 4. UI components
207
- 5. Main screen
208
- 6. Navigation integration
209
- 7. Tests
210
-
211
- ---
212
-
213
- ## Phase 5: Implementation
214
-
215
- **AI:** Starting implementation.
216
-
217
- ### Step 1: Types
218
-
219
- ```typescript
220
- // src/types/notifications.ts
221
- export interface NotificationSettings {
222
- // Push notifications
223
- pushEnabled: boolean;
224
- pushMessages: boolean;
225
- pushUpdates: boolean;
226
- pushPromotions: boolean;
227
-
228
- // In-app
229
- showBadges: boolean;
230
- showBanners: boolean;
231
- vibrationEnabled: boolean;
232
-
233
- // Sounds
234
- soundEnabled: boolean;
235
- soundName: string;
236
- }
237
-
238
- export const defaultNotificationSettings: NotificationSettings = {
239
- pushEnabled: true,
240
- pushMessages: true,
241
- pushUpdates: true,
242
- pushPromotions: false,
243
- showBadges: true,
244
- showBanners: true,
245
- vibrationEnabled: true,
246
- soundEnabled: true,
247
- soundName: 'default',
248
- };
249
- ```
250
-
251
- ### Step 2: Service Layer
252
-
253
- ```typescript
254
- // src/services/notificationSettings.ts
255
- import AsyncStorage from '@react-native-async-storage/async-storage';
256
- import { NotificationSettings, defaultNotificationSettings } from '@/types/notifications';
257
- import { api } from './api';
258
-
259
- const STORAGE_KEY = '@notification_settings';
260
-
261
- export const notificationSettingsService = {
262
- async getLocal(): Promise<NotificationSettings> {
263
- try {
264
- const stored = await AsyncStorage.getItem(STORAGE_KEY);
265
- if (stored) {
266
- return { ...defaultNotificationSettings, ...JSON.parse(stored) };
267
- }
268
- return defaultNotificationSettings;
269
- } catch (error) {
270
- console.error('Failed to get notification settings:', error);
271
- return defaultNotificationSettings;
272
- }
273
- },
274
-
275
- async saveLocal(settings: NotificationSettings): Promise<void> {
276
- try {
277
- await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(settings));
278
- } catch (error) {
279
- console.error('Failed to save notification settings:', error);
280
- throw error;
281
- }
282
- },
283
-
284
- async syncWithServer(settings: NotificationSettings): Promise<void> {
285
- try {
286
- await api.patch('/user/notification-settings', settings);
287
- } catch (error) {
288
- console.error('Failed to sync with server:', error);
289
- // Don't throw - offline support
290
- }
291
- },
292
-
293
- async fetchFromServer(): Promise<NotificationSettings | null> {
294
- try {
295
- const response = await api.get('/user/notification-settings');
296
- return response.data;
297
- } catch (error) {
298
- console.error('Failed to fetch from server:', error);
299
- return null;
300
- }
301
- },
302
- };
303
- ```
304
-
305
- ### Step 3: Custom Hook
306
-
307
- ```typescript
308
- // src/hooks/useNotificationSettings.ts
309
- import { useState, useEffect, useCallback } from 'react';
310
- import { Platform, Linking } from 'react-native';
311
- import * as Notifications from 'expo-notifications';
312
- import { NotificationSettings, defaultNotificationSettings } from '@/types/notifications';
313
- import { notificationSettingsService } from '@/services/notificationSettings';
314
-
315
- export function useNotificationSettings() {
316
- const [settings, setSettings] = useState<NotificationSettings>(defaultNotificationSettings);
317
- const [loading, setLoading] = useState(true);
318
- const [permissionStatus, setPermissionStatus] = useState<string>('undetermined');
319
-
320
- // Load settings on mount
321
- useEffect(() => {
322
- loadSettings();
323
- checkPermissions();
324
- }, []);
325
-
326
- const loadSettings = async () => {
327
- setLoading(true);
328
- try {
329
- // Try server first, fall back to local
330
- const serverSettings = await notificationSettingsService.fetchFromServer();
331
- if (serverSettings) {
332
- setSettings(serverSettings);
333
- await notificationSettingsService.saveLocal(serverSettings);
334
- } else {
335
- const localSettings = await notificationSettingsService.getLocal();
336
- setSettings(localSettings);
337
- }
338
- } finally {
339
- setLoading(false);
340
- }
341
- };
342
-
343
- const checkPermissions = async () => {
344
- const { status } = await Notifications.getPermissionsAsync();
345
- setPermissionStatus(status);
346
- };
347
-
348
- const requestPermissions = async () => {
349
- const { status } = await Notifications.requestPermissionsAsync();
350
- setPermissionStatus(status);
351
- return status === 'granted';
352
- };
353
-
354
- const updateSetting = useCallback(async <K extends keyof NotificationSettings>(
355
- key: K,
356
- value: NotificationSettings[K]
357
- ) => {
358
- const newSettings = { ...settings, [key]: value };
359
- setSettings(newSettings);
360
-
361
- // Save locally immediately
362
- await notificationSettingsService.saveLocal(newSettings);
363
-
364
- // Sync with server in background
365
- notificationSettingsService.syncWithServer(newSettings);
366
- }, [settings]);
367
-
368
- const openSystemSettings = useCallback(() => {
369
- if (Platform.OS === 'ios') {
370
- Linking.openURL('app-settings:');
371
- } else {
372
- Linking.openSettings();
373
- }
374
- }, []);
375
-
376
- return {
377
- settings,
378
- loading,
379
- permissionStatus,
380
- updateSetting,
381
- requestPermissions,
382
- openSystemSettings,
383
- refresh: loadSettings,
384
- };
385
- }
386
- ```
387
-
388
- ### Step 4: UI Components
389
-
390
- ```tsx
391
- // src/components/settings/SettingsSection.tsx
392
- import React from 'react';
393
- import { View, Text, StyleSheet } from 'react-native';
394
-
395
- interface SettingsSectionProps {
396
- title: string;
397
- children: React.ReactNode;
398
- }
399
-
400
- export function SettingsSection({ title, children }: SettingsSectionProps) {
401
- return (
402
- <View style={styles.container}>
403
- <Text style={styles.title}>{title}</Text>
404
- <View style={styles.content}>{children}</View>
405
- </View>
406
- );
407
- }
408
-
409
- const styles = StyleSheet.create({
410
- container: {
411
- marginBottom: 24,
412
- },
413
- title: {
414
- fontSize: 14,
415
- fontWeight: '600',
416
- color: '#666',
417
- marginBottom: 8,
418
- paddingHorizontal: 16,
419
- textTransform: 'uppercase',
420
- },
421
- content: {
422
- backgroundColor: '#fff',
423
- borderRadius: 12,
424
- overflow: 'hidden',
425
- },
426
- });
427
- ```
428
-
429
- ```tsx
430
- // src/components/settings/SettingsToggle.tsx
431
- import React from 'react';
432
- import { View, Text, Switch, StyleSheet } from 'react-native';
433
-
434
- interface SettingsToggleProps {
435
- label: string;
436
- description?: string;
437
- value: boolean;
438
- onValueChange: (value: boolean) => void;
439
- disabled?: boolean;
440
- }
441
-
442
- export function SettingsToggle({
443
- label,
444
- description,
445
- value,
446
- onValueChange,
447
- disabled = false,
448
- }: SettingsToggleProps) {
449
- return (
450
- <View style={[styles.container, disabled && styles.disabled]}>
451
- <View style={styles.textContainer}>
452
- <Text style={styles.label}>{label}</Text>
453
- {description && <Text style={styles.description}>{description}</Text>}
454
- </View>
455
- <Switch
456
- value={value}
457
- onValueChange={onValueChange}
458
- disabled={disabled}
459
- trackColor={{ false: '#e0e0e0', true: '#4CAF50' }}
460
- thumbColor="#fff"
461
- />
462
- </View>
463
- );
464
- }
465
-
466
- const styles = StyleSheet.create({
467
- container: {
468
- flexDirection: 'row',
469
- alignItems: 'center',
470
- justifyContent: 'space-between',
471
- padding: 16,
472
- borderBottomWidth: StyleSheet.hairlineWidth,
473
- borderBottomColor: '#e0e0e0',
474
- },
475
- disabled: {
476
- opacity: 0.5,
477
- },
478
- textContainer: {
479
- flex: 1,
480
- marginRight: 16,
481
- },
482
- label: {
483
- fontSize: 16,
484
- color: '#333',
485
- },
486
- description: {
487
- fontSize: 13,
488
- color: '#666',
489
- marginTop: 2,
490
- },
491
- });
492
- ```
493
-
494
- ### Step 5: Main Screen
495
-
496
- ```tsx
497
- // src/screens/NotificationSettingsScreen.tsx
498
- import React from 'react';
499
- import { ScrollView, StyleSheet, Alert } from 'react-native';
500
- import { SettingsSection } from '@/components/settings/SettingsSection';
501
- import { SettingsToggle } from '@/components/settings/SettingsToggle';
502
- import { SettingsLink } from '@/components/settings/SettingsLink';
503
- import { Button } from '@/components/ui/Button';
504
- import { useNotificationSettings } from '@/hooks/useNotificationSettings';
505
- import { LoadingScreen } from '@/components/common/LoadingScreen';
506
-
507
- export function NotificationSettingsScreen() {
508
- const {
509
- settings,
510
- loading,
511
- permissionStatus,
512
- updateSetting,
513
- requestPermissions,
514
- openSystemSettings,
515
- } = useNotificationSettings();
516
-
517
- if (loading) {
518
- return <LoadingScreen />;
519
- }
520
-
521
- const handlePushToggle = async (value: boolean) => {
522
- if (value && permissionStatus !== 'granted') {
523
- const granted = await requestPermissions();
524
- if (!granted) {
525
- Alert.alert(
526
- 'Permission Required',
527
- 'Please enable notifications in your device settings.',
528
- [
529
- { text: 'Cancel', style: 'cancel' },
530
- { text: 'Open Settings', onPress: openSystemSettings },
531
- ]
532
- );
533
- return;
534
- }
535
- }
536
- updateSetting('pushEnabled', value);
537
- };
538
-
539
- return (
540
- <ScrollView style={styles.container}>
541
- <SettingsSection title="Push Notifications">
542
- <SettingsToggle
543
- label="Enable Push Notifications"
544
- description="Receive notifications when the app is closed"
545
- value={settings.pushEnabled}
546
- onValueChange={handlePushToggle}
547
- />
548
- <SettingsToggle
549
- label="Messages"
550
- description="New messages and replies"
551
- value={settings.pushMessages}
552
- onValueChange={(v) => updateSetting('pushMessages', v)}
553
- disabled={!settings.pushEnabled}
554
- />
555
- <SettingsToggle
556
- label="Updates"
557
- description="App updates and new features"
558
- value={settings.pushUpdates}
559
- onValueChange={(v) => updateSetting('pushUpdates', v)}
560
- disabled={!settings.pushEnabled}
561
- />
562
- <SettingsToggle
563
- label="Promotions"
564
- description="Special offers and discounts"
565
- value={settings.pushPromotions}
566
- onValueChange={(v) => updateSetting('pushPromotions', v)}
567
- disabled={!settings.pushEnabled}
568
- />
569
- </SettingsSection>
570
-
571
- <SettingsSection title="In-App Alerts">
572
- <SettingsToggle
573
- label="Show Badge Count"
574
- description="Display unread count on app icon"
575
- value={settings.showBadges}
576
- onValueChange={(v) => updateSetting('showBadges', v)}
577
- />
578
- <SettingsToggle
579
- label="Show Banners"
580
- description="Display in-app notification banners"
581
- value={settings.showBanners}
582
- onValueChange={(v) => updateSetting('showBanners', v)}
583
- />
584
- <SettingsToggle
585
- label="Vibration"
586
- description="Vibrate on notifications"
587
- value={settings.vibrationEnabled}
588
- onValueChange={(v) => updateSetting('vibrationEnabled', v)}
589
- />
590
- </SettingsSection>
591
-
592
- <SettingsSection title="Sounds">
593
- <SettingsToggle
594
- label="Notification Sound"
595
- description="Play sound for notifications"
596
- value={settings.soundEnabled}
597
- onValueChange={(v) => updateSetting('soundEnabled', v)}
598
- />
599
- <SettingsLink
600
- label="Sound"
601
- value={settings.soundName}
602
- onPress={() => {/* Open sound picker */}}
603
- disabled={!settings.soundEnabled}
604
- />
605
- </SettingsSection>
606
-
607
- <Button
608
- title="Open System Settings"
609
- variant="outline"
610
- onPress={openSystemSettings}
611
- style={styles.systemButton}
612
- />
613
- </ScrollView>
614
- );
615
- }
616
-
617
- const styles = StyleSheet.create({
618
- container: {
619
- flex: 1,
620
- backgroundColor: '#f5f5f5',
621
- padding: 16,
622
- },
623
- systemButton: {
624
- marginTop: 8,
625
- marginBottom: 32,
626
- },
627
- });
628
- ```
629
-
630
- ---
631
-
632
- ## Phase 6: Testing
633
-
634
- **AI:** Creating comprehensive tests.
635
-
636
- ### Hook Tests
637
-
638
- ```typescript
639
- // __tests__/hooks/useNotificationSettings.test.ts
640
- import { renderHook, act, waitFor } from '@testing-library/react-native';
641
- import { useNotificationSettings } from '@/hooks/useNotificationSettings';
642
- import { notificationSettingsService } from '@/services/notificationSettings';
643
-
644
- jest.mock('@/services/notificationSettings');
645
- jest.mock('expo-notifications', () => ({
646
- getPermissionsAsync: jest.fn().mockResolvedValue({ status: 'granted' }),
647
- requestPermissionsAsync: jest.fn().mockResolvedValue({ status: 'granted' }),
648
- }));
649
-
650
- describe('useNotificationSettings', () => {
651
- beforeEach(() => {
652
- jest.clearAllMocks();
653
- });
654
-
655
- it('loads settings on mount', async () => {
656
- const mockSettings = {
657
- pushEnabled: true,
658
- pushMessages: false,
659
- };
660
-
661
- (notificationSettingsService.fetchFromServer as jest.Mock)
662
- .mockResolvedValue(mockSettings);
663
-
664
- const { result } = renderHook(() => useNotificationSettings());
665
-
666
- await waitFor(() => {
667
- expect(result.current.loading).toBe(false);
668
- });
669
-
670
- expect(result.current.settings.pushMessages).toBe(false);
671
- });
672
-
673
- it('updates setting and saves locally', async () => {
674
- (notificationSettingsService.fetchFromServer as jest.Mock)
675
- .mockResolvedValue(null);
676
- (notificationSettingsService.getLocal as jest.Mock)
677
- .mockResolvedValue({ pushEnabled: true });
678
-
679
- const { result } = renderHook(() => useNotificationSettings());
680
-
681
- await waitFor(() => {
682
- expect(result.current.loading).toBe(false);
683
- });
684
-
685
- await act(async () => {
686
- await result.current.updateSetting('pushEnabled', false);
687
- });
688
-
689
- expect(notificationSettingsService.saveLocal).toHaveBeenCalledWith(
690
- expect.objectContaining({ pushEnabled: false })
691
- );
692
- });
693
- });
694
- ```
695
-
696
- ### Screen Tests
697
-
698
- ```typescript
699
- // __tests__/screens/NotificationSettingsScreen.test.tsx
700
- import React from 'react';
701
- import { render, fireEvent, waitFor } from '@testing-library/react-native';
702
- import { NotificationSettingsScreen } from '@/screens/NotificationSettingsScreen';
703
-
704
- jest.mock('@/hooks/useNotificationSettings', () => ({
705
- useNotificationSettings: () => ({
706
- settings: {
707
- pushEnabled: true,
708
- pushMessages: true,
709
- pushUpdates: true,
710
- pushPromotions: false,
711
- showBadges: true,
712
- showBanners: true,
713
- vibrationEnabled: true,
714
- soundEnabled: true,
715
- soundName: 'default',
716
- },
717
- loading: false,
718
- permissionStatus: 'granted',
719
- updateSetting: jest.fn(),
720
- requestPermissions: jest.fn(),
721
- openSystemSettings: jest.fn(),
722
- }),
723
- }));
724
-
725
- describe('NotificationSettingsScreen', () => {
726
- it('renders all settings sections', () => {
727
- const { getByText } = render(<NotificationSettingsScreen />);
728
-
729
- expect(getByText('Push Notifications')).toBeTruthy();
730
- expect(getByText('In-App Alerts')).toBeTruthy();
731
- expect(getByText('Sounds')).toBeTruthy();
732
- });
733
-
734
- it('disables child toggles when push is disabled', () => {
735
- // Test that Messages, Updates, Promotions toggles are disabled
736
- // when pushEnabled is false
737
- });
738
-
739
- it('handles permission request when enabling push', async () => {
740
- const mockRequestPermissions = jest.fn().mockResolvedValue(true);
741
-
742
- jest.mock('@/hooks/useNotificationSettings', () => ({
743
- useNotificationSettings: () => ({
744
- settings: { pushEnabled: false },
745
- permissionStatus: 'undetermined',
746
- requestPermissions: mockRequestPermissions,
747
- }),
748
- }));
749
-
750
- // Test permission flow
751
- });
752
- });
753
- ```
754
-
755
- **Test Results:**
756
- ```
757
- ✓ Hook tests: 8 passed
758
- ✓ Component tests: 12 passed
759
- ✓ Screen tests: 6 passed
760
- Coverage: 85%
761
- ```
762
-
763
- ---
764
-
765
- ## Phase 7: Documentation
766
-
767
- **AI:** Feature documentation created.
768
-
769
- ### Usage Guide
770
-
771
- ```markdown
772
- ## Notification Settings
773
-
774
- Navigate to Settings > Notifications to configure:
775
-
776
- ### Push Notifications
777
- Control which push notifications you receive:
778
- - Messages: New messages and replies
779
- - Updates: App updates and features
780
- - Promotions: Special offers (off by default)
781
-
782
- ### In-App Alerts
783
- - Badge Count: Show unread count on app icon
784
- - Banners: Show notification banners in-app
785
- - Vibration: Vibrate for notifications
786
-
787
- ### Sounds
788
- - Enable/disable notification sounds
789
- - Select custom notification sound
790
-
791
- ### System Settings
792
- Tap "Open System Settings" for advanced OS-level notification configuration.
793
- ```
794
-
795
- ---
796
-
797
- ## Phase 8: Deployment Preparation
798
-
799
- **AI:** Pre-deployment checklist:
800
-
801
- - [x] All tests passing
802
- - [x] iOS permissions handled
803
- - [x] Android channels configured
804
- - [x] Offline mode working
805
- - [x] Settings persist correctly
806
- - [x] Both platforms tested
807
-
808
- **Ready for deployment.**
809
-
810
- ---
811
-
812
- ## Summary
813
-
814
- **Feature Complete:** Notification Settings Screen
815
-
816
- **Files Created:** 9
817
- **Files Modified:** 3
818
- **Tests Added:** 26
819
- **Coverage:** 85%
820
-
821
- **Platforms Tested:**
822
- - iOS Simulator (iPhone 14)
823
- - Android Emulator (Pixel 6)
824
-
825
- **PR Ready:** `feature/notification-settings` → `main`