mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 20:49:16 +00:00
added account reset screen
This commit is contained in:
parent
a2d20d04de
commit
a745513092
@ -16,6 +16,7 @@ export default function App() {
|
|||||||
<Route path="/" element={ <Root /> } />
|
<Route path="/" element={ <Root /> } />
|
||||||
<Route path="/admin" element={ <Admin /> } />
|
<Route path="/admin" element={ <Admin /> } />
|
||||||
<Route path="/login" element={ <Access mode="login" /> } />
|
<Route path="/login" element={ <Access mode="login" /> } />
|
||||||
|
<Route path="/reset" element={ <Access mode="reset" /> } />
|
||||||
<Route path="/create" element={ <Access mode="create" /> } />
|
<Route path="/create" element={ <Access mode="create" /> } />
|
||||||
<Route path="/session" element={ <Session/> } />
|
<Route path="/session" element={ <Session/> } />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
@ -3,6 +3,7 @@ import { Wrapper, Container, PaddedPane, Pane, Splash } from './Access.styled';
|
|||||||
import { useAccess } from './useAccess.hook';
|
import { useAccess } from './useAccess.hook';
|
||||||
import { Login } from './login/Login';
|
import { Login } from './login/Login';
|
||||||
import { Create } from './create/Create';
|
import { Create } from './create/Create';
|
||||||
|
import { Reset } from './reset/Reset';
|
||||||
import logo from 'images/login.png';
|
import logo from 'images/login.png';
|
||||||
|
|
||||||
export function Access({ mode }) {
|
export function Access({ mode }) {
|
||||||
@ -24,6 +25,9 @@ export function Access({ mode }) {
|
|||||||
{ mode === 'create' && (
|
{ mode === 'create' && (
|
||||||
<Create />
|
<Create />
|
||||||
)}
|
)}
|
||||||
|
{ mode === 'reset' && (
|
||||||
|
<Reset />
|
||||||
|
)}
|
||||||
</Pane>
|
</Pane>
|
||||||
</Container>
|
</Container>
|
||||||
)}
|
)}
|
||||||
@ -35,6 +39,9 @@ export function Access({ mode }) {
|
|||||||
{ mode === 'create' && (
|
{ mode === 'create' && (
|
||||||
<Create />
|
<Create />
|
||||||
)}
|
)}
|
||||||
|
{ mode === 'reset' && (
|
||||||
|
<Reset />
|
||||||
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
)}
|
)}
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
|
@ -28,7 +28,7 @@ export function Create() {
|
|||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<View style={styles.control}>
|
<View style={styles.control}>
|
||||||
<TouchableOpacity onPress={actions.config}>
|
<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>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
<Text style={styles.title}>Databag</Text>
|
<Text style={styles.title}>Databag</Text>
|
||||||
|
@ -76,6 +76,11 @@ export function Login() {
|
|||||||
<TouchableOpacity style={styles.create} onPress={actions.create}>
|
<TouchableOpacity style={styles.create} onPress={actions.create}>
|
||||||
<Text style={styles.createtext}>Create Account</Text>
|
<Text style={styles.createtext}>Create Account</Text>
|
||||||
</TouchableOpacity>
|
</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>
|
||||||
</View>
|
</View>
|
||||||
|
@ -108,6 +108,12 @@ export const styles = StyleSheet.create({
|
|||||||
nocreatetext: {
|
nocreatetext: {
|
||||||
color: Colors.disabled,
|
color: Colors.disabled,
|
||||||
},
|
},
|
||||||
|
bottom: {
|
||||||
|
display: 'flex',
|
||||||
|
flexGrow: 1,
|
||||||
|
alignItems: 'flex-end',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
paddingBottom: 16,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -42,6 +42,9 @@ export function useLogin() {
|
|||||||
create: () => {
|
create: () => {
|
||||||
navigate('/create');
|
navigate('/create');
|
||||||
},
|
},
|
||||||
|
reset: () => {
|
||||||
|
navigate('/reset');
|
||||||
|
},
|
||||||
showPassword: () => {
|
showPassword: () => {
|
||||||
updateState({ showPassword: true });
|
updateState({ showPassword: true });
|
||||||
},
|
},
|
||||||
|
69
app/mobile/src/access/reset/Reset.jsx
Normal file
69
app/mobile/src/access/reset/Reset.jsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
113
app/mobile/src/access/reset/Reset.styled.js
Normal file
113
app/mobile/src/access/reset/Reset.styled.js
Normal 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,
|
||||||
|
},
|
||||||
|
|
||||||
|
})
|
||||||
|
|
63
app/mobile/src/access/reset/useReset.hook.js
Normal file
63
app/mobile/src/access/reset/useReset.hook.js
Normal 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 };
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user