UNPKG

@oxyhq/services

Version:

Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀

956 lines (945 loc) • 28.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _OxyContext = require("../context/OxyContext"); var _styles = require("../styles"); var _OxyLogo = _interopRequireDefault(require("../components/OxyLogo")); var _Avatar = _interopRequireDefault(require("../components/Avatar")); var _bottomSheet = require("../components/bottomSheet"); var _vectorIcons = require("@expo/vector-icons"); var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg")); var _sonner = require("../../lib/sonner"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const SignInScreen = ({ navigate, goBack, theme }) => { // Form data states const [username, setUsername] = (0, _react.useState)(''); const [password, setPassword] = (0, _react.useState)(''); const [errorMessage, setErrorMessage] = (0, _react.useState)(''); const [userProfile, setUserProfile] = (0, _react.useState)(null); // Multi-step form states const [currentStep, setCurrentStep] = (0, _react.useState)(0); const [isInputFocused, setIsInputFocused] = (0, _react.useState)(false); const fadeAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current; const slideAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current; const scaleAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current; const inputScaleAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current; const logoAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current; const progressAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0.5)).current; const { login, isLoading, user, isAuthenticated, sessions } = (0, _OxyContext.useOxy)(); const colors = (0, _styles.useThemeColors)(theme); const commonStyles = (0, _styles.createCommonStyles)(theme); // Check if this should be treated as "Add Account" mode const isAddAccountMode = user && isAuthenticated && sessions && sessions.length > 0; // Initialize logo animation (0, _react.useEffect)(() => { _reactNative.Animated.spring(logoAnim, { toValue: 1, tension: 50, friction: 8, useNativeDriver: true }).start(); }, []); // Input focus animations const handleInputFocus = () => { setIsInputFocused(true); _reactNative.Animated.spring(inputScaleAnim, { toValue: 1.02, useNativeDriver: true }).start(); }; const handleInputBlur = () => { setIsInputFocused(false); _reactNative.Animated.spring(inputScaleAnim, { toValue: 1, useNativeDriver: true }).start(); }; // Animation functions const animateTransition = nextStep => { // Scale down current content _reactNative.Animated.timing(scaleAnim, { toValue: 0.95, duration: 150, useNativeDriver: true }).start(); // Fade out _reactNative.Animated.timing(fadeAnim, { toValue: 0, duration: 200, useNativeDriver: true }).start(() => { setCurrentStep(nextStep); // Reset animations slideAnim.setValue(-50); scaleAnim.setValue(0.95); // Animate in new content _reactNative.Animated.parallel([_reactNative.Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }), _reactNative.Animated.spring(slideAnim, { toValue: 0, tension: 80, friction: 8, useNativeDriver: true }), _reactNative.Animated.spring(scaleAnim, { toValue: 1, tension: 80, friction: 8, useNativeDriver: true })]).start(); }); }; const nextStep = () => { if (currentStep < 1) { // Animate progress bar _reactNative.Animated.timing(progressAnim, { toValue: 1.0, duration: 300, useNativeDriver: false }).start(); animateTransition(currentStep + 1); } }; const prevStep = () => { if (currentStep > 0) { // Animate progress bar _reactNative.Animated.timing(progressAnim, { toValue: 0.5, duration: 300, useNativeDriver: false }).start(); animateTransition(currentStep - 1); } }; // Fetch user profile when username is entered (0, _react.useEffect)(() => { const fetchUserProfile = async () => { if (username.length >= 3 && currentStep === 1) { try { // For now, we'll create a mock profile based on username // In a real app, you'd fetch this from your API setUserProfile({ displayName: username, name: username, avatar: null // Could be fetched from API }); } catch (error) { // If user not found, we'll show a generic avatar setUserProfile(null); } } }; fetchUserProfile(); }, [username, currentStep]); const handleUsernameNext = () => { if (!username) { _sonner.toast.error('Please enter your username'); return; } setErrorMessage(''); nextStep(); }; const handleLogin = async () => { if (!username || !password) { _sonner.toast.error('Please enter both username and password'); return; } try { setErrorMessage(''); await login(username, password); // The authentication state change will be handled through context } catch (error) { _sonner.toast.error(error.message || 'Login failed'); } }; // Step components const renderUsernameStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, { style: [styles.stepContainer, { opacity: fadeAnim, transform: [{ translateX: slideAnim }, { scale: scaleAnim }] }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.modernImageContainer, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.default, { width: 280, height: 160, viewBox: "0 0 280 160", children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.Defs, { children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.LinearGradient, { id: "primaryGradient", x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, { offset: "0%", stopColor: colors.primary, stopOpacity: "0.8" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, { offset: "100%", stopColor: colors.primary, stopOpacity: "0.2" })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.LinearGradient, { id: "secondaryGradient", x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, { offset: "0%", stopColor: colors.primary, stopOpacity: "0.1" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, { offset: "100%", stopColor: colors.primary, stopOpacity: "0.3" })] })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "80", cy: "80", r: "45", fill: "url(#primaryGradient)" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "200", cy: "80", r: "35", fill: "url(#secondaryGradient)" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, { d: "M40 120 Q80 40 140 80 Q200 120 240 60", stroke: colors.primary, strokeWidth: "4", fill: "none", strokeLinecap: "round" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "60", cy: "50", r: "8", fill: colors.primary, opacity: "0.6" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "220", cy: "120", r: "6", fill: colors.primary, opacity: "0.4" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "250", cy: "40", r: "4", fill: colors.primary, opacity: "0.8" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "140", cy: "80", r: "25", fill: colors.background, opacity: "0.9" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "135", cy: "75", r: "3", fill: colors.primary }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, { cx: "145", cy: "75", r: "3", fill: colors.primary }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, { d: "M132 85 Q140 92 148 85", stroke: colors.primary, strokeWidth: "2", fill: "none", strokeLinecap: "round" })] }) }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.modernHeader, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.modernTitle, { color: colors.text }], children: isAddAccountMode ? 'Add Account' : 'Welcome Back' }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.modernSubtitle, { color: colors.secondaryText }], children: isAddAccountMode ? 'Sign in with another account' : 'Sign in to continue your journey' })] }), isAddAccountMode && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.modernInfoCard, { backgroundColor: colors.inputBackground }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "information-circle", size: 20, color: colors.primary }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: [styles.modernInfoText, { color: colors.text }], children: ["Currently signed in as ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { fontWeight: 'bold' }, children: user?.username })] })] }), errorMessage ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, { style: [styles.modernErrorCard, { backgroundColor: '#FF6B6B20' }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "alert-circle", size: 20, color: "#FF6B6B" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.errorText, { color: '#FF6B6B' }], children: errorMessage })] }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, { style: [styles.modernInputContainer, { transform: [{ scale: inputScaleAnim }] }], children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.inputWrapper, { borderColor: isInputFocused ? colors.primary : colors.border }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "person-outline", size: 20, color: isInputFocused ? colors.primary : colors.secondaryText, style: styles.inputIcon }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, { style: [styles.modernInput, { color: colors.text }], placeholder: "Enter your username", placeholderTextColor: colors.placeholder, value: username, onChangeText: setUsername, onFocus: handleInputFocus, onBlur: handleInputBlur, autoCapitalize: "none", testID: "username-input" })] }) }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, { style: [styles.modernButton, { backgroundColor: colors.primary, opacity: !username ? 0.5 : 1, shadowColor: colors.primary }], onPress: handleUsernameNext, disabled: !username, testID: "username-next-button", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.modernButtonText, children: "Continue" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "arrow-forward", size: 20, color: "#FFFFFF", style: styles.buttonIcon })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.footerTextContainer, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: [styles.footerText, { color: colors.secondaryText }], children: ["Don't have an account?", ' '] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { onPress: () => navigate('SignUp'), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.modernLinkText, { color: colors.primary }], children: "Sign Up" }) })] })] }); const renderPasswordStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, { style: [styles.stepContainer, { opacity: fadeAnim, transform: [{ translateX: slideAnim }, { scale: scaleAnim }] }], children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.modernUserProfileContainer, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, { style: [styles.avatarContainer, { transform: [{ scale: logoAnim }] }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar.default, { uri: userProfile?.avatar, name: userProfile?.displayName || userProfile?.name || username, size: 100, theme: theme, style: styles.modernUserAvatar }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.statusIndicator, { backgroundColor: colors.primary }] })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.modernUserDisplayName, { color: colors.text }], children: userProfile?.displayName || userProfile?.name || username }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: [styles.modernUsernameSubtext, { color: colors.secondaryText }], children: ["@", username] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.welcomeBackBadge, { backgroundColor: colors.primary + '15' }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "checkmark-circle", size: 16, color: colors.primary }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.welcomeBackText, { color: colors.primary }], children: "Welcome back!" })] })] }), errorMessage ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, { style: [styles.modernErrorCard, { backgroundColor: '#FF6B6B20' }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "alert-circle", size: 20, color: "#FF6B6B" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.errorText, { color: '#FF6B6B' }], children: errorMessage })] }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, { style: [styles.modernInputContainer, { transform: [{ scale: inputScaleAnim }] }], children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.inputWrapper, { borderColor: isInputFocused ? colors.primary : colors.border }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "lock-closed-outline", size: 20, color: isInputFocused ? colors.primary : colors.secondaryText, style: styles.inputIcon }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, { style: [styles.modernInput, { color: colors.text }], placeholder: "Enter your password", placeholderTextColor: colors.placeholder, value: password, onChangeText: setPassword, onFocus: handleInputFocus, onBlur: handleInputBlur, secureTextEntry: true, testID: "password-input" })] }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: [styles.modernButton, { backgroundColor: colors.primary, opacity: isLoading ? 0.8 : 1, shadowColor: colors.primary }], onPress: handleLogin, disabled: isLoading, testID: "login-button", children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.modernButtonText, children: isAddAccountMode ? 'Add Account' : 'Sign In' }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "arrow-forward", size: 20, color: "#FFFFFF", style: styles.buttonIcon })] }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.modernNavigationButtons, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, { style: [styles.modernBackButton, { borderColor: colors.border }], onPress: prevStep, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "chevron-back", size: 20, color: colors.text }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.modernBackButtonText, { color: colors.text }], children: "Back" })] }) }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.securityNotice, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "shield-checkmark", size: 16, color: colors.secondaryText }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.securityText, { color: colors.secondaryText }], children: "Your connection is secure and encrypted" })] })] }); const renderCurrentStep = () => { switch (currentStep) { case 0: return renderUsernameStep(); case 1: return renderPasswordStep(); default: return renderUsernameStep(); } }; return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_bottomSheet.BottomSheetScrollView, { contentContainerStyle: commonStyles.scrollContainer, keyboardShouldPersistTaps: "handled", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, { style: [styles.logoContainer, { transform: [{ scale: logoAnim }] }], children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_OxyLogo.default, { style: { marginBottom: 24 }, width: 50, height: 50 }) }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.modernProgressContainer, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.progressTrack, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, { style: [styles.progressFill, { backgroundColor: colors.primary, width: progressAnim.interpolate({ inputRange: [0, 1], outputRange: ['50%', '100%'] }) }] }) }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: [styles.progressText, { color: colors.secondaryText }], children: ["Step ", currentStep + 1, " of 2"] })] }), renderCurrentStep()] }); }; const styles = _reactNative.StyleSheet.create({ // Legacy styles (keeping for compatibility) title: { fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold', fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined, fontSize: 54, marginBottom: 24 }, formContainer: { width: '100%' }, inputContainer: { marginBottom: 16 }, label: { fontSize: 14, fontWeight: '500', marginBottom: 8 }, footerTextContainer: { flexDirection: 'row', justifyContent: 'center', marginTop: 24 }, footerText: { fontSize: 14, lineHeight: 20 }, linkText: { fontSize: 14, lineHeight: 20, fontWeight: '600' }, userInfoContainer: { padding: 20, marginVertical: 20, borderRadius: 35, alignItems: 'center' }, userInfoText: { fontSize: 16, lineHeight: 24, textAlign: 'center' }, actionButtonsContainer: { marginTop: 20 }, infoContainer: { padding: 16, marginVertical: 16, borderRadius: 8, alignItems: 'center' }, infoText: { fontSize: 14, lineHeight: 20, textAlign: 'center' }, // Modern UI Styles logoContainer: { alignItems: 'center', marginBottom: 16 }, modernProgressContainer: { alignItems: 'center', marginBottom: 40, paddingHorizontal: 20 }, progressTrack: { width: '100%', height: 4, backgroundColor: '#E5E5E5', borderRadius: 2, marginBottom: 8, overflow: 'hidden' }, progressFill: { height: '100%', borderRadius: 2 }, progressText: { fontSize: 12, fontWeight: '500' }, stepContainer: { width: '100%', minHeight: 450, paddingHorizontal: 20 }, // Modern Image Container modernImageContainer: { alignItems: 'center', marginBottom: 40, paddingVertical: 20 }, modernHeader: { alignItems: 'center', marginBottom: 24 }, modernTitle: { fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold', fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined, fontSize: 54, textAlign: 'center', marginBottom: 8, letterSpacing: -0.5 }, modernSubtitle: { fontSize: 16, lineHeight: 22, textAlign: 'center', opacity: 0.8 }, // Modern Cards modernInfoCard: { flexDirection: 'row', alignItems: 'center', padding: 16, marginVertical: 16, borderRadius: 12, gap: 12 }, modernInfoText: { fontSize: 14, lineHeight: 20, flex: 1 }, modernErrorCard: { flexDirection: 'row', alignItems: 'center', padding: 16, marginVertical: 16, borderRadius: 12, gap: 12 }, errorText: { fontSize: 14, lineHeight: 20, flex: 1 }, // Modern Input Styles modernInputContainer: { marginBottom: 24 }, inputWrapper: { flexDirection: 'row', alignItems: 'center', borderWidth: 2, borderRadius: 16, paddingHorizontal: 16, paddingVertical: 4, backgroundColor: 'rgba(0,0,0,0.02)' }, inputIcon: { marginRight: 12 }, modernInput: { flex: 1, fontSize: 16, paddingVertical: 16, fontWeight: '500' }, // Modern Button Styles modernButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 18, paddingHorizontal: 32, borderRadius: 16, marginVertical: 8, shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 8, elevation: 6, gap: 8 }, modernButtonText: { color: '#FFFFFF', fontSize: 16, fontWeight: '600', letterSpacing: 0.5 }, buttonIcon: { marginLeft: 4 }, modernLinkText: { fontSize: 14, lineHeight: 20, fontWeight: '600', textDecorationLine: 'underline' }, // Modern User Profile Styles modernUserProfileContainer: { alignItems: 'center', marginBottom: 32, paddingVertical: 24 }, avatarContainer: { position: 'relative', marginBottom: 20 }, modernUserAvatar: { borderWidth: 4, borderColor: 'rgba(209, 105, 229, 0.2)' }, statusIndicator: { position: 'absolute', bottom: 4, right: 4, width: 20, height: 20, borderRadius: 10, borderWidth: 3, borderColor: '#FFFFFF' }, modernUserDisplayName: { fontSize: 26, fontWeight: '700', marginBottom: 4, textAlign: 'center', letterSpacing: -0.5 }, modernUsernameSubtext: { fontSize: 16, textAlign: 'center', marginBottom: 16, opacity: 0.7 }, welcomeBackBadge: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 20, gap: 6 }, welcomeBackText: { fontSize: 12, fontWeight: '600', textTransform: 'uppercase', letterSpacing: 0.5 }, // Modern Navigation modernNavigationButtons: { flexDirection: 'row', justifyContent: 'center', marginTop: 24, marginBottom: 16 }, modernBackButton: { flexDirection: 'row', alignItems: 'center', paddingVertical: 12, paddingHorizontal: 20, borderRadius: 12, borderWidth: 1, gap: 8 }, modernBackButtonText: { fontSize: 16, fontWeight: '500' }, // Security Notice securityNotice: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginTop: 20, gap: 6 }, securityText: { fontSize: 12, fontWeight: '500' }, // Legacy compatibility styles progressContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginBottom: 32, paddingHorizontal: 40 }, progressDot: { width: 12, height: 12, borderRadius: 6, marginHorizontal: 4 }, progressLine: { flex: 1, height: 2, marginHorizontal: 8 }, welcomeImageContainer: { alignItems: 'center', marginBottom: 32 }, header: { alignItems: 'center', marginBottom: 16 }, welcomeTitle: { fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold', fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined, fontSize: 32, textAlign: 'center', marginBottom: 8 }, welcomeText: { fontSize: 16, lineHeight: 24, textAlign: 'center', marginBottom: 32, paddingHorizontal: 20 }, userProfileContainer: { alignItems: 'center', marginBottom: 32, paddingVertical: 20 }, userAvatar: { marginBottom: 16 }, userDisplayName: { fontSize: 24, fontWeight: 'bold', marginBottom: 4, textAlign: 'center' }, usernameSubtext: { fontSize: 16, textAlign: 'center' }, navigationButtons: { flexDirection: 'row', justifyContent: 'center', marginTop: 24 }, backButton: { flexDirection: 'row', alignItems: 'center', paddingVertical: 12, paddingHorizontal: 20, borderRadius: 12, borderWidth: 1 }, backButtonText: { fontSize: 16, fontWeight: '500', marginLeft: 8 } }); var _default = exports.default = SignInScreen; //# sourceMappingURL=SignInScreen.js.map