import { Alert, AlertTitle, alpha, Box, Button, CircularProgress, Collapse, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, InputAdornment, Slide, Stack, TextField, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material' import React, { SetStateAction, useRef } from 'react'; import Iconify from '../Iconify'; import UltimaLogo from '../../assets/icons/UltimaLogoNew.png'; import { AnimatePresence, motion } from 'framer-motion'; import ProvidersButton from './ProvidersButton'; import { signUp } from '@/functions/auth/signUp'; import shakeScreen from '@/functions/system/shakeScreen'; import notificationIcon from '../../assets/icons/UltimaLogoNew.png'; import { ipcRenderer } from 'electron'; import { useNavigate } from 'react-router'; import { useSession } from '@/contexts/AuthContext'; const SignUp = ({ page, handleChangePage, setCanChangePage }: { page: 'signin' | 'signup' | 'providers'; handleChangePage: (page: 'signin' | 'signup' | 'providers') => void; setCanChangePage: React.Dispatch>; }) => { const { user, status, refreshSession } = useSession(); const navigate = useNavigate(); const theme = useTheme(); const [hidePassword, setHidePassword] = React.useState(true); const [username, setUsername] = React.useState(''); const [displayName, setDisplayName] = React.useState(''); const [email, setEmail] = React.useState(''); const [password, setPassword] = React.useState(''); const [usernameError, setUsernameError] = React.useState(false); const [displayNameError, setDisplayNameError] = React.useState(false); const [emailError, setEmailError] = React.useState(false); const [passwordError, setPasswordError] = React.useState(false); const [callState, setCallState] = React.useState(null); const [ppDialog, setPpDialog] = React.useState(false); const [generatedPP, setGeneratedPP] = React.useState(null); const [registeredUserID, setRegisteredUserID] = React.useState(null); const [isPassphraseSaved, setIsPassphraseSaved] = React.useState(false); const [areKeysSaved, setAreKeysSaved] = React.useState(false); const usernameRef = useRef(null); const displayNameRef = useRef(null); const emailRef = useRef(null); const passwordRef = useRef(null); const handleSignUp = async () => { if (!username || !displayName || !email || !password) { if (!username) setUsernameError(true); if (!displayName) setDisplayNameError(true); if (!email) setEmailError(true); if (!password) setPasswordError(true); shakeScreen(); setTimeout(() => { setUsernameError(false); setDisplayNameError(false); setEmailError(false); setPasswordError(false); }, 1500); return; } setCallState('loading'); setCanChangePage(false); try { const { data: signUpRes }: { data: { d: { userId: string, accessToken: string, refreshToken: string, epk: string, passphrase: string, } } } = await signUp({ username, settings: { displayName }, email, password, }); // AFTER SUCCESS - SAVE if(signUpRes.d.passphrase && signUpRes.d.userId && signUpRes.d.epk) { await ipcRenderer.invoke('save-keys', { userId: signUpRes.d.userId, epk: signUpRes.d.epk, passphrase: signUpRes.d.passphrase, }).then((res) => { console.log('Keys saved:', res); setGeneratedPP(signUpRes.d.passphrase); setRegisteredUserID(signUpRes.d.userId); setPpDialog(true); setAreKeysSaved(true); }).catch((error: any) => { console.error('Error saving keys:', error); setCallState('error'); setAreKeysSaved(false); throw 'Could not save keys.'; }); } else { await ipcRenderer.invoke('clear-keys'); throw 'Passphrase or ID not found.'; } } catch (error) { console.error(error); setCallState('error'); await ipcRenderer.invoke('clear-keys'); if (error?.response?.data) { new Notification('Error signing up.', { body: error?.response?.data?.data || error?.response?.data?.message || error, icon: notificationIcon }); } setTimeout(() => { setCallState(null); }, 1500) } finally { setTimeout(() => { setUsernameError(false); setDisplayNameError(false); setEmailError(false); setPasswordError(false); }, 1500); } }; const handleDialogContinue = async () => { await refreshSession(); console.log("refreshing session...") console.log("user", user) if (user && status === 'authenticated') { setTimeout(() => { navigate('/'); }, 500) } } const handleSaveToTxt = async () => { if (generatedPP && registeredUserID) { try { const result = await ipcRenderer.invoke('save-txt-file', { name: `ultima-${registeredUserID}-passphrase`, content: generatedPP, title: 'Save your passphrase to a secure location!', }); if (result.success) { new Notification('Passphrase saved!', { body: 'Your passphrase has been saved to your computer.', icon: notificationIcon }); setIsPassphraseSaved(true); } else { console.log('File save was canceled'); } } catch (error) { console.error('Error saving passphrase:', error); new Notification('Error saving passphrase!', { body: 'An error occurred while saving your passphrase.', icon: notificationIcon }); } } else { new Notification('Passphrase error.', { body: 'No passphrase was generated or ID not found.', icon: notificationIcon }); } }; const handleKeyPress = (event: React.KeyboardEvent, nextRef?: React.RefObject) => { if (event.key === 'Enter') { event.preventDefault(); if (nextRef && nextRef.current) { nextRef.current.focus(); } else { handleSignUp(); } } }; const handlePageChange = (page: 'signin' | 'signup' | 'providers') => { if (callState === 'loading' || ppDialog || generatedPP) return; handleChangePage(page); setCallState(null); setRegisteredUserID(null); setGeneratedPP(null); } const isSmall = useMediaQuery('(max-height: 700px)'); return ( {/* Welcome to the team! */} We value your privacy. Security and privacy is really important these days,
so we have generated a passphrase for you to access your account.
theme.shape.borderRadius, border: (theme) => `1px dashed ${theme.palette.divider}` }}> {generatedPP && generatedPP.split('').map((char, index) => ( theme.palette.divider, borderRadius: 1, textAlign: 'center', userSelect: 'text', bgcolor: 'background.default', color: 'text.primary', fontWeight: 'bold', fontSize: '1.2rem', }} > {char} ))} Don't take this lightly. Please save it in a secure location in your computer.
{!isSmall && ( Ultima )} Start your journey Create new account `0 0 12px ${theme.palette.primary.light}` }}>. Already a member? handlePageChange('signin')} sx={{ color: 'primary.light', cursor: 'pointer', fontSize: 15, fontWeight: 550 }}>Sign In
setUsername(e.target.value)} error={usernameError || callState === 'error'} sx={{ '& .MuiFilledInput-root': { borderColor: usernameError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'primary.main', color: usernameError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'inherit', } }} slotProps={{ input: { startAdornment: @, endAdornment: , inputRef: usernameRef, onKeyPress: (e) => handleKeyPress(e, displayNameRef) } }} /> setDisplayName(e.target.value)} error={displayNameError || callState === 'error'} sx={{ '& .MuiFilledInput-root': { borderColor: displayNameError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'primary.main', color: displayNameError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'inherit', } }} slotProps={{ input: { endAdornment: , inputRef: displayNameRef, onKeyPress: (e) => handleKeyPress(e, emailRef) } }} /> setEmail(e.target.value)} error={emailError || callState === 'error'} sx={{ '& .MuiFilledInput-root': { borderColor: emailError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'primary.main', color: emailError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'inherit', } }} slotProps={{ input: { endAdornment: , inputRef: emailRef, onKeyPress: (e) => handleKeyPress(e, passwordRef) } }} /> setPassword(e.target.value)} error={passwordError || callState === 'error'} sx={{ '& .MuiFilledInput-root': { borderColor: passwordError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'primary.main', color: passwordError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'inherit', } }} slotProps={{ input: { endAdornment: ( setHidePassword((prev) => !prev)} sx={{ p: 0, color: 'inherit', pt: 0.5 }}> ), inputRef: passwordRef, onKeyPress: (e) => handleKeyPress(e) } }} />
) } export default SignUp;