@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
JavaScript
"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