create-ern-boilerplate 0.0.21 → 0.0.22

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 (64) hide show
  1. package/package.json +1 -1
  2. package/templates/default_draft/README.md +3 -0
  3. package/templates/{simple/app/(admin)/profile.tsx → default_draft/app/(admin)/draft_profile.tsx} +5 -5
  4. package/templates/{simple/app/(admin)/user-management.tsx → default_draft/app/(admin)/draft_userManagement.tsx} +4 -4
  5. package/templates/{simple → default_draft}/app/(auth)/_layout.tsx +2 -2
  6. package/templates/{simple/app/(auth)/login.tsx → default_draft/app/(auth)/draft_login.tsx} +5 -5
  7. package/templates/{simple/app/(auth)/register.tsx → default_draft/app/(auth)/draft_register.tsx} +4 -4
  8. package/templates/{simple → default_draft}/app/(protected)/_layout.tsx +5 -5
  9. package/templates/{simple/app/(protected)/home.tsx → default_draft/app/(protected)/draft_home.tsx} +4 -4
  10. package/templates/{simple/app/(protected)/settings.tsx → default_draft/app/(protected)/draft_settings.tsx} +6 -6
  11. package/templates/{simple → default_draft}/app/_layout.tsx +2 -2
  12. package/templates/{simple → default_draft}/src/components/auth/ProtectedRoute.tsx +2 -2
  13. package/templates/{simple → default_draft}/src/components/common/Card.tsx +1 -1
  14. package/templates/{simple → default_draft}/src/components/common/Input.tsx +1 -1
  15. package/templates/{simple → default_draft}/src/components/common/Loading.tsx +1 -1
  16. package/templates/{simple → default_draft}/src/components/users/FilterModal.tsx +1 -1
  17. package/templates/{simple → default_draft}/src/components/users/UserCard.tsx +1 -1
  18. package/templates/{simple → default_draft}/src/components/users/UserFormModal.tsx +1 -1
  19. package/templates/{simple/src/contexts/AuthContext.tsx → default_draft/src/contexts/draft_AuthContext.tsx} +6 -6
  20. package/templates/{simple/src/contexts/ThemeContext.tsx → default_draft/src/contexts/draft_ThemeContext.tsx} +2 -2
  21. package/templates/{simple/src/hooks/useAuth.ts → default_draft/src/hooks/draft_useAuth.ts} +1 -1
  22. package/templates/{simple/src/hooks/useTheme.ts → default_draft/src/hooks/draft_useTheme.ts} +1 -1
  23. package/templates/{simple/src/hooks/useUsers.ts → default_draft/src/hooks/draft_useUsers.ts} +2 -2
  24. package/templates/{simple/src/services/api.ts → default_draft/src/services/draft_api.ts} +3 -3
  25. package/templates/{simple/src/services/authService.ts → default_draft/src/services/draft_authService.ts} +3 -3
  26. package/templates/{simple/src/services/productService.ts → default_draft/src/services/draft_productService.ts} +3 -3
  27. package/templates/{simple/src/services/userService.ts → default_draft/src/services/draft_userService.ts} +3 -3
  28. package/templates/{simple/src/services/mockApi/auth.mock.ts → default_draft/src/services/mockApi/draft_auth.mock.ts} +1 -1
  29. package/templates/{simple/src/services/mockApi/categories.mock.ts → default_draft/src/services/mockApi/draft_categories.mock.ts} +1 -1
  30. package/templates/{simple/src/services/mockApi/products.mock.ts → default_draft/src/services/mockApi/draft_products.mock.ts} +1 -1
  31. package/templates/{simple/src/services/mockApi/users.mock.ts → default_draft/src/services/mockApi/draft_users.mock.ts} +2 -2
  32. package/templates/{simple → default_draft}/src/services/mockApi/index.ts +4 -4
  33. package/templates/{simple/src/utils/validation.ts → default_draft/src/utils/draft_validation.ts} +1 -1
  34. package/templates/simple/PROJECT_CONTEXT.MD +0 -663
  35. package/templates/simple/README.md +0 -274
  36. /package/templates/{simple → default_draft}/app.json +0 -0
  37. /package/templates/{simple → default_draft}/babel.config.js +0 -0
  38. /package/templates/{simple → default_draft}/global.css +0 -0
  39. /package/templates/{simple → default_draft}/metro.config.js +0 -0
  40. /package/templates/{simple → default_draft}/nativewind-env.d.ts +0 -0
  41. /package/templates/{simple → default_draft}/package.json +0 -0
  42. /package/templates/{simple → default_draft}/server/db.json +0 -0
  43. /package/templates/{simple → default_draft}/src/assets/images/adaptive-icon.png +0 -0
  44. /package/templates/{simple → default_draft}/src/assets/images/favicon.png +0 -0
  45. /package/templates/{simple → default_draft}/src/assets/images/icon.png +0 -0
  46. /package/templates/{simple → default_draft}/src/assets/images/splash-icon.png +0 -0
  47. /package/templates/{simple → default_draft}/src/components/common/Button.tsx +0 -0
  48. /package/templates/{simple → default_draft}/src/components/config/ToastConfig.tsx +0 -0
  49. /package/templates/{simple/src/components/header/AppHeader.tsx → default_draft/src/components/header/draft_AppHeader.tsx} +0 -0
  50. /package/templates/{simple → default_draft}/src/components/shared/ConfirmDialog.tsx +0 -0
  51. /package/templates/{simple → default_draft}/src/components/shared/FormInput.tsx +0 -0
  52. /package/templates/{simple → default_draft}/src/components/shared/LucideIcon.tsx +0 -0
  53. /package/templates/{simple → default_draft}/src/components/shared/RoleSelector.tsx +0 -0
  54. /package/templates/{simple → default_draft}/src/components/users/EmptyState.tsx +0 -0
  55. /package/templates/{simple → default_draft}/src/components/users/ErrorState.tsx +0 -0
  56. /package/templates/{simple/src/theme/colors.ts → default_draft/src/theme/draft_colors.ts} +0 -0
  57. /package/templates/{simple/src/types/api.types.ts → default_draft/src/types/draft_api.types.ts} +0 -0
  58. /package/templates/{simple/src/types/auth.types.ts → default_draft/src/types/draft_auth.types.ts} +0 -0
  59. /package/templates/{simple/src/types/product.types.ts → default_draft/src/types/draft_product.types.ts} +0 -0
  60. /package/templates/{simple/src/types/user.types.ts → default_draft/src/types/draft_user.types.ts} +0 -0
  61. /package/templates/{simple/src/utils/constants.ts → default_draft/src/utils/draft_constants.ts} +0 -0
  62. /package/templates/{simple/src/utils/storage.ts → default_draft/src/utils/draft_storage.ts} +0 -0
  63. /package/templates/{simple → default_draft}/tailwind.config.js +0 -0
  64. /package/templates/{simple → default_draft}/tsconfig.json +0 -0
@@ -1,663 +0,0 @@
1
- # Project Context for AI Agents
2
-
3
- > **Purpose**: This document helps AI coding agents understand the project architecture, conventions, and patterns to generate consistent, high-quality code.
4
-
5
- ## 🏗️ Tech Stack
6
-
7
- ```
8
- - Framework: React Native + Expo SDK 54
9
- - Routing: Expo Router (file-based)
10
- - Language: TypeScript (strict mode)
11
- - Styling: NativeWind (Tailwind CSS for React Native)
12
- - State: React Context API
13
- - API: Mock API (development) / Real API (production)
14
- ```
15
-
16
- ## 📁 Project Structure
17
-
18
- ### Core Directories
19
-
20
- ```
21
- app/ # File-based routing (Expo Router)
22
- ├── (auth)/ # Public authentication routes
23
- ├── (protected)/ # Routes requiring authentication
24
- ├── (admin)/ # Routes requiring admin role
25
- └── _layout.tsx # Root layout wrapper
26
-
27
- src/
28
- ├── components/ # Reusable UI components
29
- ├── contexts/ # React Context providers
30
- ├── hooks/ # Custom React hooks
31
- ├── services/ # API and business logic
32
- ├── types/ # TypeScript type definitions
33
- ├── theme/ # Design tokens and theme config
34
- └── utils/ # Helper functions and utilities
35
- ```
36
-
37
- ### Detailed Structure
38
-
39
- #### **Components** (`src/components/`)
40
- - `auth/` - Authentication-specific components (ProtectedRoute)
41
- - `common/` - Generic reusable components (Button, Input, Card)
42
- - `shared/` - Shared business components (FormInput, ConfirmDialog)
43
- - `users/` - User management components
44
- - `header/` - Navigation and header components
45
- - `config/` - Configuration components (ToastConfig)
46
-
47
- #### **Services** (`src/services/`)
48
- - `*.service.ts` - Real API service implementations
49
- - `mockApi/*.mock.ts` - Mock data for development
50
- - `api.ts` - Base API client configuration
51
-
52
- #### **Types** (`src/types/`)
53
- - `*.types.ts` - TypeScript interfaces and types
54
- - Group by domain: `auth`, `user`, `product`, `api`
55
-
56
- ## 🎯 Architecture Patterns
57
-
58
- ### 1. Data Flow
59
- ```
60
- Component → Custom Hook → Service → API/Mock
61
-
62
- Context (if global state needed)
63
- ```
64
-
65
- ### 2. Authentication Flow
66
- ```
67
- 1. User logs in via authService.login()
68
- 2. Token stored in AsyncStorage
69
- 3. AuthContext provides user state
70
- 4. ProtectedRoute guards routes in (protected)/ and (admin)/
71
- ```
72
-
73
- ### 3. API Strategy
74
- - **Development**: Uses `mockApi/*.mock.ts` files
75
- - **Production**: Uses real API via `*.service.ts`
76
- - Switch via environment variable or constants
77
-
78
- ## 📝 Naming Conventions
79
-
80
- ### Files
81
- - Components: `PascalCase.tsx` (e.g., `UserCard.tsx`)
82
- - Services: `camelCase.service.ts` (e.g., `auth.service.ts`)
83
- - Hooks: `useCamelCase.ts` (e.g., `useAuth.ts`)
84
- - Types: `camelCase.types.ts` (e.g., `user.types.ts`)
85
- - Utils: `camelCase.ts` (e.g., `validation.ts`)
86
-
87
- ### Code
88
- - Components: `PascalCase` (e.g., `UserCard`)
89
- - Functions: `camelCase` (e.g., `getUserById`)
90
- - Constants: `UPPER_SNAKE_CASE` (e.g., `API_BASE_URL`)
91
- - Types/Interfaces: `PascalCase` (e.g., `User`, `ApiResponse<T>`)
92
- - Enums: `PascalCase` with `UPPER_SNAKE_CASE` values
93
-
94
- ### Variables
95
- - Boolean: prefix with `is`, `has`, `should` (e.g., `isLoading`, `hasError`)
96
- - Arrays: plural nouns (e.g., `users`, `products`)
97
- - Event handlers: prefix with `handle` or `on` (e.g., `handleSubmit`, `onPress`)
98
-
99
- ## 🗺️ Routing Guide
100
-
101
- ### Route Groups (Expo Router)
102
-
103
- #### `(auth)` - Public Routes
104
- ```typescript
105
- // No authentication required
106
- app/(auth)/
107
- ├── _layout.tsx // Auth-specific layout (no header)
108
- ├── login.tsx // Login screen
109
- └── register.tsx // Registration screen
110
- ```
111
-
112
- #### `(protected)` - Authenticated Routes
113
- ```typescript
114
- // Requires valid user token
115
- app/(protected)/
116
- ├── _layout.tsx // Protected layout with header
117
- ├── home.tsx // Home screen
118
- └── settings.tsx // User settings
119
- ```
120
-
121
- #### `(admin)` - Admin-Only Routes
122
- ```typescript
123
- // Requires admin role
124
- app/(admin)/
125
- ├── profile.tsx // Admin profile
126
- └── user-management.tsx // User CRUD
127
- ```
128
-
129
- ### Navigation
130
- ```typescript
131
- import { router } from 'expo-router';
132
-
133
- // Navigate
134
- router.push('/login');
135
- router.replace('/(protected)/home');
136
-
137
- // Go back
138
- router.back();
139
-
140
- // With params
141
- router.push({
142
- pathname: '/user/[id]',
143
- params: { id: '123' }
144
- });
145
- ```
146
-
147
- ## 🎨 Styling Guide
148
-
149
- ### NativeWind (Tailwind CSS)
150
- ```typescript
151
- // Use className prop
152
- <View className="flex-1 bg-white p-4">
153
- <Text className="text-lg font-bold text-gray-900">
154
- Hello World
155
- </Text>
156
- </View>
157
-
158
- // Conditional classes
159
- <View className={`p-4 ${isActive ? 'bg-blue-500' : 'bg-gray-200'}`}>
160
- ```
161
-
162
- ### Theme Colors
163
- ```typescript
164
- // Defined in src/theme/colors.ts
165
- import { colors } from '@/theme/colors';
166
-
167
- // Usage in StyleSheet (if needed)
168
- backgroundColor: colors.primary[500]
169
- ```
170
-
171
- ### Best Practices
172
- - Prefer NativeWind classes over StyleSheet
173
- - Use theme colors for consistency
174
- - Responsive: `sm:`, `md:`, `lg:` prefixes
175
- - Dark mode: `dark:` prefix
176
-
177
- ## 🔐 Authentication & Authorization
178
-
179
- ### AuthContext
180
- ```typescript
181
- // Available throughout the app
182
- const { user, login, logout, isAuthenticated } = useAuth();
183
-
184
- // User object structure
185
- interface User {
186
- id: string;
187
- email: string;
188
- name: string;
189
- role: 'user' | 'admin';
190
- }
191
- ```
192
-
193
- ### Protected Routes
194
- ```typescript
195
- // Automatic protection via ProtectedRoute component
196
- // Already implemented in (protected)/_layout.tsx and (admin)/_layout.tsx
197
-
198
- // Manual check in component
199
- const { isAuthenticated, user } = useAuth();
200
-
201
- if (!isAuthenticated) {
202
- return <Redirect href="/login" />;
203
- }
204
-
205
- if (user?.role !== 'admin') {
206
- return <Redirect href="/(protected)/home" />;
207
- }
208
- ```
209
-
210
- ### Token Management
211
- ```typescript
212
- // Stored in AsyncStorage via utils/storage.ts
213
- import { storage } from '@/utils/storage';
214
-
215
- await storage.setToken(token);
216
- const token = await storage.getToken();
217
- await storage.removeToken();
218
- ```
219
-
220
- ## 🛠️ Service Layer Guide
221
-
222
- ### Service Structure
223
- ```typescript
224
- // src/services/user.service.ts
225
- import { api } from './api';
226
- import { User, CreateUserDto } from '@/types/user.types';
227
-
228
- export const userService = {
229
- // GET all users
230
- getAll: async (): Promise<User[]> => {
231
- const response = await api.get('/users');
232
- return response.data;
233
- },
234
-
235
- // GET single user
236
- getById: async (id: string): Promise<User> => {
237
- const response = await api.get(`/users/${id}`);
238
- return response.data;
239
- },
240
-
241
- // POST create user
242
- create: async (data: CreateUserDto): Promise<User> => {
243
- const response = await api.post('/users', data);
244
- return response.data;
245
- },
246
-
247
- // PUT update user
248
- update: async (id: string, data: Partial<User>): Promise<User> => {
249
- const response = await api.put(`/users/${id}`, data);
250
- return response.data;
251
- },
252
-
253
- // DELETE user
254
- delete: async (id: string): Promise<void> => {
255
- await api.delete(`/users/${id}`);
256
- },
257
- };
258
- ```
259
-
260
- ### Mock Services
261
- ```typescript
262
- // src/services/mockApi/user.mock.ts
263
- import { User } from '@/types/user.types';
264
-
265
- const mockUsers: User[] = [
266
- { id: '1', name: 'John Doe', email: 'john@example.com', role: 'admin' },
267
- // ... more mock data
268
- ];
269
-
270
- export const userMockService = {
271
- getAll: async (): Promise<User[]> => {
272
- // Simulate network delay
273
- await new Promise(resolve => setTimeout(resolve, 500));
274
- return mockUsers;
275
- },
276
- // ... other methods
277
- };
278
- ```
279
-
280
- ### API Client
281
- ```typescript
282
- // src/services/api.ts
283
- import axios from 'axios';
284
- import { storage } from '@/utils/storage';
285
-
286
- export const api = axios.create({
287
- baseURL: process.env.EXPO_PUBLIC_API_URL || 'http://localhost:3000',
288
- timeout: 10000,
289
- });
290
-
291
- // Request interceptor (add auth token)
292
- api.interceptors.request.use(async (config) => {
293
- const token = await storage.getToken();
294
- if (token) {
295
- config.headers.Authorization = `Bearer ${token}`;
296
- }
297
- return config;
298
- });
299
-
300
- // Response interceptor (handle errors)
301
- api.interceptors.response.use(
302
- (response) => response,
303
- (error) => {
304
- if (error.response?.status === 401) {
305
- // Handle unauthorized
306
- storage.removeToken();
307
- router.replace('/login');
308
- }
309
- return Promise.reject(error);
310
- }
311
- );
312
- ```
313
-
314
- ## 🪝 Custom Hooks Guide
315
-
316
- ### Pattern
317
- ```typescript
318
- // src/hooks/useUsers.ts
319
- import { useState, useEffect } from 'react';
320
- import { userService } from '@/services/user.service';
321
- import { User } from '@/types/user.types';
322
-
323
- export const useUsers = () => {
324
- const [users, setUsers] = useState<User[]>([]);
325
- const [loading, setLoading] = useState(true);
326
- const [error, setError] = useState<string | null>(null);
327
-
328
- const fetchUsers = async () => {
329
- try {
330
- setLoading(true);
331
- setError(null);
332
- const data = await userService.getAll();
333
- setUsers(data);
334
- } catch (err) {
335
- setError(err instanceof Error ? err.message : 'Failed to fetch users');
336
- } finally {
337
- setLoading(false);
338
- }
339
- };
340
-
341
- useEffect(() => {
342
- fetchUsers();
343
- }, []);
344
-
345
- const refresh = () => fetchUsers();
346
-
347
- return { users, loading, error, refresh };
348
- };
349
- ```
350
-
351
- ### Usage in Component
352
- ```typescript
353
- const UserList = () => {
354
- const { users, loading, error, refresh } = useUsers();
355
-
356
- if (loading) return <Loading />;
357
- if (error) return <ErrorState message={error} />;
358
-
359
- return (
360
- <FlatList
361
- data={users}
362
- renderItem={({ item }) => <UserCard user={item} />}
363
- refreshing={loading}
364
- onRefresh={refresh}
365
- />
366
- );
367
- };
368
- ```
369
-
370
- ## 📦 Component Patterns
371
-
372
- ### Reusable Component Template
373
- ```typescript
374
- // src/components/common/Button.tsx
375
- import { TouchableOpacity, Text, ActivityIndicator } from 'react-native';
376
-
377
- interface ButtonProps {
378
- title: string;
379
- onPress: () => void;
380
- variant?: 'primary' | 'secondary' | 'danger';
381
- loading?: boolean;
382
- disabled?: boolean;
383
- }
384
-
385
- export const Button = ({
386
- title,
387
- onPress,
388
- variant = 'primary',
389
- loading = false,
390
- disabled = false,
391
- }: ButtonProps) => {
392
- const baseClasses = 'px-6 py-3 rounded-lg items-center justify-center';
393
- const variantClasses = {
394
- primary: 'bg-blue-600',
395
- secondary: 'bg-gray-600',
396
- danger: 'bg-red-600',
397
- };
398
-
399
- return (
400
- <TouchableOpacity
401
- onPress={onPress}
402
- disabled={disabled || loading}
403
- className={`${baseClasses} ${variantClasses[variant]} ${
404
- disabled ? 'opacity-50' : ''
405
- }`}
406
- >
407
- {loading ? (
408
- <ActivityIndicator color="white" />
409
- ) : (
410
- <Text className="text-white font-semibold">{title}</Text>
411
- )}
412
- </TouchableOpacity>
413
- );
414
- };
415
- ```
416
-
417
- ### Feature Component Template
418
- ```typescript
419
- // src/components/users/UserCard.tsx
420
- import { View, Text } from 'react-native';
421
- import { User } from '@/types/user.types';
422
- import { Button } from '@/components/common/Button';
423
-
424
- interface UserCardProps {
425
- user: User;
426
- onEdit?: (user: User) => void;
427
- onDelete?: (userId: string) => void;
428
- }
429
-
430
- export const UserCard = ({ user, onEdit, onDelete }: UserCardProps) => {
431
- return (
432
- <View className="bg-white p-4 rounded-lg shadow-sm mb-3">
433
- <Text className="text-lg font-bold">{user.name}</Text>
434
- <Text className="text-gray-600">{user.email}</Text>
435
- <Text className="text-sm text-gray-500">{user.role}</Text>
436
-
437
- <View className="flex-row gap-2 mt-3">
438
- {onEdit && (
439
- <Button title="Edit" onPress={() => onEdit(user)} variant="secondary" />
440
- )}
441
- {onDelete && (
442
- <Button title="Delete" onPress={() => onDelete(user.id)} variant="danger" />
443
- )}
444
- </View>
445
- </View>
446
- );
447
- };
448
- ```
449
-
450
- ## 🔤 TypeScript Patterns
451
-
452
- ### Type Definitions
453
- ```typescript
454
- // src/types/user.types.ts
455
-
456
- // Base entity
457
- export interface User {
458
- id: string;
459
- email: string;
460
- name: string;
461
- role: UserRole;
462
- createdAt: string;
463
- updatedAt: string;
464
- }
465
-
466
- // Enums
467
- export enum UserRole {
468
- USER = 'user',
469
- ADMIN = 'admin',
470
- }
471
-
472
- // DTOs (Data Transfer Objects)
473
- export interface CreateUserDto {
474
- email: string;
475
- name: string;
476
- password: string;
477
- role?: UserRole;
478
- }
479
-
480
- export interface UpdateUserDto {
481
- email?: string;
482
- name?: string;
483
- role?: UserRole;
484
- }
485
-
486
- // Utility types
487
- export type UserWithoutPassword = Omit<User, 'password'>;
488
- export type PartialUser = Partial<User>;
489
- ```
490
-
491
- ### Generic API Response
492
- ```typescript
493
- // src/types/api.types.ts
494
- export interface ApiResponse<T> {
495
- data: T;
496
- message: string;
497
- success: boolean;
498
- }
499
-
500
- export interface PaginatedResponse<T> {
501
- data: T[];
502
- total: number;
503
- page: number;
504
- limit: number;
505
- }
506
-
507
- export interface ApiError {
508
- message: string;
509
- code: string;
510
- details?: Record<string, string[]>;
511
- }
512
- ```
513
-
514
- ## 🚨 Error Handling
515
-
516
- ### Service Level
517
- ```typescript
518
- try {
519
- const users = await userService.getAll();
520
- return users;
521
- } catch (error) {
522
- if (axios.isAxiosError(error)) {
523
- // Handle API errors
524
- const message = error.response?.data?.message || 'Network error';
525
- throw new Error(message);
526
- }
527
- throw error;
528
- }
529
- ```
530
-
531
- ### Component Level
532
- ```typescript
533
- const handleSubmit = async () => {
534
- try {
535
- setLoading(true);
536
- await userService.create(formData);
537
- Toast.show({ type: 'success', text1: 'User created successfully' });
538
- router.back();
539
- } catch (error) {
540
- Toast.show({
541
- type: 'error',
542
- text1: 'Failed to create user',
543
- text2: error instanceof Error ? error.message : 'Unknown error',
544
- });
545
- } finally {
546
- setLoading(false);
547
- }
548
- };
549
- ```
550
-
551
- ## ✅ Best Practices
552
-
553
- ### Do's
554
- - ✅ Use TypeScript strict mode
555
- - ✅ Define proper interfaces for all data structures
556
- - ✅ Use custom hooks for reusable logic
557
- - ✅ Keep components small and focused (< 200 lines)
558
- - ✅ Use meaningful variable and function names
559
- - ✅ Add JSDoc comments for complex functions
560
- - ✅ Handle loading and error states in UI
561
- - ✅ Use async/await instead of promises
562
- - ✅ Implement proper error boundaries
563
- - ✅ Use React.memo for expensive renders
564
-
565
- ### Don'ts
566
- - ❌ Don't use `any` type
567
- - ❌ Don't put business logic in components
568
- - ❌ Don't mutate state directly
569
- - ❌ Don't forget to cleanup effects
570
- - ❌ Don't hardcode strings (use constants)
571
- - ❌ Don't ignore TypeScript errors
572
- - ❌ Don't use inline styles when NativeWind available
573
- - ❌ Don't fetch data in useEffect without dependency array
574
-
575
- ## 🧪 Testing Patterns
576
-
577
- ### Component Test Template
578
- ```typescript
579
- // src/components/common/__tests__/Button.test.tsx
580
- import { render, fireEvent } from '@testing-library/react-native';
581
- import { Button } from '../Button';
582
-
583
- describe('Button', () => {
584
- it('renders correctly', () => {
585
- const { getByText } = render(<Button title="Click me" onPress={() => {}} />);
586
- expect(getByText('Click me')).toBeTruthy();
587
- });
588
-
589
- it('calls onPress when clicked', () => {
590
- const onPress = jest.fn();
591
- const { getByText } = render(<Button title="Click me" onPress={onPress} />);
592
- fireEvent.press(getByText('Click me'));
593
- expect(onPress).toHaveBeenCalled();
594
- });
595
-
596
- it('shows loading state', () => {
597
- const { getByTestId } = render(
598
- <Button title="Click me" onPress={() => {}} loading={true} />
599
- );
600
- expect(getByTestId('activity-indicator')).toBeTruthy();
601
- });
602
- });
603
- ```
604
-
605
- ## 🔧 Common Tasks
606
-
607
- ### Adding a New Feature
608
- 1. Define types in `src/types/feature.types.ts`
609
- 2. Create service in `src/services/feature.service.ts`
610
- 3. Create mock in `src/services/mockApi/feature.mock.ts`
611
- 4. Create custom hook in `src/hooks/useFeature.ts`
612
- 5. Create components in `src/components/feature/`
613
- 6. Add route in `app/(protected)/feature.tsx`
614
-
615
- ### Adding a New Route
616
- 1. Create file in appropriate route group
617
- 2. Add proper layout if needed
618
- 3. Implement authentication guard if protected
619
- 4. Update navigation types if using typed routes
620
-
621
- ### Adding a New Component
622
- 1. Create component file in appropriate folder
623
- 2. Define Props interface
624
- 3. Export as named export
625
- 4. Add to index.ts if grouping exports
626
-
627
- ## 📚 Key Files Reference
628
-
629
- ### Must-Read Files
630
- - `app/_layout.tsx` - Root app layout
631
- - `src/contexts/AuthContext.tsx` - Authentication state
632
- - `src/services/api.ts` - API client setup
633
- - `src/utils/storage.ts` - AsyncStorage wrapper
634
- - `src/types/*.types.ts` - Type definitions
635
-
636
- ### Configuration Files
637
- - `app.json` - Expo configuration
638
- - `tailwind.config.js` - NativeWind/Tailwind config
639
- - `tsconfig.json` - TypeScript configuration
640
- - `babel.config.js` - Babel configuration
641
-
642
- ## 🚀 Development Workflow
643
-
644
- ### Starting Development
645
- ```bash
646
- npm install
647
- npm start
648
- # Press 'i' for iOS, 'a' for Android, 'w' for Web
649
- ```
650
-
651
- ### Code Generation Guidelines
652
- 1. Always use TypeScript with proper types
653
- 2. Follow existing file structure
654
- 3. Use NativeWind for styling
655
- 4. Implement error handling
656
- 5. Add loading states
657
- 6. Keep components reusable
658
- 7. Write JSDoc for complex functions
659
-
660
- ---
661
-
662
- **Last Updated**: 2025-01-29
663
- **Version**: 1.0.0