@oxyhq/services
Version:
Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀
229 lines (212 loc) • 7.34 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = require("react");
var _OxyContext = require("../context/OxyContext");
var _styles = require("../styles");
var _sonner = require("../../lib/sonner");
var _StepBasedScreen = _interopRequireDefault(require("../components/StepBasedScreen"));
var _SignUpWelcomeStep = _interopRequireDefault(require("./steps/SignUpWelcomeStep"));
var _SignUpIdentityStep = _interopRequireDefault(require("./steps/SignUpIdentityStep"));
var _SignUpSecurityStep = _interopRequireDefault(require("./steps/SignUpSecurityStep"));
var _SignUpSummaryStep = _interopRequireDefault(require("./steps/SignUpSummaryStep"));
var _cache = require("../../utils/cache");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// Types for better type safety
// Constants
const USERNAME_MIN_LENGTH = 3;
const PASSWORD_MIN_LENGTH = 8;
// Email validation regex
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// Main component
const SignUpScreen = ({
navigate,
goBack,
onAuthenticated,
theme
}) => {
const {
signUp,
oxyServices
} = (0, _OxyContext.useOxy)();
const colors = (0, _styles.useThemeColors)(theme);
// Form data state
const [username, setUsername] = (0, _react.useState)('');
const [email, setEmail] = (0, _react.useState)('');
const [password, setPassword] = (0, _react.useState)('');
const [confirmPassword, setConfirmPassword] = (0, _react.useState)('');
const [showPassword, setShowPassword] = (0, _react.useState)(false);
const [showConfirmPassword, setShowConfirmPassword] = (0, _react.useState)(false);
const [isLoading, setIsLoading] = (0, _react.useState)(false);
// Validation state
const [validationState, setValidationState] = (0, _react.useState)({
status: 'idle',
message: ''
});
// Error message state
const [errorMessage, setErrorMessage] = (0, _react.useState)('');
// Username validation with caching - uses centralized cache
const usernameCache = (0, _react.useRef)(new _cache.TTLCache(5 * 60 * 1000)); // 5 minutes cache
// Register cache for cleanup on mount
(0, _react.useEffect)(() => {
(0, _cache.registerCacheForCleanup)(usernameCache.current);
return () => {
usernameCache.current.clear();
};
}, []);
const validateUsername = (0, _react.useCallback)(async usernameToValidate => {
if (!usernameToValidate || usernameToValidate.length < USERNAME_MIN_LENGTH) {
setValidationState({
status: 'invalid',
message: 'Username must be at least 3 characters'
});
return false;
}
// Check cache first
const cached = usernameCache.current.get(usernameToValidate);
if (cached !== null) {
const isValid = cached;
setValidationState({
status: isValid ? 'valid' : 'invalid',
message: isValid ? '' : 'Username is already taken'
});
return isValid;
}
setValidationState({
status: 'validating',
message: ''
});
try {
const result = await oxyServices.checkUsernameAvailability(usernameToValidate);
const isValid = result.available;
// Cache the result
usernameCache.current.set(usernameToValidate, isValid);
setValidationState({
status: isValid ? 'valid' : 'invalid',
message: isValid ? '' : result.message || 'Username is already taken'
});
return isValid;
} catch (error) {
console.error('Username validation error:', error);
setValidationState({
status: 'invalid',
message: 'Unable to validate username. Please try again.'
});
return false;
}
}, [oxyServices]);
// Email validation
const validateEmail = (0, _react.useCallback)(emailToValidate => {
return EMAIL_REGEX.test(emailToValidate);
}, []);
// Password validation
const validatePassword = (0, _react.useCallback)(passwordToValidate => {
return passwordToValidate.length >= PASSWORD_MIN_LENGTH;
}, []);
// Handle form completion
const handleComplete = (0, _react.useCallback)(async stepData => {
if (!username || !email || !password) {
_sonner.toast.error('Please fill in all required fields');
return;
}
if (!validateEmail(email)) {
_sonner.toast.error('Please enter a valid email address');
return;
}
if (!validatePassword(password)) {
_sonner.toast.error('Password must be at least 8 characters long');
return;
}
if (password !== confirmPassword) {
_sonner.toast.error('Passwords do not match');
return;
}
try {
setIsLoading(true);
const user = await signUp(username, email, password);
_sonner.toast.success('Account created successfully! Welcome to Oxy!');
// Navigate to welcome screen or handle authentication
navigate('WelcomeNewUser', {
newUser: user
});
} catch (error) {
_sonner.toast.error(error.message || 'Sign up failed');
} finally {
setIsLoading(false);
}
}, [username, email, password, confirmPassword, validateEmail, validatePassword, signUp, navigate]);
// Step configurations
const steps = (0, _react.useMemo)(() => [{
id: 'welcome',
component: _SignUpWelcomeStep.default,
canProceed: () => true
}, {
id: 'identity',
component: _SignUpIdentityStep.default,
canProceed: () => !!(username.trim() && email.trim() && validateEmail(email) && validationState.status === 'valid'),
onEnter: () => {
// Auto-validate username when entering this step
if (username && validationState.status === 'idle') {
validateUsername(username);
}
}
}, {
id: 'security',
component: _SignUpSecurityStep.default,
canProceed: () => !!(password && validatePassword(password) && password === confirmPassword)
}, {
id: 'summary',
component: _SignUpSummaryStep.default,
canProceed: () => true
}], [username, email, password, confirmPassword, validationState.status, validateEmail, validatePassword, validateUsername]);
// Step data for the reusable component
const stepData = (0, _react.useMemo)(() => [
// Welcome step - no data needed
{},
// Identity step
{
username,
email,
setUsername,
setEmail,
validationState,
setValidationState,
setErrorMessage,
validateEmail,
validateUsername
},
// Security step
{
password,
confirmPassword,
setPassword,
setConfirmPassword,
showPassword,
showConfirmPassword,
setShowPassword,
setShowConfirmPassword,
setErrorMessage,
validatePassword
},
// Summary step
{
isLoading
}], [username, email, password, confirmPassword, showPassword, showConfirmPassword, validationState, errorMessage, validateEmail, validatePassword, isLoading]);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StepBasedScreen.default, {
steps: steps,
stepData: stepData,
onComplete: handleComplete,
navigate: navigate,
goBack: goBack,
onAuthenticated: onAuthenticated,
theme: theme,
showProgressIndicator: true,
enableAnimations: true,
oxyServices: oxyServices
});
};
var _default = exports.default = SignUpScreen;
//# sourceMappingURL=SignUpScreen.js.map