adding create account screen

This commit is contained in:
Roland Osborne 2022-09-08 15:09:31 -07:00
parent 180fcfe0f8
commit 7b66b30d24
5 changed files with 301 additions and 8 deletions

View File

@ -1,4 +1,103 @@
export function Create() {
return <></>
}
import { ActivityIndicator, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native';
import { styles } from './Create.styled';
import Ionicons from '@expo/vector-icons/AntDesign';
import { useCreate } from './useCreate.hook';
export function Create() {
const { state, actions } = useCreate();
const create = async () => {
try {
await actions.create();
}
catch (err) {
Alert.alert(
"Create Failed",
"Please check your login and password.",
);
}
}
return (
<View style={styles.wrapper}>
<View style={styles.container}>
<View style={styles.control}>
<TouchableOpacity onPress={actions.config}>
<Ionicons style={styles.config} name="setting" size={24} color="#aaaaaa" />
</TouchableOpacity>
</View>
<Text style={styles.title}>Databag</Text>
<View style={styles.spacemid}>
<Text style={styles.header}>Create Account</Text>
</View>
<View style={styles.spacetop}>
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="user" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.create} onChangeText={actions.setLogin}
autoCapitalize="none" placeholder="username@server" />
<View style={styles.space} />
</View>
{ state.showPassword && (
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
autoCapitalize="none" placeholder="password" />
<TouchableOpacity onPress={actions.hidePassword}>
<Ionicons style={styles.icon} name="eye" size={18} color="#aaaaaa" />
</TouchableOpacity>
</View>
)}
{ !state.showPassword && (
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
secureTextEntry={true} autoCapitalize="none" placeholder="password" />
<TouchableOpacity onPress={actions.showPassword}>
<Ionicons style={styles.icon} name="eyeo" size={18} color="#aaaaaa" />
</TouchableOpacity>
</View>
)}
{ state.showConfirm && (
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.confirm} onChangeText={actions.setConfirm}
autoCapitalize="none" placeholder="confirm password" />
<TouchableOpacity onPress={actions.hideConfirm}>
<Ionicons style={styles.icon} name="eye" size={18} color="#aaaaaa" />
</TouchableOpacity>
</View>
)}
{ !state.showConfirm && (
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.confirm} onChangeText={actions.setConfirm}
secureTextEntry={true} autoCapitalize="none" placeholder="confirm password" />
<TouchableOpacity onPress={actions.showConfirm}>
<Ionicons style={styles.icon} name="eyeo" size={18} color="#aaaaaa" />
</TouchableOpacity>
</View>
)}
{ state.enabled && (
<TouchableOpacity style={styles.create} onPress={create}>
{ state.busy && (
<ActivityIndicator size="small" color="#ffffff" />
)}
{ !state.busy && (
<Text style={styles.createtext}>Create Account</Text>
)}
</TouchableOpacity>
)}
{ !state.enabled && (
<View style={styles.nocreate}>
<Text style={styles.nocreatetext}>Create</Text>
</View>
)}
<TouchableOpacity style={styles.create} onPress={actions.login}>
<Text style={styles.createtext}>Account Login</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}

View File

@ -0,0 +1,113 @@
import { StyleSheet } from 'react-native';
import { Colors } from 'constants/Colors';
export const styles = StyleSheet.create({
wrapper: {
width: '100%',
height: '100%',
},
config: {
paddingTop: 8,
},
icon: {
padding: 8,
},
space: {
width: 32,
},
container: {
flexDirection: 'column',
backgroundColor: Colors.formBackground,
borderRadius: 4,
width: '100%',
height: '100%',
display: 'flex',
paddingLeft: 16,
paddingRight: 16,
},
control: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-end',
color: Colors.grey,
},
title: {
width: '100%',
textAlign: 'center',
fontSize: 24,
color: Colors.grey,
},
spacemid: {
flexGrow: 1,
flexDirection: 'column',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
},
spacetop: {
flexGrow: 1,
flexDirection: 'column',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'flex-start',
width: '100%',
},
header: {
fontSize: 32,
color: Colors.text,
},
inputwrapper: {
display: 'flex',
flexDirection: 'row',
width: '100%',
borderRadius: 4,
borderColor: Colors.divider,
borderWidth: 1,
marginBottom: 16,
alignItems: 'center',
},
inputfield: {
flex: 1,
textAlign: 'center',
padding: 8,
},
create: {
marginTop: 16,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: 128,
height: 28,
backgroundColor: Colors.primary,
borderRadius: 4,
},
createtext: {
color: Colors.formFocus,
},
nocreate: {
marginTop: 16,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: 128,
height: 28,
borderRadius: 4,
borderColor: Colors.divider,
borderWidth: 1,
},
nocreatetext: {
color: Colors.disabled,
},
create: {
marginTop: 16,
},
createtext: {
fontColor: 'yellow',
},
nocreatetext: {
color: Colors.disabled,
},
})

View File

@ -0,0 +1,81 @@
import { useState, useEffect, useContext } from 'react';
import { useWindowDimensions } from 'react-native';
import { useNavigate } from 'react-router-dom';
import { AppContext } from 'context/AppContext';
export function useCreate() {
const navigate = useNavigate();
const app = useContext(AppContext);
const [state, setState] = useState({
busy: false,
enabled: false,
login: null,
password: null,
confirm: null,
showPassword: false,
showConfirm: false,
});
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
useEffect(() => {
if (state.password && state.login && !state.enabled) {
updateState({ enabled: true });
}
if ((!state.password || !state.login) && state.enabled) {
updateState({ enabled: false });
}
}, [state.login, state.password]);
const actions = {
config: () => {
navigate('/admin');
},
setLogin: (login) => {
updateState({ login });
},
setPassword: (password) => {
updateState({ password });
},
setConfirm: (confirm) => {
updateState({ confirm });
},
login: () => {
navigate('/login');
},
showPassword: () => {
updateState({ showPassword: true });
},
hidePassword: () => {
updateState({ showPassword: false });
},
showConfirm: () => {
updateState({ showConfirm: true });
},
hideConfirm: () => {
updateState({ showConfirm: false });
},
create: async () => {
if (!state.busy) {
updateState({ busy: true });
try {
await app.actions.create(state.login, state.password);
navigate('/');
}
catch (err) {
console.log(err);
updateState({ busy: false, showAlert: true });
throw new Error('create failed');
}
updateState({ busy: false });
}
}
};
return { state, actions };
}

View File

@ -35,14 +35,14 @@ export function Login() {
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="user" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.login} onChangeText={actions.setLogin}
autoCapitalize="none" />
autoCapitalize="none" placeholder="username@server" />
<View style={styles.space} />
</View>
{ state.showPassword && (
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
autoCapitalize="none" />
autoCapitalize="none" placeholder="password"/>
<TouchableOpacity onPress={actions.hidePassword}>
<Ionicons style={styles.icon} name="eye" size={18} color="#aaaaaa" />
</TouchableOpacity>
@ -52,7 +52,7 @@ export function Login() {
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
secureTextEntry={true} autoCapitalize="none" />
secureTextEntry={true} autoCapitalize="none" placeholder="password" />
<TouchableOpacity onPress={actions.showPassword}>
<Ionicons style={styles.icon} name="eyeo" size={18} color="#aaaaaa" />
</TouchableOpacity>

View File

@ -21,10 +21,10 @@ export function useLogin() {
}
useEffect(() => {
if (state.password && state.login && !state.enabled) {
if (state.password && state.login && !state.enabled && state.login.includes('@')) {
updateState({ enabled: true });
}
if ((!state.password || !state.login) && state.enabled) {
if ((!state.password || !state.login || !state.login.includes('@')) && state.enabled) {
updateState({ enabled: false });
}
}, [state.login, state.password]);