Skip to content

Commit 8a4380d

Browse files
committed
Replaced Alert.alert() with Dialog component from @/components/ui/Dialog
Used Button components with proper variants (outline for Cancel, solid for Sign Out) Added loading states and proper accessibility Maintained the same user experience across all platforms (web, iOS, Android)
1 parent e4a1a67 commit 8a4380d

6 files changed

Lines changed: 729 additions & 136 deletions

File tree

KonditionExpo/TESTING_GUIDE.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Authentication Testing Guide
2+
3+
## Quick Start
4+
5+
### 1. Start the Backend
6+
7+
**Option A: Using Docker Compose (Recommended)**
8+
```bash
9+
cd KonditionFastAPI
10+
docker compose watch
11+
```
12+
13+
**Option B: Direct Python**
14+
```bash
15+
cd KonditionFastAPI
16+
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
17+
```
18+
19+
### 2. Test on Different Platforms
20+
21+
#### Web (Should work immediately)
22+
```bash
23+
cd KonditionExpo
24+
npm run web
25+
```
26+
27+
#### iOS Simulator (Should work immediately)
28+
```bash
29+
npm run ios
30+
```
31+
32+
#### Android Emulator (Should work immediately)
33+
```bash
34+
npm run android
35+
```
36+
37+
#### Physical Device / Expo Go
38+
1. Find your computer's IP address:
39+
- **macOS**: `ifconfig | grep "inet " | grep -v 127.0.0.1`
40+
- **Windows**: `ipconfig`
41+
- **Linux**: `ip addr show`
42+
43+
2. Start Expo:
44+
```bash
45+
npm start
46+
```
47+
48+
3. Open the app and go to **Profile > Developer Tools**
49+
50+
4. Set custom URL: `http://[YOUR_IP]:8000/api/v1`
51+
52+
5. Test the connection using the "Test API Connection" button
53+
54+
## Testing Checklist
55+
56+
### Signout Functionality
57+
- [ ] Click signout button in profile screen
58+
- [ ] Confirmation dialog appears
59+
- [ ] Loading state shows "Signing Out..."
60+
- [ ] Successfully redirects to login screen
61+
- [ ] No errors in console
62+
63+
### Network Connectivity
64+
- [ ] Web platform connects to localhost:8000
65+
- [ ] iOS Simulator connects to localhost:8000
66+
- [ ] Android Emulator connects to 10.0.2.2:8000
67+
- [ ] Physical device connects with custom IP
68+
- [ ] Error messages are user-friendly
69+
70+
### DevTools
71+
- [ ] Developer Tools accessible from profile
72+
- [ ] Shows current API URL
73+
- [ ] Connection test works
74+
- [ ] Custom URL can be set
75+
- [ ] Quick URL buttons work
76+
77+
## Common Issues & Solutions
78+
79+
### "Network request failed"
80+
1. Check if backend is running: `curl http://localhost:8000/docs`
81+
2. Verify backend is accessible externally: `curl http://[YOUR_IP]:8000/docs`
82+
3. Check firewall settings
83+
4. Ensure devices are on same network
84+
85+
### Signout not working
86+
1. Check console for error messages
87+
2. Clear app data/cache
88+
3. Restart the app
89+
4. Check AsyncStorage permissions
90+
91+
### DevTools not showing
92+
1. Make sure you're on the Profile tab
93+
2. Scroll down to "Other" section
94+
3. Look for blue "Developer Tools" text
95+
96+
## Debug Information
97+
98+
The app now logs detailed information to help with debugging:
99+
100+
```
101+
Platform detected: ios (ios_simulator)
102+
Using API URL: http://localhost:8000/api/v1
103+
Making request to: http://localhost:8000/api/v1/login/access-token
104+
Starting logout process...
105+
Logout successful
106+
```
107+
108+
Check the console/logs for these messages to understand what's happening.
109+
110+
## Network Setup for Mobile Testing
111+
112+
### Step 1: Find Your IP
113+
```bash
114+
# macOS/Linux
115+
ifconfig | grep "inet " | grep -v 127.0.0.1
116+
117+
# Windows
118+
ipconfig
119+
```
120+
121+
### Step 2: Start Backend with External Access
122+
```bash
123+
uvicorn app.main:app --host 0.0.0.0 --port 8000
124+
```
125+
126+
### Step 3: Configure Mobile App
127+
1. Open app on mobile device
128+
2. Go to Profile > Developer Tools
129+
3. Enter: `http://[YOUR_IP]:8000/api/v1`
130+
4. Test connection
131+
132+
### Step 4: Verify Setup
133+
- Backend accessible: `http://[YOUR_IP]:8000/docs`
134+
- API working: Test connection in DevTools
135+
- Authentication: Try login/logout
136+
137+
## Platform-Specific Notes
138+
139+
### Web
140+
- Uses localhost:8000 automatically
141+
- No additional setup required
142+
- Best for initial development
143+
144+
### iOS Simulator
145+
- Uses localhost:8000 automatically
146+
- Behaves like web platform
147+
- Good for iOS-specific testing
148+
149+
### Android Emulator
150+
- Uses 10.0.2.2:8000 automatically
151+
- Special IP for Android emulator networking
152+
- No manual configuration needed
153+
154+
### Physical Device
155+
- Requires manual IP configuration
156+
- Use DevTools for easy setup
157+
- Must be on same network as computer
158+
159+
## Success Indicators
160+
161+
**Authentication Working**:
162+
- Login redirects to main app
163+
- Logout shows confirmation and redirects to login
164+
- User data loads correctly
165+
- No network errors
166+
167+
**Platform Compatibility**:
168+
- Web works with localhost
169+
- Mobile works with appropriate URLs
170+
- Error messages are helpful
171+
- DevTools provide easy testing
172+
173+
**User Experience**:
174+
- Loading states show during auth actions
175+
- Clear error messages for failures
176+
- Smooth navigation between screens
177+
- No crashes or freezes

KonditionExpo/app/(tabs)/profile.tsx

Lines changed: 86 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,47 @@
11
import React, { useState } from 'react';
2-
import { SafeAreaView, View, Text, StyleSheet, ScrollView, TouchableOpacity, Image, Switch, Alert } from 'react-native';
2+
import { SafeAreaView, View, Text, StyleSheet, ScrollView, TouchableOpacity, Image, Switch } from 'react-native';
33
import { useUser } from '@/contexts/UserContext';
44
import { useAuth } from '@/contexts/AuthContext';
55
import { router } from 'expo-router';
6+
import { DevTools } from '@/components/DevTools';
7+
import { Dialog } from '@/components/ui/Dialog';
8+
import { Button } from '@/components/ui/Button';
69

710
const ProfileScreen = () => {
811
const { name, height, weight, age } = useUser();
912
const { user, logout, isLoading } = useAuth();
1013
const [notificationsEnabled, setNotificationsEnabled] = useState(false);
14+
const [showDevTools, setShowDevTools] = useState(false);
15+
const [showLogoutDialog, setShowLogoutDialog] = useState(false);
1116

1217
const toggleNotifications = () => setNotificationsEnabled(prev => !prev);
1318

1419
const handleLogout = () => {
15-
Alert.alert(
16-
'Sign Out',
17-
'Are you sure you want to sign out?',
18-
[
19-
{
20-
text: 'Cancel',
21-
style: 'cancel',
22-
},
23-
{
24-
text: 'Sign Out',
25-
style: 'destructive',
26-
onPress: async () => {
27-
try {
28-
await logout();
29-
// Navigation will be handled automatically by AuthNavigator
30-
} catch (error) {
31-
console.error('Logout error:', error);
32-
Alert.alert('Error', 'Failed to sign out. Please try again.');
33-
}
34-
},
35-
},
36-
]
37-
);
20+
setShowLogoutDialog(true);
21+
};
22+
23+
const confirmLogout = async () => {
24+
try {
25+
console.log('Starting logout process...');
26+
setShowLogoutDialog(false);
27+
await logout();
28+
console.log('Logout successful');
29+
// Navigation will be handled automatically by ProtectedRoute
30+
} catch (error) {
31+
console.error('Logout error:', error);
32+
// For web compatibility, we'll use a simple alert or could create another dialog
33+
if (typeof window !== 'undefined') {
34+
// Web environment
35+
alert(`Failed to sign out: ${error instanceof Error ? error.message : 'Unknown error'}. Please try again.`);
36+
} else {
37+
// Mobile environment - this shouldn't happen but as fallback
38+
console.error('Logout failed:', error);
39+
}
40+
}
41+
};
42+
43+
const cancelLogout = () => {
44+
setShowLogoutDialog(false);
3845
};
3946

4047
return (
@@ -93,6 +100,9 @@ const ProfileScreen = () => {
93100
<Text style={styles.optionItem}>Privacy Policy</Text>
94101
<Text style={styles.optionItem}>Contact Us</Text>
95102
<Text style={styles.optionItem}>Settings</Text>
103+
<TouchableOpacity onPress={() => setShowDevTools(true)}>
104+
<Text style={[styles.optionItem, { color: '#70A1FF' }]}>Developer Tools</Text>
105+
</TouchableOpacity>
96106
</View>
97107

98108
{/* Logout Button */}
@@ -106,6 +116,41 @@ const ProfileScreen = () => {
106116
</Text>
107117
</TouchableOpacity>
108118
</ScrollView>
119+
120+
{/* DevTools Modal */}
121+
<DevTools
122+
visible={showDevTools}
123+
onClose={() => setShowDevTools(false)}
124+
/>
125+
126+
{/* Logout Confirmation Dialog */}
127+
<Dialog
128+
isOpen={showLogoutDialog}
129+
onClose={cancelLogout}
130+
title="Sign Out"
131+
size="sm"
132+
footer={
133+
<View style={styles.dialogFooter}>
134+
<Button
135+
title="Cancel"
136+
variant="outline"
137+
onPress={cancelLogout}
138+
style={styles.cancelButton}
139+
/>
140+
<Button
141+
title="Sign Out"
142+
onPress={confirmLogout}
143+
loading={isLoading}
144+
loadingText="Signing Out..."
145+
style={styles.confirmButton}
146+
/>
147+
</View>
148+
}
149+
>
150+
<Text style={styles.dialogText}>
151+
Are you sure you want to sign out?
152+
</Text>
153+
</Dialog>
109154
</SafeAreaView>
110155
);
111156
};
@@ -139,6 +184,23 @@ const styles = StyleSheet.create({
139184
fontSize: 16,
140185
fontWeight: 'bold'
141186
},
187+
dialogFooter: {
188+
flexDirection: 'row',
189+
gap: 12,
190+
},
191+
cancelButton: {
192+
flex: 1,
193+
},
194+
confirmButton: {
195+
flex: 1,
196+
backgroundColor: '#FF6B6B',
197+
},
198+
dialogText: {
199+
fontSize: 16,
200+
color: '#333',
201+
textAlign: 'center',
202+
lineHeight: 24,
203+
},
142204
});
143205

144206
export default ProfileScreen;

0 commit comments

Comments
 (0)