@oxyhq/services
Version:
758 lines (744 loc) • 29.5 kB
JavaScript
"use strict";
import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, Alert, Platform, Image } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import Avatar from "../components/Avatar.js";
import OxyIcon from "../components/icon/OxyIcon.js";
import { fontFamilies } from "../styles/fonts.js";
import { toast } from '../../lib/sonner';
import { confirmAction } from "../utils/confirmAction.js";
import { Section, GroupedSection, GroupedItem } from "../components/index.js";
import { useI18n } from "../hooks/useI18n.js";
import { useThemeStyles } from "../hooks/useThemeStyles.js";
import { getDisplayName, getShortDisplayName } from "../utils/userUtils.js";
import { useColorScheme } from "../hooks/useColorScheme.js";
import { normalizeTheme } from "../utils/themeUtils.js";
import { useOxy } from "../context/OxyContext.js";
import { useUsersBySessions } from "../hooks/queries/useAccountQueries.js";
import { SECTION_GAP, HEADER_PADDING_TOP_OVERVIEW, createScreenContentStyle } from "../constants/spacing.js";
import { DeleteAccountModal } from "../components/modals/index.js";
// Optional Lottie import - gracefully handle if not available
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
let LottieView = null;
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
LottieView = require('lottie-react-native').default;
} catch {
// Lottie not available, will use fallback
}
// Import Lottie animation - will be undefined if file doesn't exist
let lottieAnimation = undefined;
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
lottieAnimation = require('../assets/lottie/welcomeheader_background_op1.json');
} catch {
// Animation file not available
}
/**
* AccountOverviewScreen - Optimized for performance
*
* Performance optimizations implemented:
* - useMemo for theme calculations (only recalculates when theme changes)
* - useMemo for additional accounts filtering (only recalculates when dependencies change)
* - useCallback for event handlers to prevent unnecessary re-renders
* - React.memo wrapper to prevent re-renders when props haven't changed
* - GroupedSection components for better organization and cleaner code
*/
const AccountOverviewScreen = ({
onClose,
theme,
navigate
}) => {
// Use useOxy() hook for OxyContext values
const {
user,
logout,
isLoading,
sessions,
activeSessionId,
oxyServices,
isAuthenticated,
openAvatarPicker
} = useOxy();
const {
t
} = useI18n();
const [showMoreAccounts, setShowMoreAccounts] = useState(false);
const [additionalAccountsData, setAdditionalAccountsData] = useState([]);
const [loadingAdditionalAccounts, setLoadingAdditionalAccounts] = useState(false);
const [showDeleteModal, setShowDeleteModal] = useState(false);
const lottieRef = useRef(null);
const hasPlayedRef = useRef(false);
const insets = useSafeAreaInsets();
// Use centralized theme styles hook for consistency
const colorScheme = useColorScheme();
const normalizedTheme = normalizeTheme(theme);
const baseThemeStyles = useThemeStyles(normalizedTheme, colorScheme);
const themeStyles = useMemo(() => ({
...baseThemeStyles,
// AccountOverviewScreen uses a custom primary color (purple) instead of the default blue
primaryColor: '#d169e5',
// Keep custom icon color for this screen
iconColor: baseThemeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
}), [baseThemeStyles]);
// Compute user data for display
const displayName = useMemo(() => getDisplayName(user), [user]);
const shortDisplayName = useMemo(() => getShortDisplayName(user), [user]);
const avatarUrl = useMemo(() => {
if (user?.avatar && oxyServices) {
return oxyServices.getFileDownloadUrl(user.avatar, 'thumb');
}
return undefined;
}, [user?.avatar, oxyServices]);
// Handle avatar press - use openAvatarPicker from context
const handleAvatarPress = useCallback(() => {
openAvatarPicker();
}, [openAvatarPicker]);
// Play Lottie animation once when component mounts
useEffect(() => {
if (hasPlayedRef.current || !LottieView || !lottieRef.current || !lottieAnimation) return;
const timer = setTimeout(() => {
if (lottieRef.current && !hasPlayedRef.current) {
lottieRef.current.play();
hasPlayedRef.current = true;
}
}, 100);
return () => clearTimeout(timer);
}, []);
// Memoize additional accounts filtering to prevent recalculation on every render
const additionalAccounts = useMemo(() => (sessions || []).filter(session => session.sessionId !== activeSessionId && session.userId !== user?.id), [sessions, activeSessionId, user?.id]);
// Load user profiles for additional accounts using TanStack Query
const sessionIds = additionalAccounts.map(s => s.sessionId);
const {
data: usersData,
isLoading: isLoadingUsers
} = useUsersBySessions(sessionIds, {
enabled: additionalAccounts.length > 0
});
React.useEffect(() => {
if (usersData && usersData.length > 0) {
const accountsData = usersData.map(({
sessionId,
user: userProfile
}) => {
if (!userProfile) {
return {
id: sessionId,
sessionId,
username: 'Unknown User',
email: 'No email available',
avatar: null,
userProfile: null
};
}
return {
id: sessionId,
sessionId,
username: userProfile.username,
email: userProfile.email,
name: userProfile.name,
avatar: userProfile.avatar,
userProfile
};
});
setAdditionalAccountsData(accountsData);
setLoadingAdditionalAccounts(false);
} else if (additionalAccounts.length === 0) {
setAdditionalAccountsData([]);
setLoadingAdditionalAccounts(false);
} else if (!isLoadingUsers) {
setLoadingAdditionalAccounts(false);
}
}, [usersData, additionalAccounts.length, isLoadingUsers]);
// Feature settings (with mock values)
const features = {
safeSearch: false,
language: 'English'
};
// Memoize event handlers to prevent recreation on every render
const handleLogout = useCallback(async () => {
try {
await logout();
if (onClose) {
onClose();
}
} catch (error) {
if (__DEV__) {
console.error('Logout failed:', error);
}
toast.error(t('common.errors.signOutFailed'));
}
}, [logout, onClose]);
const confirmLogout = useCallback(() => {
confirmAction(t('common.confirms.signOut'), handleLogout);
}, [handleLogout]);
const handleAddAccount = useCallback(() => {
toast.info(t('accountOverview.addAccountComing'));
}, [t]);
const handleSignOutAll = useCallback(() => {
confirmAction(t('common.confirms.signOutAll'), handleLogout);
}, [handleLogout]);
const handleDownloadData = useCallback(async () => {
if (!oxyServices || !user) {
toast.error(t('accountOverview.items.downloadData.error') || 'Service not available');
return;
}
try {
Alert.alert(t('accountOverview.items.downloadData.confirmTitle') || 'Download Account Data', t('accountOverview.items.downloadData.confirmMessage') || 'Choose the format for your account data export:', [{
text: t('common.cancel') || 'Cancel',
style: 'cancel'
}, {
text: 'JSON',
onPress: async () => {
try {
toast.loading(t('accountOverview.items.downloadData.downloading') || 'Preparing download...');
const blob = await oxyServices.downloadAccountData('json');
// Create download link for web
if (Platform.OS === 'web') {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `account-data-${Date.now()}.json`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
} else {
// For React Native, you'd need to use a library like expo-file-system
toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
}
} catch (error) {
if (__DEV__) {
console.error('Failed to download data:', error);
}
toast.error(error?.message || t('accountOverview.items.downloadData.error') || 'Failed to download data');
}
}
}, {
text: 'CSV',
onPress: async () => {
try {
toast.loading(t('accountOverview.items.downloadData.downloading') || 'Preparing download...');
const blob = await oxyServices.downloadAccountData('csv');
// Create download link for web
if (Platform.OS === 'web') {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `account-data-${Date.now()}.csv`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
} else {
// For React Native, you'd need to use a library like expo-file-system
toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
}
} catch (error) {
if (__DEV__) {
console.error('Failed to download data:', error);
}
toast.error(error?.message || t('accountOverview.items.downloadData.error') || 'Failed to download data');
}
}
}]);
} catch (error) {
if (__DEV__) {
console.error('Failed to initiate download:', error);
}
toast.error(error?.message || t('accountOverview.items.downloadData.error') || 'Failed to download data');
}
}, [oxyServices, user, t]);
const handleDeleteAccount = useCallback(() => {
if (!user) {
toast.error(t('accountOverview.items.deleteAccount.error') || 'User not available');
return;
}
setShowDeleteModal(true);
}, [user, t]);
const handleConfirmDelete = useCallback(async password => {
if (!oxyServices || !user) {
throw new Error(t('accountOverview.items.deleteAccount.error') || 'Service not available');
}
await oxyServices.deleteAccount(password);
toast.success(t('accountOverview.items.deleteAccount.success') || 'Account deleted successfully');
setShowDeleteModal(false);
await logout();
if (onClose) {
onClose();
}
}, [oxyServices, user, logout, onClose, t]);
if (!isAuthenticated) {
return /*#__PURE__*/_jsx(View, {
style: [styles.container, {
backgroundColor: themeStyles.backgroundColor
}],
children: /*#__PURE__*/_jsx(Text, {
style: [styles.message, {
color: themeStyles.textColor
}],
children: t('common.status.notSignedIn')
})
});
}
if (isLoading) {
return /*#__PURE__*/_jsx(View, {
style: [styles.container, {
backgroundColor: themeStyles.backgroundColor,
justifyContent: 'center'
}],
children: /*#__PURE__*/_jsx(ActivityIndicator, {
size: "large",
color: themeStyles.primaryColor
})
});
}
return /*#__PURE__*/_jsxs(View, {
style: [styles.container, {
backgroundColor: themeStyles.backgroundColor
}],
children: [/*#__PURE__*/_jsxs(ScrollView, {
style: styles.content,
contentContainerStyle: styles.scrollContent,
showsVerticalScrollIndicator: false,
children: [user && /*#__PURE__*/_jsx(View, {
style: styles.headerSection,
children: /*#__PURE__*/_jsxs(View, {
style: styles.avatarSectionWrapper,
children: [/*#__PURE__*/_jsxs(View, {
style: styles.avatarContainer,
children: [LottieView && lottieAnimation && /*#__PURE__*/_jsx(LottieView, {
ref: lottieRef,
source: lottieAnimation,
style: styles.lottieBackground,
loop: false,
autoPlay: false
}), /*#__PURE__*/_jsx(TouchableOpacity, {
style: styles.avatarWrapper,
onPress: handleAvatarPress,
activeOpacity: 0.8,
children: /*#__PURE__*/_jsx(Avatar, {
uri: avatarUrl,
name: displayName,
size: 100,
theme: normalizedTheme
})
})]
}), /*#__PURE__*/_jsxs(View, {
style: styles.nameWrapper,
children: [/*#__PURE__*/_jsx(Text, {
style: [styles.welcomeText, {
color: themeStyles.textColor
}],
children: displayName
}), /*#__PURE__*/_jsx(Text, {
style: [styles.welcomeSubtext, {
color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
}],
children: "Manage your Oxy account."
})]
})]
})
}), /*#__PURE__*/_jsx(Section, {
title: t('accountOverview.sections.profile'),
isFirst: true,
children: /*#__PURE__*/_jsx(GroupedSection, {
items: [{
id: 'profile-info',
icon: 'account',
iconColor: baseThemeStyles.colors.iconSecurity,
title: displayName,
subtitle: user ? user.email || user.username : t('common.status.loading') || 'Loading...',
onPress: () => navigate?.('AccountSettings', {
activeTab: 'profile'
})
}]
})
}), /*#__PURE__*/_jsx(Section, {
title: t('accountOverview.sections.accountSettings'),
children: /*#__PURE__*/_jsx(GroupedSection, {
items: [{
id: 'edit-profile',
icon: 'account-circle',
iconColor: baseThemeStyles.colors.iconPersonalInfo,
title: t('accountOverview.items.editProfile.title'),
subtitle: t('accountOverview.items.editProfile.subtitle'),
onPress: () => navigate?.('AccountSettings', {
activeTab: 'profile'
})
}, {
id: 'security-privacy',
icon: 'shield-check',
iconColor: baseThemeStyles.colors.iconSecurity,
title: t('accountOverview.items.security.title'),
subtitle: t('accountOverview.items.security.subtitle'),
onPress: () => navigate?.('AccountSettings', {
activeTab: 'password'
})
}, {
id: 'notifications',
icon: 'bell',
iconColor: baseThemeStyles.colors.iconStorage,
title: t('accountOverview.items.notifications.title'),
subtitle: t('accountOverview.items.notifications.subtitle'),
onPress: () => navigate?.('AccountSettings', {
activeTab: 'notifications'
})
}, {
id: 'premium-subscription',
icon: 'star',
iconColor: baseThemeStyles.colors.iconPayments,
title: t('accountOverview.items.premium.title'),
subtitle: user?.isPremium ? t('accountOverview.items.premium.manage') : t('accountOverview.items.premium.upgrade'),
onPress: () => navigate?.('PremiumSubscription')
}, ...(user?.isPremium ? [{
id: 'billing-management',
icon: 'card',
iconColor: baseThemeStyles.colors.iconPersonalInfo,
title: t('accountOverview.items.billing.title'),
subtitle: t('accountOverview.items.billing.subtitle'),
onPress: () => toast.info(t('accountOverview.items.billing.coming'))
}] : [])]
})
}), showMoreAccounts && /*#__PURE__*/_jsx(Section, {
title: `${t('accountOverview.sections.additionalAccounts') || 'Additional Accounts'}${additionalAccountsData.length > 0 ? ` (${additionalAccountsData.length})` : ''}`,
children: loadingAdditionalAccounts ? /*#__PURE__*/_jsx(GroupedSection, {
items: [{
id: 'loading-accounts',
icon: 'sync',
iconColor: baseThemeStyles.colors.iconSecurity,
title: t('accountOverview.loadingAdditional.title') || 'Loading accounts...',
subtitle: t('accountOverview.loadingAdditional.subtitle') || 'Please wait while we load your additional accounts',
customContent: /*#__PURE__*/_jsxs(View, {
style: styles.loadingContainer,
children: [/*#__PURE__*/_jsx(ActivityIndicator, {
size: "small",
color: baseThemeStyles.colors.iconSecurity
}), /*#__PURE__*/_jsx(Text, {
style: styles.loadingText,
children: t('accountOverview.loadingAdditional.title') || 'Loading accounts...'
})]
})
}]
}) : additionalAccountsData.length > 0 ? /*#__PURE__*/_jsx(GroupedSection, {
items: additionalAccountsData.map((account, index) => ({
id: `account-${account.id}`,
icon: 'account',
iconColor: baseThemeStyles.colors.iconData,
title: typeof account.name === 'object' ? account.name?.full || account.name?.first || account.username : account.name || account.username,
subtitle: account.email || account.username,
onPress: () => {
toast.info(t('accountOverview.items.accountSwitcher.switchPrompt', {
username: account.username
}) || `Switch to ${account.username}?`);
},
customContent: /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(View, {
style: styles.userIcon,
children: account.avatar ? /*#__PURE__*/_jsx(Image, {
source: {
uri: oxyServices.getFileDownloadUrl(account.avatar, 'thumb')
},
style: styles.accountAvatarImage
}) : /*#__PURE__*/_jsx(View, {
style: styles.accountAvatarFallback,
children: /*#__PURE__*/_jsx(Text, {
style: styles.accountAvatarText,
children: account.username?.charAt(0).toUpperCase() || '?'
})
})
}), /*#__PURE__*/_jsx(OxyIcon, {
name: "chevron-forward",
size: 16,
color: "#ccc"
})]
})
}))
}) : /*#__PURE__*/_jsx(GroupedSection, {
items: [{
id: 'no-accounts',
icon: 'account-outline',
iconColor: '#ccc',
title: t('accountOverview.additional.noAccounts.title') || 'No other accounts',
subtitle: t('accountOverview.additional.noAccounts.subtitle') || 'Add another account to switch between them'
}]
})
}), showMoreAccounts && /*#__PURE__*/_jsx(Section, {
title: t('accountOverview.sections.accountManagement') || 'Account Management',
children: /*#__PURE__*/_jsx(GroupedSection, {
items: [{
id: 'add-account',
icon: 'add',
iconColor: baseThemeStyles.colors.iconSecurity,
title: t('accountOverview.items.addAccount.title') || 'Add Another Account',
subtitle: t('accountOverview.items.addAccount.subtitle') || 'Sign in with a different account',
onPress: handleAddAccount
}, {
id: 'sign-out-all',
icon: 'logout',
iconColor: baseThemeStyles.colors.iconSharing,
title: t('accountOverview.items.signOutAll.title') || 'Sign out of all accounts',
subtitle: t('accountOverview.items.signOutAll.subtitle') || 'Remove all accounts from this device',
onPress: handleSignOutAll
}]
})
}), /*#__PURE__*/_jsx(Section, {
title: t('accountOverview.sections.quickActions'),
children: /*#__PURE__*/_jsx(GroupedSection, {
items: [{
id: 'account-switcher',
icon: 'account-group',
iconColor: baseThemeStyles.colors.iconData,
title: showMoreAccounts ? t('accountOverview.items.accountSwitcher.titleHide') : t('accountOverview.items.accountSwitcher.titleShow'),
subtitle: showMoreAccounts ? t('accountOverview.items.accountSwitcher.subtitleHide') : additionalAccountsData.length > 0 ? t('accountOverview.items.accountSwitcher.subtitleSwitchBetween', {
count: String(additionalAccountsData.length + 1)
}) : loadingAdditionalAccounts ? t('accountOverview.items.accountSwitcher.subtitleLoading') : t('accountOverview.items.accountSwitcher.subtitleManageMultiple'),
onPress: () => setShowMoreAccounts(!showMoreAccounts)
}, {
id: 'history-view',
icon: 'clock',
iconColor: baseThemeStyles.colors.iconSecurity,
title: t('accountOverview.items.history.title') || 'History',
subtitle: t('accountOverview.items.history.subtitle') || 'View and manage your search history',
onPress: () => navigate?.('HistoryView')
}, {
id: 'saves-collections',
icon: 'bookmark',
iconColor: baseThemeStyles.colors.iconStorage,
title: t('accountOverview.items.saves.title') || 'Saves & Collections',
subtitle: t('accountOverview.items.saves.subtitle') || 'View your saved items and collections',
onPress: () => navigate?.('SavesCollections')
}, {
id: 'download-data',
icon: 'download',
iconColor: baseThemeStyles.colors.iconPersonalInfo,
title: t('accountOverview.items.downloadData.title'),
subtitle: t('accountOverview.items.downloadData.subtitle'),
onPress: handleDownloadData
}, {
id: 'delete-account',
icon: 'delete',
iconColor: baseThemeStyles.colors.iconSharing,
title: t('accountOverview.items.deleteAccount.title'),
subtitle: t('accountOverview.items.deleteAccount.subtitle'),
onPress: handleDeleteAccount
}]
})
}), /*#__PURE__*/_jsx(Section, {
title: t('accountOverview.sections.support'),
children: /*#__PURE__*/_jsx(GroupedSection, {
items: [{
id: 'search-settings',
icon: 'magnify',
iconColor: baseThemeStyles.colors.iconSecurity,
title: t('accountOverview.items.searchSettings.title') || 'Search Settings',
subtitle: t('accountOverview.items.searchSettings.subtitle') || 'SafeSearch and personalization',
onPress: () => navigate?.('SearchSettings')
}, {
id: 'language-settings',
icon: 'translate',
iconColor: baseThemeStyles.colors.iconPersonalInfo,
title: t('accountOverview.items.language.title') || 'Language',
subtitle: t('accountOverview.items.language.subtitle') || 'Choose your preferred language',
onPress: () => navigate?.('LanguageSelector')
}, {
id: 'account-preferences',
icon: 'cog',
iconColor: '#8E8E93',
title: t('accountOverview.items.preferences.title'),
subtitle: t('accountOverview.items.preferences.subtitle'),
onPress: () => toast.info(t('accountOverview.items.preferences.coming'))
}, {
id: 'help-support',
icon: 'help-circle',
iconColor: baseThemeStyles.colors.iconSecurity,
title: t('accountOverview.items.help.title'),
subtitle: t('accountOverview.items.help.subtitle'),
onPress: () => navigate?.('HelpSupport')
}, {
id: 'privacy-policy',
icon: 'shield-check',
iconColor: baseThemeStyles.colors.iconPersonalInfo,
title: t('accountOverview.items.privacyPolicy.title') || 'Privacy Policy',
subtitle: t('accountOverview.items.privacyPolicy.subtitle') || 'How we handle your data',
onPress: () => navigate?.('LegalDocuments', {
initialStep: 1
})
}, {
id: 'terms-of-service',
icon: 'file-document',
iconColor: baseThemeStyles.colors.iconSecurity,
title: t('accountOverview.items.termsOfService.title') || 'Terms of Service',
subtitle: t('accountOverview.items.termsOfService.subtitle') || 'Terms and conditions of use',
onPress: () => navigate?.('LegalDocuments', {
initialStep: 2
})
}, {
id: 'connected-apps',
icon: 'link',
iconColor: baseThemeStyles.colors.iconPersonalInfo,
title: t('accountOverview.items.connectedApps.title'),
subtitle: t('accountOverview.items.connectedApps.subtitle'),
onPress: () => toast.info(t('accountOverview.items.connectedApps.coming'))
}, {
id: 'about',
icon: 'information',
iconColor: '#8E8E93',
title: t('accountOverview.items.about.title'),
subtitle: t('accountOverview.items.about.subtitle'),
onPress: () => navigate?.('AppInfo')
}]
})
}), /*#__PURE__*/_jsx(Section, {
title: t('accountOverview.sections.actions'),
children: /*#__PURE__*/_jsx(GroupedItem, {
icon: "logout",
iconColor: "#FF3B30",
title: t('accountOverview.items.signOut.title'),
subtitle: t('accountOverview.items.signOut.subtitle'),
onPress: confirmLogout,
isFirst: true,
isLast: true,
showChevron: false
})
})]
}), user && /*#__PURE__*/_jsx(DeleteAccountModal, {
visible: showDeleteModal,
username: user.username || '',
onClose: () => setShowDeleteModal(false),
onDelete: handleConfirmDelete,
colors: {
background: themeStyles.backgroundColor,
text: themeStyles.textColor,
secondaryText: themeStyles.isDarkTheme ? '#888888' : '#666666',
border: themeStyles.borderColor,
danger: '#FF3B30',
inputBackground: themeStyles.isDarkTheme ? '#333333' : '#F5F5F5'
},
t: t
})]
});
};
const styles = StyleSheet.create({
container: {
flex: 1
},
content: {
flex: 1
},
scrollContent: createScreenContentStyle(HEADER_PADDING_TOP_OVERVIEW),
headerSection: {
alignItems: 'center',
marginBottom: SECTION_GAP,
paddingTop: HEADER_PADDING_TOP_OVERVIEW
},
avatarSectionWrapper: {
alignItems: 'center',
justifyContent: 'center',
width: '100%'
},
avatarContainer: {
position: 'relative',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
maxWidth: 600,
minHeight: 100,
overflow: 'hidden',
alignSelf: 'center',
aspectRatio: 6
},
lottieBackground: {
position: 'absolute',
width: '100%',
maxWidth: 600,
minHeight: 100,
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 0,
aspectRatio: 6
},
avatarWrapper: {
zIndex: 1,
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
width: 100,
height: 100,
left: '50%',
marginLeft: -50,
top: 0
},
nameWrapper: {
marginTop: 12,
alignItems: 'center',
justifyContent: 'center'
},
welcomeText: {
fontSize: 28,
fontWeight: '600',
marginBottom: 8,
fontFamily: fontFamilies.interBold,
maxWidth: '90%'
},
welcomeSubtext: {
fontSize: 16,
fontWeight: '400',
opacity: 0.6
},
userIcon: {
marginRight: 12
},
manageButton: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 16
// backgroundColor should be applied inline using colors.iconSecurity
},
manageButtonText: {
color: '#fff',
fontSize: 14,
fontWeight: '500'
},
accountAvatarImage: {
width: 40,
height: 40,
borderRadius: 20
},
accountAvatarFallback: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#d169e5',
alignItems: 'center',
justifyContent: 'center'
},
accountAvatarText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold'
},
message: {
fontSize: 16,
textAlign: 'center',
marginTop: 24,
color: '#333'
},
loadingContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 20,
gap: 12
},
loadingText: {
fontSize: 16,
color: '#666'
}
});
export default /*#__PURE__*/React.memo(AccountOverviewScreen);
//# sourceMappingURL=AccountOverviewScreen.js.map