@multiplayer-app/session-recorder-react-native 0.0.1-alpha.1 → 0.0.1-alpha.2

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 (166) hide show
  1. package/dist/config/constants.d.ts +19 -0
  2. package/dist/config/constants.js +1 -0
  3. package/dist/config/constants.js.map +1 -0
  4. package/dist/config/defaults.d.ts +4 -0
  5. package/dist/config/defaults.js +1 -0
  6. package/dist/config/defaults.js.map +1 -0
  7. package/dist/config/index.d.ts +5 -0
  8. package/dist/config/index.js +1 -0
  9. package/dist/config/index.js.map +1 -0
  10. package/dist/config/masking.d.ts +2 -30
  11. package/dist/config/masking.js +1 -1
  12. package/dist/config/masking.js.map +1 -1
  13. package/dist/config/session-recorder.d.ts +2 -0
  14. package/dist/config/session-recorder.js +1 -0
  15. package/dist/config/session-recorder.js.map +1 -0
  16. package/dist/config/validators.d.ts +10 -0
  17. package/dist/config/validators.js +1 -0
  18. package/dist/config/validators.js.map +1 -0
  19. package/dist/expo.d.ts +2 -2
  20. package/dist/expo.js +1 -1
  21. package/dist/expo.js.map +1 -1
  22. package/dist/exporters.d.ts +3 -0
  23. package/dist/exporters.js +1 -0
  24. package/dist/exporters.js.map +1 -0
  25. package/dist/index.d.ts +3 -9
  26. package/dist/index.js +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/otel/helpers.d.ts +45 -3
  29. package/dist/otel/helpers.js +1 -1
  30. package/dist/otel/helpers.js.map +1 -1
  31. package/dist/otel/index.d.ts +9 -5
  32. package/dist/otel/index.js +1 -1
  33. package/dist/otel/index.js.map +1 -1
  34. package/dist/otel/instrumentations/index.js +1 -1
  35. package/dist/otel/instrumentations/index.js.map +1 -1
  36. package/dist/patch/index.d.ts +1 -0
  37. package/dist/patch/index.js +1 -0
  38. package/dist/patch/index.js.map +1 -0
  39. package/dist/patch/xhr.d.ts +2 -0
  40. package/dist/patch/xhr.js +1 -0
  41. package/dist/patch/xhr.js.map +1 -0
  42. package/dist/recorder/gestureRecorder.js +1 -1
  43. package/dist/recorder/gestureRecorder.js.map +1 -1
  44. package/dist/recorder/navigationTracker.js +1 -1
  45. package/dist/recorder/navigationTracker.js.map +1 -1
  46. package/dist/recorder/screenRecorder.d.ts +1 -0
  47. package/dist/recorder/screenRecorder.js +1 -1
  48. package/dist/recorder/screenRecorder.js.map +1 -1
  49. package/dist/services/api.service.d.ts +62 -10
  50. package/dist/services/api.service.js +1 -1
  51. package/dist/services/api.service.js.map +1 -1
  52. package/dist/services/storage.service.d.ts +23 -16
  53. package/dist/services/storage.service.js +1 -1
  54. package/dist/services/storage.service.js.map +1 -1
  55. package/dist/session-recorder.d.ts +131 -0
  56. package/dist/session-recorder.js +1 -0
  57. package/dist/session-recorder.js.map +1 -0
  58. package/dist/sessionRecorder.d.ts +113 -34
  59. package/dist/sessionRecorder.js +1 -1
  60. package/dist/sessionRecorder.js.map +1 -1
  61. package/dist/types/index.d.ts +2 -81
  62. package/dist/types/index.js +1 -1
  63. package/dist/types/index.js.map +1 -1
  64. package/dist/types/session-recorder.d.ts +366 -0
  65. package/dist/types/session-recorder.js +1 -0
  66. package/dist/types/session-recorder.js.map +1 -0
  67. package/dist/types/session.d.ts +59 -0
  68. package/dist/types/session.js +1 -0
  69. package/dist/types/session.js.map +1 -0
  70. package/dist/utils/index.d.ts +5 -0
  71. package/dist/utils/index.js +1 -0
  72. package/dist/utils/index.js.map +1 -0
  73. package/dist/utils/platform.d.ts +5 -0
  74. package/dist/utils/platform.js +1 -1
  75. package/dist/utils/platform.js.map +1 -1
  76. package/dist/utils/request-utils.d.ts +21 -0
  77. package/dist/utils/request-utils.js +1 -0
  78. package/dist/utils/request-utils.js.map +1 -0
  79. package/dist/utils/session.d.ts +5 -0
  80. package/dist/utils/session.js +1 -0
  81. package/dist/utils/session.js.map +1 -0
  82. package/dist/utils/time.d.ts +4 -0
  83. package/dist/utils/time.js +1 -0
  84. package/dist/utils/time.js.map +1 -0
  85. package/dist/utils/type-utils.d.ts +16 -0
  86. package/dist/utils/type-utils.js +1 -0
  87. package/dist/utils/type-utils.js.map +1 -0
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/package.json +2 -2
  91. package/src/config/constants.ts +60 -0
  92. package/src/config/defaults.ts +82 -0
  93. package/src/config/index.ts +6 -0
  94. package/src/config/masking.ts +10 -61
  95. package/src/config/session-recorder.ts +55 -0
  96. package/src/config/validators.ts +31 -0
  97. package/src/expo.ts +2 -22
  98. package/src/index.ts +3 -15
  99. package/src/otel/helpers.ts +247 -11
  100. package/src/otel/index.ts +109 -76
  101. package/src/otel/instrumentations/index.ts +8 -8
  102. package/src/patch/index.ts +1 -0
  103. package/src/patch/xhr.ts +142 -0
  104. package/src/recorder/gestureRecorder.ts +12 -12
  105. package/src/recorder/navigationTracker.ts +10 -10
  106. package/src/recorder/screenRecorder.ts +26 -26
  107. package/src/services/api.service.ts +169 -37
  108. package/src/services/storage.service.ts +101 -74
  109. package/src/session-recorder.ts +570 -0
  110. package/src/types/index.ts +2 -88
  111. package/src/types/session-recorder.ts +423 -0
  112. package/src/types/session.ts +65 -0
  113. package/src/utils/index.ts +6 -0
  114. package/src/utils/platform.ts +13 -0
  115. package/src/utils/request-utils.ts +61 -0
  116. package/src/utils/session.ts +18 -0
  117. package/src/utils/time.ts +17 -0
  118. package/src/utils/type-utils.ts +75 -0
  119. package/src/version.ts +1 -1
  120. package/examples/sample-expo-app/README.md +0 -142
  121. package/examples/sample-expo-app/app/(tabs)/_layout.tsx +0 -60
  122. package/examples/sample-expo-app/app/(tabs)/explore.tsx +0 -110
  123. package/examples/sample-expo-app/app/(tabs)/index.tsx +0 -125
  124. package/examples/sample-expo-app/app/(tabs)/posts.tsx +0 -96
  125. package/examples/sample-expo-app/app/(tabs)/users.tsx +0 -131
  126. package/examples/sample-expo-app/app/+not-found.tsx +0 -32
  127. package/examples/sample-expo-app/app/_layout.tsx +0 -53
  128. package/examples/sample-expo-app/app/post/[id].tsx +0 -199
  129. package/examples/sample-expo-app/app/user/[id].tsx +0 -270
  130. package/examples/sample-expo-app/app.json +0 -42
  131. package/examples/sample-expo-app/assets/fonts/SpaceMono-Regular.ttf +0 -0
  132. package/examples/sample-expo-app/assets/images/adaptive-icon.png +0 -0
  133. package/examples/sample-expo-app/assets/images/favicon.png +0 -0
  134. package/examples/sample-expo-app/assets/images/icon.png +0 -0
  135. package/examples/sample-expo-app/assets/images/partial-react-logo.png +0 -0
  136. package/examples/sample-expo-app/assets/images/react-logo.png +0 -0
  137. package/examples/sample-expo-app/assets/images/react-logo@2x.png +0 -0
  138. package/examples/sample-expo-app/assets/images/react-logo@3x.png +0 -0
  139. package/examples/sample-expo-app/assets/images/splash-icon.png +0 -0
  140. package/examples/sample-expo-app/components/Collapsible.tsx +0 -45
  141. package/examples/sample-expo-app/components/ErrorView.tsx +0 -52
  142. package/examples/sample-expo-app/components/ExternalLink.tsx +0 -24
  143. package/examples/sample-expo-app/components/HapticTab.tsx +0 -18
  144. package/examples/sample-expo-app/components/HelloWave.tsx +0 -40
  145. package/examples/sample-expo-app/components/LoadingSpinner.tsx +0 -34
  146. package/examples/sample-expo-app/components/ParallaxScrollView.tsx +0 -82
  147. package/examples/sample-expo-app/components/ThemedText.tsx +0 -60
  148. package/examples/sample-expo-app/components/ThemedView.tsx +0 -14
  149. package/examples/sample-expo-app/components/ui/IconSymbol.ios.tsx +0 -32
  150. package/examples/sample-expo-app/components/ui/IconSymbol.tsx +0 -41
  151. package/examples/sample-expo-app/components/ui/TabBarBackground.ios.tsx +0 -19
  152. package/examples/sample-expo-app/components/ui/TabBarBackground.tsx +0 -6
  153. package/examples/sample-expo-app/constants/Colors.ts +0 -26
  154. package/examples/sample-expo-app/eslint.config.js +0 -10
  155. package/examples/sample-expo-app/hooks/useApi.ts +0 -41
  156. package/examples/sample-expo-app/hooks/useColorScheme.ts +0 -1
  157. package/examples/sample-expo-app/hooks/useColorScheme.web.ts +0 -21
  158. package/examples/sample-expo-app/hooks/useThemeColor.ts +0 -21
  159. package/examples/sample-expo-app/metro.config.js +0 -26
  160. package/examples/sample-expo-app/package-lock.json +0 -26296
  161. package/examples/sample-expo-app/package.json +0 -59
  162. package/examples/sample-expo-app/scripts/reset-project.js +0 -112
  163. package/examples/sample-expo-app/services/api.ts +0 -98
  164. package/examples/sample-expo-app/tsconfig.json +0 -17
  165. package/examples/sample-expo-app/utils/navigation.ts +0 -19
  166. package/src/sessionRecorder.ts +0 -367
@@ -1,142 +0,0 @@
1
- # Enhanced Sample Expo React Native App
2
-
3
- This is an enhanced sample Expo React Native app that demonstrates multiple pages, navigation, and API integration with JSONPlaceholder.
4
-
5
- ## Features
6
-
7
- ### 🏠 Home Screen
8
-
9
- - Welcome page with feature overview
10
- - Quick navigation to Posts and Users sections
11
- - Information about the app's capabilities
12
-
13
- ### 📝 Posts Tab
14
-
15
- - Displays posts from JSONPlaceholder API
16
- - Pull-to-refresh functionality
17
- - Tap to view post details with comments
18
- - Loading states and error handling
19
-
20
- ### 👥 Users Tab
21
-
22
- - Shows user profiles from JSONPlaceholder API
23
- - User avatars and basic information
24
- - Tap to view detailed user profiles
25
- - Displays user's posts
26
-
27
- ### 📄 Post Details
28
-
29
- - Full post content with title and body
30
- - Comments section with all post comments
31
- - Navigation to user profile
32
- - Back navigation
33
-
34
- ### 👤 User Details
35
-
36
- - Complete user profile information
37
- - Contact details (email, phone, website)
38
- - Company information
39
- - Address details
40
- - User's posts list
41
- - Navigation to individual posts
42
-
43
- ## API Integration
44
-
45
- The app integrates with [JSONPlaceholder](https://jsonplaceholder.typicode.com/) API to demonstrate:
46
-
47
- - **Posts API**: Fetch all posts, individual posts, and post comments
48
- - **Users API**: Fetch all users, individual users, and user posts
49
- - **Error Handling**: Proper error states with retry functionality
50
- - **Loading States**: Loading spinners and progress indicators
51
- - **Data Management**: Custom hooks for API state management
52
-
53
- ## Technical Stack
54
-
55
- - **Expo Router**: File-based navigation
56
- - **React Native**: Cross-platform mobile development
57
- - **TypeScript**: Type-safe development
58
- - **Axios**: HTTP client for API requests
59
- - **Custom Hooks**: Reusable API state management
60
- - **Themed Components**: Consistent UI with dark/light mode support
61
-
62
- ## Project Structure
63
-
64
- ```
65
- app/
66
- ├── (tabs)/
67
- │ ├── index.tsx # Home screen
68
- │ ├── posts.tsx # Posts list
69
- │ ├── users.tsx # Users list
70
- │ ├── explore.tsx # Original explore screen
71
- │ └── _layout.tsx # Tab navigation layout
72
- ├── post/
73
- │ └── [id].tsx # Post detail page
74
- ├── user/
75
- │ └── [id].tsx # User detail page
76
- └── _layout.tsx # Root layout
77
-
78
- components/
79
- ├── LoadingSpinner.tsx # Loading component
80
- ├── ErrorView.tsx # Error display component
81
- └── ... # Other UI components
82
-
83
- services/
84
- └── api.ts # API service with JSONPlaceholder integration
85
-
86
- hooks/
87
- └── useApi.ts # Custom hook for API state management
88
- ```
89
-
90
- ## Getting Started
91
-
92
- 1. Install dependencies:
93
-
94
- ```bash
95
- npm install
96
- ```
97
-
98
- 2. Start the development server:
99
-
100
- ```bash
101
- npm start
102
- ```
103
-
104
- 3. Run on your preferred platform:
105
- ```bash
106
- npm run ios # iOS simulator
107
- npm run android # Android emulator
108
- npm run web # Web browser
109
- ```
110
-
111
- ## API Endpoints Used
112
-
113
- - `GET /posts` - Fetch all posts
114
- - `GET /posts/:id` - Fetch specific post
115
- - `GET /posts/:id/comments` - Fetch post comments
116
- - `GET /users` - Fetch all users
117
- - `GET /users/:id` - Fetch specific user
118
- - `GET /users/:id/posts` - Fetch user's posts
119
-
120
- ## Navigation Flow
121
-
122
- 1. **Home** → **Posts** → **Post Detail** → **User Detail**
123
- 2. **Home** → **Users** → **User Detail** → **Post Detail**
124
- 3. **Posts** → **Post Detail** → **User Detail**
125
- 4. **Users** → **User Detail** → **Post Detail**
126
-
127
- ## Customization
128
-
129
- The app is designed to be easily customizable:
130
-
131
- - **API Service**: Modify `services/api.ts` to integrate with different APIs
132
- - **UI Components**: Update components in the `components/` directory
133
- - **Navigation**: Add new routes in the `app/` directory
134
- - **Styling**: Modify styles in individual component files
135
-
136
- ## Session Recording Integration
137
-
138
- This sample app includes the session recorder integration, demonstrating how to capture user interactions and API calls for debugging and analytics purposes.
139
-
140
- ## Contributing
141
-
142
- Feel free to enhance this sample app with additional features, better error handling, or different API integrations.
@@ -1,60 +0,0 @@
1
- import { Tabs } from 'expo-router'
2
- import React from 'react'
3
- import { Platform } from 'react-native'
4
-
5
- import { HapticTab } from '@/components/HapticTab'
6
- import { IconSymbol } from '@/components/ui/IconSymbol'
7
- import TabBarBackground from '@/components/ui/TabBarBackground'
8
- import { Colors } from '@/constants/Colors'
9
- import { useColorScheme } from '@/hooks/useColorScheme'
10
-
11
- export default function TabLayout() {
12
- const colorScheme = useColorScheme()
13
-
14
- return (
15
- <Tabs
16
- screenOptions={{
17
- tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
18
- headerShown: false,
19
- tabBarButton: HapticTab,
20
- tabBarBackground: TabBarBackground,
21
- tabBarStyle: Platform.select({
22
- ios: {
23
- // Use a transparent background on iOS to show the blur effect
24
- position: 'absolute'
25
- },
26
- default: {}
27
- })
28
- }}
29
- >
30
- <Tabs.Screen
31
- name='index'
32
- options={{
33
- title: 'Home',
34
- tabBarIcon: ({ color }) => <IconSymbol size={28} name='house.fill' color={color} />
35
- }}
36
- />
37
- <Tabs.Screen
38
- name='posts'
39
- options={{
40
- title: 'Posts',
41
- tabBarIcon: ({ color }) => <IconSymbol size={28} name='doc.text.fill' color={color} />
42
- }}
43
- />
44
- <Tabs.Screen
45
- name='users'
46
- options={{
47
- title: 'Users',
48
- tabBarIcon: ({ color }) => <IconSymbol size={28} name='person.2.fill' color={color} />
49
- }}
50
- />
51
- <Tabs.Screen
52
- name='explore'
53
- options={{
54
- title: 'Explore',
55
- tabBarIcon: ({ color }) => <IconSymbol size={28} name='paperplane.fill' color={color} />
56
- }}
57
- />
58
- </Tabs>
59
- )
60
- }
@@ -1,110 +0,0 @@
1
- import { Image } from 'expo-image';
2
- import { Platform, StyleSheet } from 'react-native';
3
-
4
- import { Collapsible } from '@/components/Collapsible';
5
- import { ExternalLink } from '@/components/ExternalLink';
6
- import ParallaxScrollView from '@/components/ParallaxScrollView';
7
- import { ThemedText } from '@/components/ThemedText';
8
- import { ThemedView } from '@/components/ThemedView';
9
- import { IconSymbol } from '@/components/ui/IconSymbol';
10
-
11
- export default function TabTwoScreen() {
12
- return (
13
- <ParallaxScrollView
14
- headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
15
- headerImage={
16
- <IconSymbol
17
- size={310}
18
- color="#808080"
19
- name="chevron.left.forwardslash.chevron.right"
20
- style={styles.headerImage}
21
- />
22
- }>
23
- <ThemedView style={styles.titleContainer}>
24
- <ThemedText type="title">Explore</ThemedText>
25
- </ThemedView>
26
- <ThemedText>This app includes example code to help you get started.</ThemedText>
27
- <Collapsible title="File-based routing">
28
- <ThemedText>
29
- This app has two screens:{' '}
30
- <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
31
- <ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
32
- </ThemedText>
33
- <ThemedText>
34
- The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
35
- sets up the tab navigator.
36
- </ThemedText>
37
- <ExternalLink href="https://docs.expo.dev/router/introduction">
38
- <ThemedText type="link">Learn more</ThemedText>
39
- </ExternalLink>
40
- </Collapsible>
41
- <Collapsible title="Android, iOS, and web support">
42
- <ThemedText>
43
- You can open this project on Android, iOS, and the web. To open the web version, press{' '}
44
- <ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project.
45
- </ThemedText>
46
- </Collapsible>
47
- <Collapsible title="Images">
48
- <ThemedText>
49
- For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
50
- <ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
51
- different screen densities
52
- </ThemedText>
53
- <Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} />
54
- <ExternalLink href="https://reactnative.dev/docs/images">
55
- <ThemedText type="link">Learn more</ThemedText>
56
- </ExternalLink>
57
- </Collapsible>
58
- <Collapsible title="Custom fonts">
59
- <ThemedText>
60
- Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '}
61
- <ThemedText style={{ fontFamily: 'SpaceMono' }}>
62
- custom fonts such as this one.
63
- </ThemedText>
64
- </ThemedText>
65
- <ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font">
66
- <ThemedText type="link">Learn more</ThemedText>
67
- </ExternalLink>
68
- </Collapsible>
69
- <Collapsible title="Light and dark mode components">
70
- <ThemedText>
71
- This template has light and dark mode support. The{' '}
72
- <ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect
73
- what the user&apos;s current color scheme is, and so you can adjust UI colors accordingly.
74
- </ThemedText>
75
- <ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
76
- <ThemedText type="link">Learn more</ThemedText>
77
- </ExternalLink>
78
- </Collapsible>
79
- <Collapsible title="Animations">
80
- <ThemedText>
81
- This template includes an example of an animated component. The{' '}
82
- <ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
83
- the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '}
84
- library to create a waving hand animation.
85
- </ThemedText>
86
- {Platform.select({
87
- ios: (
88
- <ThemedText>
89
- The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '}
90
- component provides a parallax effect for the header image.
91
- </ThemedText>
92
- ),
93
- })}
94
- </Collapsible>
95
- </ParallaxScrollView>
96
- );
97
- }
98
-
99
- const styles = StyleSheet.create({
100
- headerImage: {
101
- color: '#808080',
102
- bottom: -90,
103
- left: -35,
104
- position: 'absolute',
105
- },
106
- titleContainer: {
107
- flexDirection: 'row',
108
- gap: 8,
109
- },
110
- });
@@ -1,125 +0,0 @@
1
- import { Image } from 'expo-image'
2
- import { StyleSheet, TouchableOpacity } from 'react-native'
3
-
4
- import { HelloWave } from '@/components/HelloWave'
5
- import ParallaxScrollView from '@/components/ParallaxScrollView'
6
- import { ThemedText } from '@/components/ThemedText'
7
- import { ThemedView } from '@/components/ThemedView'
8
- import { IconSymbol } from '@/components/ui/IconSymbol'
9
- import { Colors } from '@/constants/Colors'
10
- import { useColorScheme } from '@/hooks/useColorScheme'
11
-
12
- export default function HomeScreen() {
13
- const colorScheme = useColorScheme()
14
-
15
- const handleNavigateToPosts = () => {
16
- // Navigate to posts tab
17
- }
18
-
19
- const handleNavigateToUsers = () => {
20
- // Navigate to users tab
21
- }
22
-
23
- return (
24
- <ParallaxScrollView
25
- headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
26
- headerImage={<Image source={require('@/assets/images/partial-react-logo.png')} style={styles.reactLogo} />}
27
- >
28
- <ThemedView style={styles.titleContainer}>
29
- <ThemedText type='title'>Welcome!</ThemedText>
30
- <HelloWave />
31
- </ThemedView>
32
-
33
- <ThemedView style={styles.stepContainer}>
34
- <ThemedText type='subtitle'>Enhanced Sample App</ThemedText>
35
- <ThemedText>
36
- This sample app now includes multiple pages, navigation, and API integration with JSONPlaceholder.
37
- </ThemedText>
38
- </ThemedView>
39
-
40
- <ThemedView style={styles.featuresContainer}>
41
- <ThemedText type='subtitle' style={styles.featuresTitle}>
42
- Features
43
- </ThemedText>
44
-
45
- <TouchableOpacity style={styles.featureCard} onPress={handleNavigateToPosts} activeOpacity={0.7}>
46
- <IconSymbol name='doc.text.fill' size={24} color={Colors[colorScheme ?? 'light'].tint} />
47
- <ThemedView style={styles.featureContent}>
48
- <ThemedText type='defaultSemiBold'>Posts</ThemedText>
49
- <ThemedText style={styles.featureDescription}>Browse posts from JSONPlaceholder API with comments</ThemedText>
50
- </ThemedView>
51
- <IconSymbol name='chevron.right' size={16} color={Colors[colorScheme ?? 'light'].tint} />
52
- </TouchableOpacity>
53
-
54
- <TouchableOpacity style={styles.featureCard} onPress={handleNavigateToUsers} activeOpacity={0.7}>
55
- <IconSymbol name='person.2.fill' size={24} color={Colors[colorScheme ?? 'light'].tint} />
56
- <ThemedView style={styles.featureContent}>
57
- <ThemedText type='defaultSemiBold'>Users</ThemedText>
58
- <ThemedText style={styles.featureDescription}>View user profiles with their posts and details</ThemedText>
59
- </ThemedView>
60
- <IconSymbol name='chevron.right' size={16} color={Colors[colorScheme ?? 'light'].tint} />
61
- </TouchableOpacity>
62
- </ThemedView>
63
-
64
- <ThemedView style={styles.stepContainer}>
65
- <ThemedText type='subtitle'>Navigation</ThemedText>
66
- <ThemedText>
67
- Use the bottom tabs to navigate between different sections, or tap the feature cards above to explore the new
68
- functionality.
69
- </ThemedText>
70
- </ThemedView>
71
-
72
- <ThemedView style={styles.stepContainer}>
73
- <ThemedText type='subtitle'>API Integration</ThemedText>
74
- <ThemedText>
75
- The app demonstrates real API calls to JSONPlaceholder with proper loading states, error handling, and data management.
76
- </ThemedText>
77
- </ThemedView>
78
- </ParallaxScrollView>
79
- )
80
- }
81
-
82
- const styles = StyleSheet.create({
83
- titleContainer: {
84
- flexDirection: 'row',
85
- alignItems: 'center',
86
- gap: 8
87
- },
88
- stepContainer: {
89
- gap: 8,
90
- marginBottom: 8
91
- },
92
- featuresContainer: {
93
- marginBottom: 16
94
- },
95
- featuresTitle: {
96
- marginBottom: 12
97
- },
98
- featureCard: {
99
- flexDirection: 'row',
100
- alignItems: 'center',
101
- padding: 16,
102
- marginBottom: 12,
103
- borderRadius: 12,
104
- backgroundColor: 'rgba(255, 255, 255, 0.1)',
105
- borderWidth: 1,
106
- borderColor: 'rgba(255, 255, 255, 0.2)'
107
- },
108
- featureContent: {
109
- flex: 1,
110
- marginLeft: 12,
111
- marginRight: 12
112
- },
113
- featureDescription: {
114
- fontSize: 14,
115
- opacity: 0.7,
116
- marginTop: 2
117
- },
118
- reactLogo: {
119
- height: 178,
120
- width: 290,
121
- bottom: 0,
122
- left: 0,
123
- position: 'absolute'
124
- }
125
- })
@@ -1,96 +0,0 @@
1
- import React from 'react'
2
- import { FlatList, StyleSheet, TouchableOpacity, RefreshControl } from 'react-native'
3
- import { router } from 'expo-router'
4
- import { ThemedView } from '@/components/ThemedView'
5
- import { ThemedText } from '@/components/ThemedText'
6
- import { LoadingSpinner } from '@/components/LoadingSpinner'
7
- import { ErrorView } from '@/components/ErrorView'
8
- import { useApi } from '@/hooks/useApi'
9
- import { apiService, Post } from '@/services/api'
10
-
11
- export default function PostsScreen() {
12
- const { data: posts, loading, error, refetch } = useApi(() => apiService.getPosts())
13
-
14
- const handlePostPress = (post: Post) => {
15
- router.push(`/post/${post.id}`)
16
- }
17
-
18
- const renderPost = ({ item }: { item: Post }) => (
19
- <TouchableOpacity style={styles.postCard} onPress={() => handlePostPress(item)} activeOpacity={0.7}>
20
- <ThemedText type='subtitle' style={styles.postTitle}>
21
- {item.title}
22
- </ThemedText>
23
- <ThemedText style={styles.postBody} numberOfLines={3}>
24
- {item.body}
25
- </ThemedText>
26
- <ThemedText style={styles.postMeta}>
27
- Post ID: {item.id} • User ID: {item.userId}
28
- </ThemedText>
29
- </TouchableOpacity>
30
- )
31
-
32
- if (loading) {
33
- return <LoadingSpinner message='Loading posts...' />
34
- }
35
-
36
- if (error) {
37
- return <ErrorView message={error} onRetry={refetch} />
38
- }
39
-
40
- return (
41
- <ThemedView style={styles.container}>
42
- <ThemedView style={styles.header}>
43
- <ThemedText type='title'>Posts</ThemedText>
44
- <ThemedText style={styles.subtitle}>Latest posts from JSONPlaceholder API</ThemedText>
45
- </ThemedView>
46
-
47
- <FlatList
48
- data={posts}
49
- renderItem={renderPost}
50
- keyExtractor={(item) => item.id.toString()}
51
- contentContainerStyle={styles.listContainer}
52
- refreshControl={<RefreshControl refreshing={loading} onRefresh={refetch} />}
53
- showsVerticalScrollIndicator={false}
54
- />
55
- </ThemedView>
56
- )
57
- }
58
-
59
- const styles = StyleSheet.create({
60
- container: {
61
- flex: 1
62
- },
63
- header: {
64
- padding: 20,
65
- paddingTop: 60,
66
- paddingBottom: 10
67
- },
68
- subtitle: {
69
- marginTop: 4,
70
- opacity: 0.7
71
- },
72
- listContainer: {
73
- padding: 20,
74
- paddingTop: 10
75
- },
76
- postCard: {
77
- padding: 16,
78
- marginBottom: 12,
79
- borderRadius: 12,
80
- backgroundColor: 'rgba(255, 255, 255, 0.1)',
81
- borderWidth: 1,
82
- borderColor: 'rgba(255, 255, 255, 0.2)'
83
- },
84
- postTitle: {
85
- marginBottom: 8,
86
- fontWeight: '600'
87
- },
88
- postBody: {
89
- marginBottom: 12,
90
- lineHeight: 20
91
- },
92
- postMeta: {
93
- fontSize: 12,
94
- opacity: 0.6
95
- }
96
- })
@@ -1,131 +0,0 @@
1
- import React from 'react'
2
- import { FlatList, StyleSheet, TouchableOpacity, RefreshControl } from 'react-native'
3
- import { router } from 'expo-router'
4
- import { ThemedView } from '@/components/ThemedView'
5
- import { ThemedText } from '@/components/ThemedText'
6
- import { LoadingSpinner } from '@/components/LoadingSpinner'
7
- import { ErrorView } from '@/components/ErrorView'
8
- import { IconSymbol } from '@/components/ui/IconSymbol'
9
- import { useApi } from '@/hooks/useApi'
10
- import { apiService, User } from '@/services/api'
11
- import { Colors } from '@/constants/Colors'
12
- import { useColorScheme } from '@/hooks/useColorScheme'
13
-
14
- export default function UsersScreen() {
15
- const { data: users, loading, error, refetch } = useApi(() => apiService.getUsers())
16
- const colorScheme = useColorScheme()
17
-
18
- const handleUserPress = (user: User) => {
19
- router.push(`/user/${user.id}`)
20
- }
21
-
22
- const renderUser = ({ item }: { item: User }) => (
23
- <TouchableOpacity style={styles.userCard} onPress={() => handleUserPress(item)} activeOpacity={0.7}>
24
- <ThemedView style={styles.userAvatar}>
25
- <IconSymbol name='person.fill' size={24} color={Colors[colorScheme ?? 'light'].tint} />
26
- </ThemedView>
27
-
28
- <ThemedView style={styles.userInfo}>
29
- <ThemedText type='subtitle' style={styles.userName}>
30
- {item.name}
31
- </ThemedText>
32
- <ThemedText style={styles.userUsername}>@{item.username}</ThemedText>
33
- <ThemedText style={styles.userEmail} numberOfLines={1}>
34
- {item.email}
35
- </ThemedText>
36
- <ThemedText style={styles.userCompany}>{item.company.name}</ThemedText>
37
- </ThemedView>
38
-
39
- <IconSymbol name='chevron.right' size={16} color={Colors[colorScheme ?? 'light'].tint} style={styles.chevron} />
40
- </TouchableOpacity>
41
- )
42
-
43
- if (loading) {
44
- return <LoadingSpinner message='Loading users...' />
45
- }
46
-
47
- if (error) {
48
- return <ErrorView message={error} onRetry={refetch} />
49
- }
50
-
51
- return (
52
- <ThemedView style={styles.container}>
53
- <ThemedView style={styles.header}>
54
- <ThemedText type='title'>Users</ThemedText>
55
- <ThemedText style={styles.subtitle}>Users from JSONPlaceholder API</ThemedText>
56
- </ThemedView>
57
-
58
- <FlatList
59
- data={users}
60
- renderItem={renderUser}
61
- keyExtractor={(item) => item.id.toString()}
62
- contentContainerStyle={styles.listContainer}
63
- refreshControl={<RefreshControl refreshing={loading} onRefresh={refetch} />}
64
- showsVerticalScrollIndicator={false}
65
- />
66
- </ThemedView>
67
- )
68
- }
69
-
70
- const styles = StyleSheet.create({
71
- container: {
72
- flex: 1
73
- },
74
- header: {
75
- padding: 20,
76
- paddingTop: 60,
77
- paddingBottom: 10
78
- },
79
- subtitle: {
80
- marginTop: 4,
81
- opacity: 0.7
82
- },
83
- listContainer: {
84
- padding: 20,
85
- paddingTop: 10
86
- },
87
- userCard: {
88
- flexDirection: 'row',
89
- alignItems: 'center',
90
- padding: 16,
91
- marginBottom: 12,
92
- borderRadius: 12,
93
- backgroundColor: 'rgba(255, 255, 255, 0.1)',
94
- borderWidth: 1,
95
- borderColor: 'rgba(255, 255, 255, 0.2)'
96
- },
97
- userAvatar: {
98
- width: 48,
99
- height: 48,
100
- borderRadius: 24,
101
- backgroundColor: 'rgba(255, 255, 255, 0.2)',
102
- justifyContent: 'center',
103
- alignItems: 'center',
104
- marginRight: 12
105
- },
106
- userInfo: {
107
- flex: 1
108
- },
109
- userName: {
110
- marginBottom: 2,
111
- fontWeight: '600'
112
- },
113
- userUsername: {
114
- fontSize: 14,
115
- opacity: 0.7,
116
- marginBottom: 4
117
- },
118
- userEmail: {
119
- fontSize: 12,
120
- opacity: 0.6,
121
- marginBottom: 2
122
- },
123
- userCompany: {
124
- fontSize: 12,
125
- opacity: 0.8,
126
- fontStyle: 'italic'
127
- },
128
- chevron: {
129
- opacity: 0.5
130
- }
131
- })
@@ -1,32 +0,0 @@
1
- import { Link, Stack } from 'expo-router';
2
- import { StyleSheet } from 'react-native';
3
-
4
- import { ThemedText } from '@/components/ThemedText';
5
- import { ThemedView } from '@/components/ThemedView';
6
-
7
- export default function NotFoundScreen() {
8
- return (
9
- <>
10
- <Stack.Screen options={{ title: 'Oops!' }} />
11
- <ThemedView style={styles.container}>
12
- <ThemedText type="title">This screen does not exist.</ThemedText>
13
- <Link href="/" style={styles.link}>
14
- <ThemedText type="link">Go to home screen!</ThemedText>
15
- </Link>
16
- </ThemedView>
17
- </>
18
- );
19
- }
20
-
21
- const styles = StyleSheet.create({
22
- container: {
23
- flex: 1,
24
- alignItems: 'center',
25
- justifyContent: 'center',
26
- padding: 20,
27
- },
28
- link: {
29
- marginTop: 15,
30
- paddingVertical: 15,
31
- },
32
- });