diff --git a/src/components/FormErrors.js b/src/components/FormErrors.js
new file mode 100644
index 0000000..b10666d
--- /dev/null
+++ b/src/components/FormErrors.js
@@ -0,0 +1,26 @@
+import React from 'react';
+import { Alert, HStack, Text } from 'native-base';
+
+const FormErrors = ({ errors }) => {
+ if (!Object.keys(errors).length || !['non_field_errors', 'detail'].some((errorField) => errorField in errors)) {
+ return null;
+ }
+
+ let errorFormatted;
+ if ('non_field_errors' in errors) {
+ errorFormatted = errors.non_field_errors?.[0];
+ } else if ('detail' in errors) {
+ errorFormatted = errors.detail;
+ }
+ if (!errorFormatted) errorFormatted = 'Kunne ikke sende inn skjemaet, prøv igjen...';
+
+ return (
+
+
+
+ {errorFormatted}
+
+
+ );
+};
+export default FormErrors;
diff --git a/src/components/FormInput.js b/src/components/FormInput.js
new file mode 100644
index 0000000..a3cc3d5
--- /dev/null
+++ b/src/components/FormInput.js
@@ -0,0 +1,44 @@
+import React from 'react';
+import { Controller } from 'react-hook-form';
+
+import { Input, Text, WarningOutlineIcon, FormControl } from 'native-base';
+
+const FormInput = ({
+ control,
+ errors,
+ name,
+ label,
+ rules = {
+ required: 'kan ikke være tomt.',
+ },
+ returnKeyType = 'next',
+ ...rest
+}) => {
+ return (
+ (
+
+ {label}
+
+ {errors[name] && (
+ }>
+ {errors[name].message}
+
+ )}
+
+ )}
+ name={name}
+ defaultValue=""
+ />
+ );
+};
+export default FormInput;
diff --git a/src/modules/login/Login.js b/src/modules/login/Login.js
index 22bbf1b..ebd5e12 100644
--- a/src/modules/login/Login.js
+++ b/src/modules/login/Login.js
@@ -1,102 +1,70 @@
-import React, { useRef } from 'react';
+import React from 'react';
import { Linking, StyleSheet, View } from 'react-native';
-import { Container, Input, Spinner, Button, Text } from 'native-base';
+import { ScrollView, Spinner, Button, Text } from 'native-base';
import Config from 'react-native-config';
import theme from '../../theme';
import useLogin from './useLogin';
-
-const FormErrors = ({ loginError }) => {
- if (!loginError) {
- return ;
- }
- const err = loginError.non_field_errors;
- const errorFormatted = err ? err[0] : 'Feil brukernavn eller passord, prøv igjen...';
- // TODO: Format these and highlight error fields
- return (
-
- {errorFormatted}
-
- );
-};
+import FormInput from '../../components/FormInput';
+import FormErrors from '../../components/FormErrors';
const Login = ({ onLogin }) => {
- const passwordInputRef = useRef();
- const { password, setPassword, email, setEmail, loginError, onLoginPress, isLoggingIn } = useLogin(onLogin);
-
- // FIXME: highlight fields with errors
- // const usernameHasError = Boolean(loginError?.username);
- // const passwordHasError = Boolean(loginError?.password);
+ const { isLoggingIn, errors, control, setFocus, onSubmit } = useLogin(onLogin);
return (
-
-
- E-post / Brukernavn
- {
- passwordInputRef.current.focus();
- }}
- />
- Passord
-
-
-
- {isLoggingIn && }
-
+
+
+
+ setFocus('password')}
+ />
+
+
+
+ {isLoggingIn && }
+
+
);
};
export default Login;
const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- },
- input: {
- width: 320,
- fontSize: 20,
- height: 52,
- },
loginButton: {
- marginBottom: 16,
+ marginTop: 16,
},
forgotPasswordButton: {
alignSelf: 'center',
marginTop: 32,
marginBottom: 16,
},
- errorBox: {
- marginVertical: 10,
- },
- errorMessage: {
- textAlign: 'center',
- color: 'red',
- },
card: theme.card,
});
diff --git a/src/modules/login/useLogin.js b/src/modules/login/useLogin.js
index 6487d4a..573d51a 100644
--- a/src/modules/login/useLogin.js
+++ b/src/modules/login/useLogin.js
@@ -1,25 +1,31 @@
import { useNavigation } from '@react-navigation/native';
-import { useState, useEffect } from 'react';
+import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
+import { useForm } from 'react-hook-form';
import { requestLogin } from '../../api';
const useLogin = () => {
- const [email, setEmail] = useState('');
- const [password, setPassword] = useState('');
const navigation = useNavigation();
const dispatch = useDispatch();
- const onLoginPress = () => {
- dispatch(requestLogin(email, password));
- };
-
const { isAuthenticated, isLoggingIn, loginError } = useSelector((store) => ({
isAuthenticated: store.isAuthenticated,
isLoggingIn: store.isLoggingIn,
loginError: store.loginError,
}));
+ const {
+ control,
+ handleSubmit,
+ formState: { errors },
+ setFocus,
+ } = useForm();
+
+ const onSubmit = handleSubmit(({ email, password }) => {
+ dispatch(requestLogin(email, password));
+ });
+
useEffect(() => {
if (isAuthenticated) {
// navigation.goBack onLogin works since LoginScreen is allways navigated to from MembershipScreen
@@ -27,7 +33,7 @@ const useLogin = () => {
}
}, [isAuthenticated]);
- return { email, setEmail, password, setPassword, onLoginPress, isLoggingIn, loginError };
+ return { onSubmit, isLoggingIn, control, setFocus, errors: { ...errors, ...loginError } };
};
export default useLogin;
diff --git a/src/modules/register/UserRegister.js b/src/modules/register/UserRegister.js
index a89c62a..329bd9e 100644
--- a/src/modules/register/UserRegister.js
+++ b/src/modules/register/UserRegister.js
@@ -1,77 +1,12 @@
import React from 'react';
-import { Input, Spinner, Button, Text, WarningOutlineIcon, FormControl, ScrollView } from 'native-base';
+import { Spinner, Button, Text, ScrollView } from 'native-base';
import { StyleSheet, View } from 'react-native';
import * as EmailValidator from 'email-validator';
-import { Controller } from 'react-hook-form';
import theme from '../../theme';
import useUserRegister from './useUserRegister';
-
-const FormInput = ({
- control,
- errors,
- name,
- label,
- rules = {
- required: 'kan ikke være tomt.',
- },
- returnKeyType = 'next',
- ...rest
-}) => {
- return (
- (
-
- {label}
-
- {errors[name] && (
- }>
- {errors[name].message}
-
- )}
-
- )}
- name={name}
- defaultValue=""
- />
- );
-};
-
-const Registerbutton = ({ isDisabled, onPress }) => (
-
-);
-
-const NonFieldErrors = ({ errors }) => {
- if (!Object.keys(errors).length || !['non_field_errors', 'detail'].some((errorField) => errorField in errors)) {
- return null;
- }
- let errorFormatted;
- if ('non_field_errors' in errors) {
- errorFormatted = errors.non_field_errors?.[0];
- } else if ('detail' in errors) {
- errorFormatted = errors.detail;
- }
- if (!errorFormatted) errorFormatted = 'Kunne ikke registrere bruker, prøv igjen...';
-
- return (
-
- }>
- {errorFormatted}
-
-
- );
-};
+import FormInput from '../../components/FormInput';
+import FormErrors from '../../components/FormErrors';
const UserRegister = () => {
const { isRegisteringUser, onSubmit, control, isValid, errors, setFocus } = useUserRegister();
@@ -130,8 +65,12 @@ const UserRegister = () => {
returnKeyType="send"
onSubmitEditing={onSubmit}
/>
-
-
+
+
+
+
{isRegisteringUser && }
diff --git a/src/reduxStore.js b/src/reduxStore.js
index 4513771..d6e5682 100644
--- a/src/reduxStore.js
+++ b/src/reduxStore.js
@@ -8,7 +8,7 @@ import rootReducer from './reducers';
const persistConfig = {
key: 'root',
storage: AsyncStorage,
- blacklist: ['isLoggingIn', 'isFetchingUserData', 'isRegisteringUser', 'isChargingMembership'],
+ blacklist: ['isLoggingIn', 'isFetchingUserData', 'isRegisteringUser', 'isChargingMembership', 'loginError'],
};
const persistedReducer = persistReducer(persistConfig, rootReducer);