added account reset screen

This commit is contained in:
balzack 2022-09-10 23:40:11 -07:00
parent a2d20d04de
commit a745513092
9 changed files with 269 additions and 2 deletions

View File

@ -16,6 +16,7 @@ export default function App() {
<Route path="/" element={ <Root /> } />
<Route path="/admin" element={ <Admin /> } />
<Route path="/login" element={ <Access mode="login" /> } />
<Route path="/reset" element={ <Access mode="reset" /> } />
<Route path="/create" element={ <Access mode="create" /> } />
<Route path="/session" element={ <Session/> } />
</Routes>

View File

@ -3,6 +3,7 @@ import { Wrapper, Container, PaddedPane, Pane, Splash } from './Access.styled';
import { useAccess } from './useAccess.hook';
import { Login } from './login/Login';
import { Create } from './create/Create';
import { Reset } from './reset/Reset';
import logo from 'images/login.png';
export function Access({ mode }) {
@ -24,6 +25,9 @@ export function Access({ mode }) {
{ mode === 'create' && (
<Create />
)}
{ mode === 'reset' && (
<Reset />
)}
</Pane>
</Container>
)}
@ -35,6 +39,9 @@ export function Access({ mode }) {
{ mode === 'create' && (
<Create />
)}
{ mode === 'reset' && (
<Reset />
)}
</Container>
)}
</SafeAreaView>

View File

@ -28,7 +28,7 @@ export function Create() {
<View style={styles.container}>
<View style={styles.control}>
<TouchableOpacity onPress={actions.config}>
<Ionicons style={styles.config} name="setting" size={24} color="#888888" />
<Ionicons style={styles.config} name="setting" size={24} color="#aaaaaa" />
</TouchableOpacity>
</View>
<Text style={styles.title}>Databag</Text>

View File

@ -76,6 +76,11 @@ export function Login() {
<TouchableOpacity style={styles.create} onPress={actions.create}>
<Text style={styles.createtext}>Create Account</Text>
</TouchableOpacity>
<View style={styles.bottom}>
<TouchableOpacity style={styles.create} onPress={actions.reset}>
<Text style={styles.createtext}>Forgot Password</Text>
</TouchableOpacity>
</View>
</View>
</View>
</View>

View File

@ -108,6 +108,12 @@ export const styles = StyleSheet.create({
nocreatetext: {
color: Colors.disabled,
},
bottom: {
display: 'flex',
flexGrow: 1,
alignItems: 'flex-end',
justifyContent: 'flex-end',
paddingBottom: 16,
},
})

View File

@ -42,6 +42,9 @@ export function useLogin() {
create: () => {
navigate('/create');
},
reset: () => {
navigate('/reset');
},
showPassword: () => {
updateState({ showPassword: true });
},

View File

@ -0,0 +1,69 @@
import { ActivityIndicator, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native';
import { styles } from './Reset.styled';
import Ionicons from '@expo/vector-icons/AntDesign';
import { useReset } from './useReset.hook';
export function Reset() {
const { state, actions } = useReset();
const reset = async () => {
try {
await actions.reset();
}
catch (err) {
Alert.alert(
"Reset Failed",
"Please check your server and token.",
);
}
}
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}>Access Account</Text>
</View>
<View style={styles.spacetop}>
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="database" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.server} onChangeText={actions.setServer}
autoCapitalize="none" placeholder="server" />
<View style={styles.space} />
</View>
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="key" size={18} color="#aaaaaa" />
<TextInput style={styles.inputfield} value={state.token} onChangeText={actions.setToken}
autoCapitalize="none" placeholder="token"/>
<View style={styles.space} />
</View>
{ state.enabled && (
<TouchableOpacity style={styles.reset} onPress={reset}>
{ state.busy && (
<ActivityIndicator size="small" color="#ffffff" />
)}
{ !state.busy && (
<Text style={styles.resettext}>Access</Text>
)}
</TouchableOpacity>
)}
{ !state.enabled && (
<View style={styles.noreset}>
<Text style={styles.noresettext}>Access</Text>
</View>
)}
<TouchableOpacity style={styles.login} 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,
},
reset: {
marginTop: 16,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: 128,
height: 28,
backgroundColor: Colors.primary,
borderRadius: 4,
},
resettext: {
color: Colors.formFocus,
},
noreset: {
marginTop: 16,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: 128,
height: 28,
borderRadius: 4,
borderColor: Colors.divider,
borderWidth: 1,
},
noresettext: {
color: Colors.disabled,
},
login: {
marginTop: 16,
},
logintext: {
fontColor: 'yellow',
},
nologintext: {
color: Colors.disabled,
},
})

View File

@ -0,0 +1,63 @@
import { useState, useEffect, useContext } from 'react';
import { useWindowDimensions } from 'react-native';
import { useNavigate } from 'react-router-dom';
import { AppContext } from 'context/AppContext';
export function useReset() {
const navigate = useNavigate();
const app = useContext(AppContext);
const [state, setState] = useState({
busy: false,
enabled: false,
server: null,
token: null,
});
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
useEffect(() => {
if (state.token && state.server && !state.enabled) {
updateState({ enabled: true });
}
if ((!state.token || !state.server) && state.enabled) {
updateState({ enabled: false });
}
}, [state.server, state.token]);
const actions = {
config: () => {
navigate('/admin');
},
setServer: (server) => {
updateState({ server });
},
setToken: (token) => {
updateState({ token });
},
login: () => {
navigate('/login');
},
access: async () => {
if (!state.busy) {
updateState({ busy: true });
try {
await app.actions.login(state.login, state.password);
navigate('/');
}
catch (err) {
console.log(err);
updateState({ busy: false, showAlert: true });
throw new Error('login failed');
}
updateState({ busy: false });
}
}
};
return { state, actions };
}