@oxyhq/services 5.3.5 → 5.3.6

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.
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  import React, { useState, useEffect } from 'react';
4
- import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, Alert, Platform, Dimensions } from 'react-native';
4
+ import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, Alert, Image, Dimensions } from 'react-native';
5
5
  import { useOxy } from '../context/OxyContext';
6
6
  import { fontFamilies } from '../styles/fonts';
7
7
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
8
- const AccountSwitcherScreen = ({
8
+ const ModernAccountSwitcherScreen = ({
9
9
  onClose,
10
10
  theme,
11
11
  navigate,
@@ -21,11 +21,16 @@ const AccountSwitcherScreen = ({
21
21
  logoutAll,
22
22
  isLoading
23
23
  } = useOxy();
24
- const [allDeviceSessions, setAllDeviceSessions] = useState([]);
25
- const [loadingDeviceSessions, setLoadingDeviceSessions] = useState(false);
24
+ const [sessionsWithUsers, setSessionsWithUsers] = useState([]);
26
25
  const [switchingToUserId, setSwitchingToUserId] = useState(null);
27
26
  const [removingUserId, setRemovingUserId] = useState(null);
28
- const [showRemoteDevices, setShowRemoteDevices] = useState(false);
27
+
28
+ // Device session management state
29
+ const [showDeviceManagement, setShowDeviceManagement] = useState(false);
30
+ const [deviceSessions, setDeviceSessions] = useState([]);
31
+ const [loadingDeviceSessions, setLoadingDeviceSessions] = useState(false);
32
+ const [remotingLogoutSessionId, setRemoteLogoutSessionId] = useState(null);
33
+ const [loggingOutAllDevices, setLoggingOutAllDevices] = useState(false);
29
34
  const screenWidth = Dimensions.get('window').width;
30
35
  const isDarkTheme = theme === 'dark';
31
36
 
@@ -44,36 +49,38 @@ const AccountSwitcherScreen = ({
44
49
  shadow: isDarkTheme ? 'rgba(0,0,0,0.3)' : 'rgba(0,0,0,0.1)'
45
50
  };
46
51
 
47
- // Load all device sessions for remote management
48
- const loadAllDeviceSessions = async () => {
49
- if (!activeSessionId || !oxyServices) return;
50
- setLoadingDeviceSessions(true);
51
- try {
52
- const allSessions = await oxyServices.getSessionsBySessionId(activeSessionId);
53
- const deviceSessions = allSessions.map(session => ({
54
- sessionId: session.sessionId,
55
- deviceId: session.deviceId,
56
- deviceName: session.deviceName || 'Unknown Device',
57
- isActive: session.isActive,
58
- lastActive: session.lastActive || new Date().toISOString(),
59
- expiresAt: session.expiresAt || new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
60
- isCurrent: session.sessionId === activeSessionId
52
+ // Load user profiles for sessions
53
+ useEffect(() => {
54
+ const loadUserProfiles = async () => {
55
+ if (!sessions.length || !oxyServices) return;
56
+ const updatedSessions = sessions.map(session => ({
57
+ ...session,
58
+ isLoadingProfile: true
61
59
  }));
62
- setAllDeviceSessions(deviceSessions);
63
- } catch (error) {
64
- console.error('Failed to load device sessions:', error);
65
- Alert.alert('Error', 'Failed to load device sessions');
66
- } finally {
67
- setLoadingDeviceSessions(false);
68
- }
69
- };
60
+ setSessionsWithUsers(updatedSessions);
70
61
 
71
- // Load device sessions when showing remote devices
72
- useEffect(() => {
73
- if (showRemoteDevices) {
74
- loadAllDeviceSessions();
75
- }
76
- }, [showRemoteDevices, activeSessionId, oxyServices]);
62
+ // Load profiles for each session
63
+ for (let i = 0; i < sessions.length; i++) {
64
+ const session = sessions[i];
65
+ try {
66
+ // Try to get user profile using the session
67
+ const userProfile = await oxyServices.getUserBySession(session.sessionId);
68
+ setSessionsWithUsers(prev => prev.map(s => s.sessionId === session.sessionId ? {
69
+ ...s,
70
+ userProfile,
71
+ isLoadingProfile: false
72
+ } : s));
73
+ } catch (error) {
74
+ console.error(`Failed to load profile for session ${session.sessionId}:`, error);
75
+ setSessionsWithUsers(prev => prev.map(s => s.sessionId === session.sessionId ? {
76
+ ...s,
77
+ isLoadingProfile: false
78
+ } : s));
79
+ }
80
+ }
81
+ };
82
+ loadUserProfiles();
83
+ }, [sessions, oxyServices]);
77
84
  const handleSwitchSession = async sessionId => {
78
85
  if (sessionId === user?.sessionId) return; // Already active session
79
86
 
@@ -92,9 +99,10 @@ const AccountSwitcherScreen = ({
92
99
  }
93
100
  };
94
101
  const handleRemoveSession = async sessionId => {
95
- const sessionToRemove = sessions.find(s => s.sessionId === sessionId);
102
+ const sessionToRemove = sessionsWithUsers.find(s => s.sessionId === sessionId);
96
103
  if (!sessionToRemove) return;
97
- Alert.alert('Remove Account', `Are you sure you want to remove this session from this device? You'll need to sign in again to access this account.`, [{
104
+ const displayName = typeof sessionToRemove.userProfile?.name === 'object' ? sessionToRemove.userProfile.name.full || sessionToRemove.userProfile.name.first || sessionToRemove.userProfile.username : sessionToRemove.userProfile?.name || sessionToRemove.userProfile?.username || 'this account';
105
+ Alert.alert('Remove Account', `Are you sure you want to remove ${displayName} from this device? You'll need to sign in again to access this account.`, [{
98
106
  text: 'Cancel',
99
107
  style: 'cancel'
100
108
  }, {
@@ -139,22 +147,41 @@ const AccountSwitcherScreen = ({
139
147
  cancelable: true
140
148
  });
141
149
  };
150
+
151
+ // Device session management functions
152
+ const loadAllDeviceSessions = async () => {
153
+ if (!oxyServices || !user?.sessionId) return;
154
+ setLoadingDeviceSessions(true);
155
+ try {
156
+ // This would call the API to get all device sessions for the current user
157
+ const allSessions = await oxyServices.getDeviceSessions(user.sessionId);
158
+ setDeviceSessions(allSessions || []);
159
+ } catch (error) {
160
+ console.error('Failed to load device sessions:', error);
161
+ Alert.alert('Error', 'Failed to load device sessions. Please try again.');
162
+ } finally {
163
+ setLoadingDeviceSessions(false);
164
+ }
165
+ };
142
166
  const handleRemoteSessionLogout = async (sessionId, deviceName) => {
143
- Alert.alert('Logout Remote Session', `Are you sure you want to logout from "${deviceName}"?`, [{
167
+ Alert.alert('Remove Device Session', `Are you sure you want to sign out from "${deviceName}"? This will end the session on that device.`, [{
144
168
  text: 'Cancel',
145
169
  style: 'cancel'
146
170
  }, {
147
- text: 'Logout',
171
+ text: 'Sign Out',
148
172
  style: 'destructive',
149
173
  onPress: async () => {
174
+ setRemoteLogoutSessionId(sessionId);
150
175
  try {
151
- await oxyServices.logoutSecureSession(activeSessionId, sessionId);
152
- Alert.alert('Success', 'Remote session logged out successfully!');
153
- // Refresh the device sessions list
176
+ await oxyServices?.logoutSecureSession(user?.sessionId || '', sessionId);
177
+ // Refresh device sessions list
154
178
  await loadAllDeviceSessions();
179
+ Alert.alert('Success', `Signed out from ${deviceName} successfully!`);
155
180
  } catch (error) {
156
181
  console.error('Remote logout failed:', error);
157
- Alert.alert('Logout Failed', 'There was a problem logging out the remote session. Please try again.');
182
+ Alert.alert('Logout Failed', 'There was a problem signing out from the device. Please try again.');
183
+ } finally {
184
+ setRemoteLogoutSessionId(null);
158
185
  }
159
186
  }
160
187
  }], {
@@ -162,64 +189,182 @@ const AccountSwitcherScreen = ({
162
189
  });
163
190
  };
164
191
  const handleLogoutAllDevices = async () => {
165
- Alert.alert('Logout All Devices', 'Are you sure you want to logout from all other devices? This will keep your current session active.', [{
192
+ const otherDevicesCount = deviceSessions.filter(session => !session.isCurrent).length;
193
+ if (otherDevicesCount === 0) {
194
+ Alert.alert('No Other Devices', 'No other device sessions found to sign out from.');
195
+ return;
196
+ }
197
+ Alert.alert('Sign Out All Other Devices', `Are you sure you want to sign out from all ${otherDevicesCount} other device(s)? This will end sessions on all other devices except this one.`, [{
166
198
  text: 'Cancel',
167
199
  style: 'cancel'
168
200
  }, {
169
- text: 'Logout All Others',
201
+ text: 'Sign Out All',
170
202
  style: 'destructive',
171
203
  onPress: async () => {
204
+ setLoggingOutAllDevices(true);
172
205
  try {
173
- await oxyServices.logoutAllDeviceSessions(activeSessionId, undefined, true);
174
- Alert.alert('Success', 'All other device sessions logged out successfully!');
175
- // Refresh the device sessions list
206
+ await oxyServices?.logoutAllDeviceSessions(user?.sessionId || '', undefined, true);
207
+ // Refresh device sessions list
176
208
  await loadAllDeviceSessions();
209
+ Alert.alert('Success', `Signed out from all other devices successfully!`);
177
210
  } catch (error) {
178
211
  console.error('Logout all devices failed:', error);
179
- Alert.alert('Logout Failed', 'There was a problem logging out other devices. Please try again.');
212
+ Alert.alert('Logout Failed', 'There was a problem signing out from other devices. Please try again.');
213
+ } finally {
214
+ setLoggingOutAllDevices(false);
180
215
  }
181
216
  }
182
217
  }], {
183
218
  cancelable: true
184
219
  });
185
220
  };
186
- const renderSessionItem = session => {
187
- const isActive = session.sessionId === activeSessionId;
188
- const isSwitching = switchingToUserId === session.sessionId;
189
- const isRemoving = removingUserId === session.sessionId;
190
- return /*#__PURE__*/_jsxs(View, {
191
- style: [styles.userItem, {
192
- backgroundColor: isActive ? colors.activeCard : colors.surface,
193
- borderColor: isActive ? colors.accent : colors.border
221
+ const renderDeviceSessionItem = deviceSession => {
222
+ const isLoggingOut = remotingLogoutSessionId === deviceSession.sessionId;
223
+ return /*#__PURE__*/_jsx(View, {
224
+ style: [styles.sessionCard, {
225
+ backgroundColor: deviceSession.isCurrent ? colors.activeCard : colors.card,
226
+ borderColor: deviceSession.isCurrent ? colors.accent : colors.border,
227
+ borderWidth: deviceSession.isCurrent ? 2 : 1
194
228
  }],
195
- children: [/*#__PURE__*/_jsxs(View, {
196
- style: styles.userInfo,
197
- children: [/*#__PURE__*/_jsx(Text, {
198
- style: [styles.username, {
199
- color: colors.text
200
- }],
201
- children: isActive ? user?.username || 'Current Account' : 'Account Session'
202
- }), /*#__PURE__*/_jsxs(Text, {
203
- style: [styles.email, {
204
- color: isDarkTheme ? '#BBBBBB' : '#666666'
205
- }],
206
- children: ["Last active: ", new Date(session.lastActive).toLocaleDateString()]
207
- }), isActive && /*#__PURE__*/_jsx(View, {
208
- style: [styles.activeBadge, {
209
- backgroundColor: colors.success
229
+ children: /*#__PURE__*/_jsxs(View, {
230
+ style: styles.sessionHeader,
231
+ children: [/*#__PURE__*/_jsxs(View, {
232
+ style: styles.userInfo,
233
+ children: [/*#__PURE__*/_jsxs(Text, {
234
+ style: [styles.displayName, {
235
+ color: colors.text
236
+ }],
237
+ numberOfLines: 1,
238
+ children: [deviceSession.deviceName, deviceSession.isCurrent && /*#__PURE__*/_jsx(Text, {
239
+ style: [styles.username, {
240
+ color: colors.accent
241
+ }],
242
+ children: ' (This Device)'
243
+ })]
244
+ }), /*#__PURE__*/_jsxs(Text, {
245
+ style: [styles.username, {
246
+ color: colors.secondaryText
247
+ }],
248
+ numberOfLines: 1,
249
+ children: ["ID: ...", deviceSession.deviceId.slice(-8)]
250
+ }), /*#__PURE__*/_jsxs(Text, {
251
+ style: [styles.lastActive, {
252
+ color: colors.secondaryText
253
+ }],
254
+ numberOfLines: 1,
255
+ children: ["Last active: ", new Date(deviceSession.lastActive).toLocaleDateString()]
256
+ })]
257
+ }), !deviceSession.isCurrent && /*#__PURE__*/_jsx(TouchableOpacity, {
258
+ style: [styles.removeButton, {
259
+ borderColor: colors.destructive,
260
+ backgroundColor: colors.background
210
261
  }],
211
- children: /*#__PURE__*/_jsx(Text, {
212
- style: styles.activeBadgeText,
213
- children: "Active"
262
+ onPress: () => handleRemoteSessionLogout(deviceSession.sessionId, deviceSession.deviceName),
263
+ disabled: isLoggingOut,
264
+ children: isLoggingOut ? /*#__PURE__*/_jsx(ActivityIndicator, {
265
+ color: colors.destructive,
266
+ size: "small"
267
+ }) : /*#__PURE__*/_jsx(Text, {
268
+ style: [styles.removeButtonText, {
269
+ color: colors.destructive
270
+ }],
271
+ children: "Sign Out"
214
272
  })
215
273
  })]
274
+ })
275
+ }, deviceSession.sessionId);
276
+ };
277
+
278
+ // Load device sessions when device management is shown
279
+ useEffect(() => {
280
+ if (showDeviceManagement && deviceSessions.length === 0) {
281
+ loadAllDeviceSessions();
282
+ }
283
+ }, [showDeviceManagement]);
284
+ const renderSessionItem = sessionWithUser => {
285
+ const isActive = sessionWithUser.sessionId === activeSessionId;
286
+ const isSwitching = switchingToUserId === sessionWithUser.sessionId;
287
+ const isRemoving = removingUserId === sessionWithUser.sessionId;
288
+ const {
289
+ userProfile,
290
+ isLoadingProfile
291
+ } = sessionWithUser;
292
+ const displayName = typeof userProfile?.name === 'object' ? userProfile.name.full || userProfile.name.first || userProfile.username : userProfile?.name || userProfile?.username || 'Unknown User';
293
+ const username = userProfile?.username || 'unknown';
294
+ const avatarUrl = userProfile?.avatar?.url;
295
+ return /*#__PURE__*/_jsxs(View, {
296
+ style: [styles.sessionCard, {
297
+ backgroundColor: isActive ? colors.activeCard : colors.card,
298
+ borderColor: isActive ? colors.accent : colors.border,
299
+ borderWidth: isActive ? 2 : 1,
300
+ shadowColor: colors.shadow
301
+ }],
302
+ children: [/*#__PURE__*/_jsxs(View, {
303
+ style: styles.sessionHeader,
304
+ children: [/*#__PURE__*/_jsxs(View, {
305
+ style: styles.avatarContainer,
306
+ children: [isLoadingProfile ? /*#__PURE__*/_jsx(View, {
307
+ style: [styles.avatarPlaceholder, {
308
+ backgroundColor: colors.surface
309
+ }],
310
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
311
+ size: "small",
312
+ color: colors.accent
313
+ })
314
+ }) : avatarUrl ? /*#__PURE__*/_jsx(Image, {
315
+ source: {
316
+ uri: avatarUrl
317
+ },
318
+ style: styles.avatar
319
+ }) : /*#__PURE__*/_jsx(View, {
320
+ style: [styles.avatarPlaceholder, {
321
+ backgroundColor: colors.surface
322
+ }],
323
+ children: /*#__PURE__*/_jsx(Text, {
324
+ style: [styles.avatarText, {
325
+ color: colors.accent
326
+ }],
327
+ children: displayName.charAt(0).toUpperCase()
328
+ })
329
+ }), isActive && /*#__PURE__*/_jsx(View, {
330
+ style: [styles.activeBadge, {
331
+ backgroundColor: colors.success
332
+ }],
333
+ children: /*#__PURE__*/_jsx(Text, {
334
+ style: styles.activeBadgeText,
335
+ children: "\u2713"
336
+ })
337
+ })]
338
+ }), /*#__PURE__*/_jsxs(View, {
339
+ style: styles.userInfo,
340
+ children: [/*#__PURE__*/_jsx(Text, {
341
+ style: [styles.displayName, {
342
+ color: colors.text
343
+ }],
344
+ numberOfLines: 1,
345
+ children: displayName
346
+ }), /*#__PURE__*/_jsxs(Text, {
347
+ style: [styles.username, {
348
+ color: colors.secondaryText
349
+ }],
350
+ numberOfLines: 1,
351
+ children: ["@", username]
352
+ }), /*#__PURE__*/_jsxs(Text, {
353
+ style: [styles.lastActive, {
354
+ color: colors.secondaryText
355
+ }],
356
+ numberOfLines: 1,
357
+ children: ["Last active: ", new Date(sessionWithUser.lastActive).toLocaleDateString()]
358
+ })]
359
+ })]
216
360
  }), /*#__PURE__*/_jsxs(View, {
217
- style: styles.userActions,
361
+ style: styles.sessionActions,
218
362
  children: [!isActive && /*#__PURE__*/_jsx(TouchableOpacity, {
219
363
  style: [styles.switchButton, {
220
- borderColor: colors.accent
364
+ borderColor: colors.accent,
365
+ backgroundColor: colors.background
221
366
  }],
222
- onPress: () => handleSwitchSession(session.sessionId),
367
+ onPress: () => handleSwitchSession(sessionWithUser.sessionId),
223
368
  disabled: isSwitching || isRemoving,
224
369
  children: isSwitching ? /*#__PURE__*/_jsx(ActivityIndicator, {
225
370
  color: colors.accent,
@@ -232,10 +377,11 @@ const AccountSwitcherScreen = ({
232
377
  })
233
378
  }), /*#__PURE__*/_jsx(TouchableOpacity, {
234
379
  style: [styles.removeButton, {
235
- borderColor: colors.destructive
380
+ borderColor: colors.destructive,
381
+ backgroundColor: colors.background
236
382
  }],
237
- onPress: () => handleRemoveSession(session.sessionId),
238
- disabled: isSwitching || isRemoving || sessions.length === 1,
383
+ onPress: () => handleRemoveSession(sessionWithUser.sessionId),
384
+ disabled: isSwitching || isRemoving,
239
385
  children: isRemoving ? /*#__PURE__*/_jsx(ActivityIndicator, {
240
386
  color: colors.destructive,
241
387
  size: "small"
@@ -247,57 +393,7 @@ const AccountSwitcherScreen = ({
247
393
  })
248
394
  })]
249
395
  })]
250
- }, session.sessionId);
251
- };
252
- const renderDeviceSessionItem = deviceSession => {
253
- const isCurrentSession = deviceSession.isCurrent;
254
- return /*#__PURE__*/_jsxs(View, {
255
- style: [styles.userItem, {
256
- backgroundColor: isCurrentSession ? colors.activeCard : colors.surface,
257
- borderColor: isCurrentSession ? colors.accent : colors.border
258
- }],
259
- children: [/*#__PURE__*/_jsxs(View, {
260
- style: styles.userInfo,
261
- children: [/*#__PURE__*/_jsxs(Text, {
262
- style: [styles.username, {
263
- color: colors.text
264
- }],
265
- children: [deviceSession.deviceName, isCurrentSession && ' (This Device)']
266
- }), /*#__PURE__*/_jsxs(Text, {
267
- style: [styles.email, {
268
- color: isDarkTheme ? '#BBBBBB' : '#666666'
269
- }],
270
- children: ["Last active: ", new Date(deviceSession.lastActive).toLocaleDateString()]
271
- }), /*#__PURE__*/_jsxs(Text, {
272
- style: [styles.email, {
273
- color: isDarkTheme ? '#BBBBBB' : '#666666'
274
- }],
275
- children: ["Device ID: ", deviceSession.deviceId.substring(0, 8), "..."]
276
- }), isCurrentSession && /*#__PURE__*/_jsx(View, {
277
- style: [styles.activeBadge, {
278
- backgroundColor: colors.success
279
- }],
280
- children: /*#__PURE__*/_jsx(Text, {
281
- style: styles.activeBadgeText,
282
- children: "Current"
283
- })
284
- })]
285
- }), /*#__PURE__*/_jsx(View, {
286
- style: styles.userActions,
287
- children: !isCurrentSession && /*#__PURE__*/_jsx(TouchableOpacity, {
288
- style: [styles.removeButton, {
289
- borderColor: colors.destructive
290
- }],
291
- onPress: () => handleRemoteSessionLogout(deviceSession.sessionId, deviceSession.deviceName),
292
- children: /*#__PURE__*/_jsx(Text, {
293
- style: [styles.removeButtonText, {
294
- color: colors.destructive
295
- }],
296
- children: "Logout"
297
- })
298
- })
299
- })]
300
- }, deviceSession.sessionId);
396
+ }, sessionWithUser.sessionId);
301
397
  };
302
398
  return /*#__PURE__*/_jsxs(View, {
303
399
  style: [styles.container, {
@@ -318,115 +414,159 @@ const AccountSwitcherScreen = ({
318
414
  style: [styles.title, {
319
415
  color: colors.text
320
416
  }],
321
- children: "Account Switcher"
417
+ children: "Accounts"
322
418
  }), /*#__PURE__*/_jsx(View, {
323
- style: styles.placeholder
419
+ style: styles.headerSpacer
324
420
  })]
325
- }), /*#__PURE__*/_jsxs(ScrollView, {
326
- style: styles.scrollView,
327
- contentContainerStyle: styles.scrollContainer,
328
- children: [/*#__PURE__*/_jsx(View, {
329
- style: styles.description,
330
- children: /*#__PURE__*/_jsx(Text, {
331
- style: [styles.descriptionText, {
332
- color: isDarkTheme ? '#BBBBBB' : '#666666'
421
+ }), /*#__PURE__*/_jsx(ScrollView, {
422
+ style: styles.content,
423
+ showsVerticalScrollIndicator: false,
424
+ contentContainerStyle: styles.scrollContent,
425
+ children: isLoading ? /*#__PURE__*/_jsxs(View, {
426
+ style: styles.loadingContainer,
427
+ children: [/*#__PURE__*/_jsx(ActivityIndicator, {
428
+ size: "large",
429
+ color: colors.accent
430
+ }), /*#__PURE__*/_jsx(Text, {
431
+ style: [styles.loadingText, {
432
+ color: colors.secondaryText
333
433
  }],
334
- children: "Manage multiple accounts on this device. Switch between accounts or remove them from this device."
335
- })
336
- }), /*#__PURE__*/_jsxs(View, {
337
- style: styles.usersContainer,
434
+ children: "Loading accounts..."
435
+ })]
436
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
338
437
  children: [/*#__PURE__*/_jsxs(Text, {
339
438
  style: [styles.sectionTitle, {
340
439
  color: colors.text
341
440
  }],
342
- children: ["Local Sessions (", sessions.length, ")"]
343
- }), sessions.map(renderSessionItem)]
344
- }), /*#__PURE__*/_jsxs(View, {
345
- style: styles.usersContainer,
346
- children: [/*#__PURE__*/_jsxs(View, {
347
- style: styles.sectionHeader,
348
- children: [/*#__PURE__*/_jsx(Text, {
349
- style: [styles.sectionTitle, {
350
- color: colors.text
441
+ children: ["Saved Accounts (", sessionsWithUsers.length, ")"]
442
+ }), sessionsWithUsers.length === 0 ? /*#__PURE__*/_jsx(View, {
443
+ style: styles.emptyState,
444
+ children: /*#__PURE__*/_jsx(Text, {
445
+ style: [styles.emptyText, {
446
+ color: colors.secondaryText
351
447
  }],
352
- children: "All Devices & Sessions"
353
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
354
- style: [styles.toggleButton, {
355
- borderColor: colors.accent
448
+ children: "No saved accounts found"
449
+ })
450
+ }) : sessionsWithUsers.map(renderSessionItem), /*#__PURE__*/_jsxs(View, {
451
+ style: styles.actionsSection,
452
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
453
+ style: [styles.actionButton, {
454
+ borderColor: colors.border,
455
+ backgroundColor: colors.card
356
456
  }],
357
- onPress: () => setShowRemoteDevices(!showRemoteDevices),
457
+ onPress: () => navigate?.('SignIn'),
358
458
  children: /*#__PURE__*/_jsx(Text, {
359
- style: [styles.toggleButtonText, {
360
- color: colors.accent
459
+ style: [styles.actionButtonText, {
460
+ color: colors.text
461
+ }],
462
+ children: "+ Add Another Account"
463
+ })
464
+ }), sessionsWithUsers.length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
465
+ style: [styles.actionButton, styles.dangerButton, {
466
+ borderColor: colors.destructive,
467
+ backgroundColor: colors.background
468
+ }],
469
+ onPress: handleLogoutAll,
470
+ children: /*#__PURE__*/_jsx(Text, {
471
+ style: [styles.dangerButtonText, {
472
+ color: colors.destructive
361
473
  }],
362
- children: showRemoteDevices ? 'Hide' : 'Show'
474
+ children: "Sign Out All Accounts"
363
475
  })
364
476
  })]
365
- }), showRemoteDevices && /*#__PURE__*/_jsx(_Fragment, {
366
- children: loadingDeviceSessions ? /*#__PURE__*/_jsxs(View, {
477
+ }), /*#__PURE__*/_jsx(View, {
478
+ style: styles.actionsSection,
479
+ children: /*#__PURE__*/_jsx(TouchableOpacity, {
480
+ style: [styles.actionButton, {
481
+ borderColor: colors.border,
482
+ backgroundColor: colors.card
483
+ }],
484
+ onPress: () => setShowDeviceManagement(!showDeviceManagement),
485
+ children: /*#__PURE__*/_jsx(Text, {
486
+ style: [styles.actionButtonText, {
487
+ color: colors.text
488
+ }],
489
+ children: showDeviceManagement ? '− Hide Device Management' : '+ Manage Device Sessions'
490
+ })
491
+ })
492
+ }), showDeviceManagement && /*#__PURE__*/_jsxs(View, {
493
+ style: [styles.deviceManagementSection, {
494
+ backgroundColor: colors.card,
495
+ borderColor: colors.border
496
+ }],
497
+ children: [/*#__PURE__*/_jsx(Text, {
498
+ style: [styles.sectionTitle, {
499
+ color: colors.text
500
+ }],
501
+ children: "Device Sessions"
502
+ }), loadingDeviceSessions ? /*#__PURE__*/_jsxs(View, {
367
503
  style: styles.loadingContainer,
368
504
  children: [/*#__PURE__*/_jsx(ActivityIndicator, {
369
- color: colors.accent,
370
- size: "small"
505
+ size: "large",
506
+ color: colors.accent
371
507
  }), /*#__PURE__*/_jsx(Text, {
372
508
  style: [styles.loadingText, {
373
509
  color: colors.secondaryText
374
510
  }],
375
511
  children: "Loading device sessions..."
376
512
  })]
377
- }) : /*#__PURE__*/_jsx(_Fragment, {
378
- children: allDeviceSessions.length > 0 ? /*#__PURE__*/_jsxs(_Fragment, {
379
- children: [allDeviceSessions.map(renderDeviceSessionItem), allDeviceSessions.filter(s => !s.isCurrent).length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
380
- style: [styles.actionButton, {
381
- borderColor: colors.destructive,
382
- marginTop: 12
383
- }],
384
- onPress: handleLogoutAllDevices,
385
- children: /*#__PURE__*/_jsx(Text, {
386
- style: [styles.actionButtonText, {
387
- color: colors.destructive
388
- }],
389
- children: "Logout All Other Devices"
390
- })
391
- })]
392
- }) : /*#__PURE__*/_jsx(Text, {
513
+ }) : deviceSessions.length === 0 ? /*#__PURE__*/_jsx(View, {
514
+ style: styles.emptyState,
515
+ children: /*#__PURE__*/_jsx(Text, {
393
516
  style: [styles.emptyText, {
394
517
  color: colors.secondaryText
395
518
  }],
396
- children: "No other device sessions found"
519
+ children: "No device sessions found"
397
520
  })
398
- })
399
- })]
400
- }), /*#__PURE__*/_jsxs(View, {
401
- style: styles.actionsContainer,
402
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
403
- style: [styles.actionButton, {
404
- borderColor: colors.border
405
- }],
406
- onPress: () => navigate('SignIn'),
407
- children: /*#__PURE__*/_jsx(Text, {
408
- style: [styles.actionButtonText, {
409
- color: colors.text
521
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
522
+ children: [deviceSessions.map(renderDeviceSessionItem), deviceSessions.filter(session => !session.isCurrent).length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
523
+ style: [styles.actionButton, styles.dangerButton, {
524
+ borderColor: colors.destructive,
525
+ backgroundColor: colors.background,
526
+ marginTop: 20
527
+ }],
528
+ onPress: handleLogoutAllDevices,
529
+ disabled: loggingOutAllDevices,
530
+ children: loggingOutAllDevices ? /*#__PURE__*/_jsx(ActivityIndicator, {
531
+ color: colors.destructive,
532
+ size: "small"
533
+ }) : /*#__PURE__*/_jsx(Text, {
534
+ style: [styles.dangerButtonText, {
535
+ color: colors.destructive
536
+ }],
537
+ children: "Sign Out All Other Devices"
538
+ })
539
+ })]
540
+ })]
541
+ }), /*#__PURE__*/_jsxs(View, {
542
+ style: styles.actionsSection,
543
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
544
+ style: [styles.actionButton, {
545
+ borderColor: colors.border,
546
+ backgroundColor: colors.card
410
547
  }],
411
- children: "Add Another Account"
412
- })
413
- }), sessions.length > 1 && /*#__PURE__*/_jsx(TouchableOpacity, {
414
- style: [styles.dangerButton, {
415
- backgroundColor: isDarkTheme ? '#300000' : '#FFEBEE'
416
- }],
417
- onPress: handleLogoutAll,
418
- disabled: isLoading,
419
- children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
420
- color: colors.destructive,
421
- size: "small"
422
- }) : /*#__PURE__*/_jsx(Text, {
423
- style: [styles.dangerButtonText, {
424
- color: colors.destructive
548
+ onPress: () => navigate?.('SignIn'),
549
+ children: /*#__PURE__*/_jsx(Text, {
550
+ style: [styles.actionButtonText, {
551
+ color: colors.text
552
+ }],
553
+ children: "+ Add Another Account"
554
+ })
555
+ }), sessionsWithUsers.length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
556
+ style: [styles.actionButton, styles.dangerButton, {
557
+ borderColor: colors.destructive,
558
+ backgroundColor: colors.background
425
559
  }],
426
- children: "Sign Out All Sessions"
427
- })
560
+ onPress: handleLogoutAll,
561
+ children: /*#__PURE__*/_jsx(Text, {
562
+ style: [styles.dangerButtonText, {
563
+ color: colors.destructive
564
+ }],
565
+ children: "Sign Out All Accounts"
566
+ })
567
+ })]
428
568
  })]
429
- })]
569
+ })
430
570
  })]
431
571
  });
432
572
  };
@@ -439,168 +579,187 @@ const styles = StyleSheet.create({
439
579
  alignItems: 'center',
440
580
  justifyContent: 'space-between',
441
581
  paddingHorizontal: 20,
442
- paddingTop: Platform.OS === 'ios' ? 50 : 20,
443
- paddingBottom: 20,
444
- borderBottomWidth: 1,
445
- borderBottomColor: 'rgba(0, 0, 0, 0.1)'
582
+ paddingTop: 20,
583
+ paddingBottom: 10
446
584
  },
447
585
  backButton: {
448
- paddingVertical: 8,
449
- paddingHorizontal: 4
586
+ padding: 8
450
587
  },
451
588
  backButtonText: {
452
589
  fontSize: 18,
453
- fontFamily: fontFamilies.phudu
590
+ fontFamily: fontFamilies.phuduMedium
454
591
  },
455
592
  title: {
456
- fontSize: 20,
457
- fontFamily: fontFamilies.phuduSemiBold,
593
+ fontSize: 24,
594
+ fontFamily: fontFamilies.phuduBold,
458
595
  textAlign: 'center'
459
596
  },
460
- placeholder: {
461
- width: 60 // Same as back button to center title
597
+ headerSpacer: {
598
+ width: 40
462
599
  },
463
- scrollView: {
464
- flex: 1
465
- },
466
- scrollContainer: {
467
- padding: 20
600
+ content: {
601
+ flex: 1,
602
+ paddingHorizontal: 20
468
603
  },
469
- description: {
470
- marginBottom: 24
604
+ scrollContent: {
605
+ paddingBottom: 40
471
606
  },
472
- descriptionText: {
473
- fontSize: 14,
474
- fontFamily: fontFamilies.phudu,
475
- lineHeight: 20
607
+ loadingContainer: {
608
+ flex: 1,
609
+ justifyContent: 'center',
610
+ alignItems: 'center',
611
+ paddingTop: 60
476
612
  },
477
- usersContainer: {
478
- marginBottom: 32
613
+ loadingText: {
614
+ marginTop: 16,
615
+ fontSize: 16,
616
+ fontFamily: fontFamilies.phudu
479
617
  },
480
618
  sectionTitle: {
481
- fontSize: 16,
619
+ fontSize: 20,
482
620
  fontFamily: fontFamilies.phuduSemiBold,
483
- marginBottom: 16
621
+ marginBottom: 20,
622
+ marginTop: 10
623
+ },
624
+ emptyState: {
625
+ alignItems: 'center',
626
+ paddingVertical: 40
627
+ },
628
+ emptyText: {
629
+ fontSize: 16,
630
+ fontFamily: fontFamilies.phudu,
631
+ textAlign: 'center'
484
632
  },
485
- userItem: {
633
+ sessionCard: {
634
+ borderRadius: 16,
635
+ marginBottom: 16,
636
+ padding: 20,
637
+ shadowOffset: {
638
+ width: 0,
639
+ height: 2
640
+ },
641
+ shadowOpacity: 0.1,
642
+ shadowRadius: 8,
643
+ elevation: 3
644
+ },
645
+ sessionHeader: {
486
646
  flexDirection: 'row',
487
647
  alignItems: 'center',
488
- justifyContent: 'space-between',
489
- padding: 16,
490
- borderRadius: 12,
491
- borderWidth: 1,
492
- marginBottom: 12
648
+ marginBottom: 16
649
+ },
650
+ avatarContainer: {
651
+ position: 'relative',
652
+ marginRight: 16
653
+ },
654
+ avatar: {
655
+ width: 60,
656
+ height: 60,
657
+ borderRadius: 30
658
+ },
659
+ avatarPlaceholder: {
660
+ width: 60,
661
+ height: 60,
662
+ borderRadius: 30,
663
+ justifyContent: 'center',
664
+ alignItems: 'center'
665
+ },
666
+ avatarText: {
667
+ fontSize: 24,
668
+ fontFamily: fontFamilies.phuduBold
669
+ },
670
+ activeBadge: {
671
+ position: 'absolute',
672
+ bottom: -2,
673
+ right: -2,
674
+ width: 20,
675
+ height: 20,
676
+ borderRadius: 10,
677
+ justifyContent: 'center',
678
+ alignItems: 'center'
679
+ },
680
+ activeBadgeText: {
681
+ color: 'white',
682
+ fontSize: 12,
683
+ fontFamily: fontFamilies.phuduBold
493
684
  },
494
685
  userInfo: {
495
- flex: 1
686
+ flex: 1,
687
+ justifyContent: 'center'
496
688
  },
497
- username: {
498
- fontSize: 16,
689
+ displayName: {
690
+ fontSize: 18,
499
691
  fontFamily: fontFamilies.phuduSemiBold,
500
692
  marginBottom: 4
501
693
  },
502
- email: {
694
+ username: {
503
695
  fontSize: 14,
504
696
  fontFamily: fontFamilies.phudu,
505
- marginBottom: 8
506
- },
507
- activeBadge: {
508
- paddingHorizontal: 8,
509
- paddingVertical: 4,
510
- borderRadius: 6,
511
- alignSelf: 'flex-start'
697
+ marginBottom: 4
512
698
  },
513
- activeBadgeText: {
514
- color: '#FFFFFF',
699
+ lastActive: {
515
700
  fontSize: 12,
516
- fontFamily: fontFamilies.phuduMedium
701
+ fontFamily: fontFamilies.phudu
517
702
  },
518
- userActions: {
703
+ sessionActions: {
519
704
  flexDirection: 'row',
520
- gap: 8
705
+ justifyContent: 'space-between',
706
+ gap: 12
521
707
  },
522
708
  switchButton: {
523
- paddingHorizontal: 16,
524
- paddingVertical: 8,
525
- borderRadius: 8,
709
+ flex: 1,
710
+ paddingVertical: 12,
711
+ paddingHorizontal: 20,
526
712
  borderWidth: 1,
527
- minWidth: 70,
528
- alignItems: 'center'
713
+ borderRadius: 8,
714
+ alignItems: 'center',
715
+ justifyContent: 'center'
529
716
  },
530
717
  switchButtonText: {
531
718
  fontSize: 14,
532
- fontFamily: fontFamilies.phuduMedium
719
+ fontFamily: fontFamilies.phuduSemiBold
533
720
  },
534
721
  removeButton: {
535
- paddingHorizontal: 16,
536
- paddingVertical: 8,
537
- borderRadius: 8,
722
+ flex: 1,
723
+ paddingVertical: 12,
724
+ paddingHorizontal: 20,
538
725
  borderWidth: 1,
539
- minWidth: 70,
540
- alignItems: 'center'
726
+ borderRadius: 8,
727
+ alignItems: 'center',
728
+ justifyContent: 'center'
541
729
  },
542
730
  removeButtonText: {
543
731
  fontSize: 14,
544
- fontFamily: fontFamilies.phuduMedium
732
+ fontFamily: fontFamilies.phuduSemiBold
545
733
  },
546
- actionsContainer: {
734
+ actionsSection: {
735
+ marginTop: 40,
547
736
  gap: 16
548
737
  },
549
738
  actionButton: {
550
739
  paddingVertical: 16,
551
740
  paddingHorizontal: 20,
552
- borderRadius: 12,
553
741
  borderWidth: 1,
554
- alignItems: 'center'
742
+ borderRadius: 12,
743
+ alignItems: 'center',
744
+ justifyContent: 'center'
555
745
  },
556
746
  actionButtonText: {
557
747
  fontSize: 16,
558
- fontFamily: fontFamilies.phuduMedium
748
+ fontFamily: fontFamilies.phuduSemiBold
559
749
  },
560
750
  dangerButton: {
561
- paddingVertical: 16,
562
- paddingHorizontal: 20,
563
- borderRadius: 12,
564
- alignItems: 'center'
751
+ // Additional styles for danger buttons if needed
565
752
  },
566
753
  dangerButtonText: {
567
754
  fontSize: 16,
568
- fontFamily: fontFamilies.phuduMedium
569
- },
570
- sectionHeader: {
571
- flexDirection: 'row',
572
- alignItems: 'center',
573
- justifyContent: 'space-between',
574
- marginBottom: 16
755
+ fontFamily: fontFamilies.phuduSemiBold
575
756
  },
576
- toggleButton: {
577
- paddingHorizontal: 12,
578
- paddingVertical: 6,
579
- borderRadius: 6,
757
+ deviceManagementSection: {
758
+ marginTop: 20,
759
+ padding: 16,
760
+ borderRadius: 12,
580
761
  borderWidth: 1
581
- },
582
- toggleButtonText: {
583
- fontSize: 14,
584
- fontFamily: fontFamilies.phuduMedium
585
- },
586
- loadingContainer: {
587
- flexDirection: 'row',
588
- alignItems: 'center',
589
- justifyContent: 'center',
590
- paddingVertical: 20,
591
- gap: 8
592
- },
593
- loadingText: {
594
- fontSize: 14,
595
- fontFamily: fontFamilies.phudu
596
- },
597
- emptyText: {
598
- fontSize: 14,
599
- fontFamily: fontFamilies.phudu,
600
- textAlign: 'center',
601
- paddingVertical: 20,
602
- fontStyle: 'italic'
603
762
  }
604
763
  });
605
- export default AccountSwitcherScreen;
764
+ export default ModernAccountSwitcherScreen;
606
765
  //# sourceMappingURL=AccountSwitcherScreen.js.map