diff --git a/app/mobile/src/access/create/Create.jsx b/app/mobile/src/access/create/Create.jsx index a5d90d18..a109127f 100644 --- a/app/mobile/src/access/create/Create.jsx +++ b/app/mobile/src/access/create/Create.jsx @@ -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 ( + + + + + + + + Databag + + Create Account + + + + + + + + { state.showPassword && ( + + + + + + + + )} + { !state.showPassword && ( + + + + + + + + )} + { state.showConfirm && ( + + + + + + + + )} + { !state.showConfirm && ( + + + + + + + + )} + { state.enabled && ( + + { state.busy && ( + + )} + { !state.busy && ( + Create Account + )} + + )} + { !state.enabled && ( + + Create + + )} + + Account Login + + + + + ); +} diff --git a/app/mobile/src/access/create/Create.styled.js b/app/mobile/src/access/create/Create.styled.js new file mode 100644 index 00000000..4c101165 --- /dev/null +++ b/app/mobile/src/access/create/Create.styled.js @@ -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, + }, + +}) + diff --git a/app/mobile/src/access/create/useCreate.hook.js b/app/mobile/src/access/create/useCreate.hook.js new file mode 100644 index 00000000..82d6d9bb --- /dev/null +++ b/app/mobile/src/access/create/useCreate.hook.js @@ -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 }; +} + diff --git a/app/mobile/src/access/login/Login.jsx b/app/mobile/src/access/login/Login.jsx index f67715ee..111913d2 100644 --- a/app/mobile/src/access/login/Login.jsx +++ b/app/mobile/src/access/login/Login.jsx @@ -35,14 +35,14 @@ export function Login() { + autoCapitalize="none" placeholder="username@server" /> { state.showPassword && ( + autoCapitalize="none" placeholder="password"/> @@ -52,7 +52,7 @@ export function Login() { + secureTextEntry={true} autoCapitalize="none" placeholder="password" /> diff --git a/app/mobile/src/access/login/useLogin.hook.js b/app/mobile/src/access/login/useLogin.hook.js index f7cbfa49..bb2dc8f6 100644 --- a/app/mobile/src/access/login/useLogin.hook.js +++ b/app/mobile/src/access/login/useLogin.hook.js @@ -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]);