Added sign in errors and logos.
This commit is contained in:
12
app.json
12
app.json
@@ -3,24 +3,22 @@
|
||||
"name": "imexmobile",
|
||||
"slug": "imexmobile",
|
||||
"version": "1.0.0",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/icon.png",
|
||||
"orientation": "both",
|
||||
"icon": "./assets/icon240.png",
|
||||
"splash": {
|
||||
"image": "./assets/splash.png",
|
||||
"image": "./assets/logo1024.png",
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"updates": {
|
||||
"fallbackToCacheTimeout": 0
|
||||
},
|
||||
"assetBundlePatterns": [
|
||||
"**/*"
|
||||
],
|
||||
"assetBundlePatterns": ["**/*"],
|
||||
"ios": {
|
||||
"supportsTablet": true
|
||||
},
|
||||
"web": {
|
||||
"favicon": "./assets/favicon.png"
|
||||
"favicon": "./assets/logo240.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
assets/logo1024.png
Normal file
BIN
assets/logo1024.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
assets/logo240.png
Normal file
BIN
assets/logo240.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
@@ -21,6 +21,32 @@
|
||||
<folder_node>
|
||||
<name>translation</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>app</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>title</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>general</name>
|
||||
<children>
|
||||
@@ -200,6 +226,74 @@
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>errors</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>emailformat</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>usernotfound</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>wrongpassword</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>fields</name>
|
||||
<children>
|
||||
|
||||
@@ -1,26 +1,34 @@
|
||||
import { Formik } from "formik";
|
||||
import {
|
||||
Input,
|
||||
Header,
|
||||
Item,
|
||||
Label,
|
||||
Form,
|
||||
Button,
|
||||
Text,
|
||||
Container,
|
||||
Content,
|
||||
Form,
|
||||
Input,
|
||||
Item,
|
||||
H1,
|
||||
Label,
|
||||
Text,
|
||||
} from "native-base";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SafeAreaView, TextInput, View } from "react-native";
|
||||
import { StyleSheet, View, ActivityIndicator, Image } from "react-native";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { emailSignInStart, signOutStart } from "../../redux/user/user.actions";
|
||||
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
import { StyleSheet } from "react-native";
|
||||
import { emailSignInStart } from "../../redux/user/user.actions";
|
||||
import {
|
||||
selectCurrentUser,
|
||||
selectSignInError,
|
||||
selectSigningIn,
|
||||
} from "../../redux/user/user.selectors";
|
||||
import SignInErrorAlertComponent from "../sign-in-error-alert/sign-in-error-alert.component";
|
||||
import styles from "../styles";
|
||||
import Logo from "../../assets/logo240.png";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentUser: selectCurrentUser,
|
||||
signInError: selectSignInError,
|
||||
signingIn: selectSigningIn,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
@@ -28,7 +36,7 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
dispatch(emailSignInStart({ email, password })),
|
||||
});
|
||||
|
||||
export function SignIn({ emailSignInStart }) {
|
||||
export function SignIn({ emailSignInStart, signInError, signingIn }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSubmit = (values) => {
|
||||
@@ -39,42 +47,45 @@ export function SignIn({ emailSignInStart }) {
|
||||
return (
|
||||
<Container>
|
||||
<Content
|
||||
scrollEnabled={false}
|
||||
padder
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
style={styles.content}
|
||||
contentContainerStyle={styles.contentContainer__centered}
|
||||
style={localStyles.content}
|
||||
>
|
||||
<View style={styles.evenlySpacedRow}>
|
||||
<Image style={localStyles.logo} source={Logo} />
|
||||
<H1>{t("app.title")}</H1>
|
||||
</View>
|
||||
<Formik
|
||||
initialValues={{ email: "", password: "" }}
|
||||
onSubmit={formSubmit}
|
||||
>
|
||||
{({ handleChange, handleBlur, handleSubmit, values }) => (
|
||||
<View>
|
||||
<Form>
|
||||
<Item>
|
||||
<Label>{t("signin.fields.email")}</Label>
|
||||
<Input
|
||||
autoCapitalize="none"
|
||||
keyboardType="email-address"
|
||||
onChangeText={handleChange("email")}
|
||||
onBlur={handleBlur("email")}
|
||||
value={values.email}
|
||||
/>
|
||||
</Item>
|
||||
|
||||
<Item>
|
||||
<Label>{t("signin.fields.password")}</Label>
|
||||
<Input
|
||||
secureTextEntry={true}
|
||||
onChangeText={handleChange("password")}
|
||||
onBlur={handleBlur("password")}
|
||||
value={values.password}
|
||||
/>
|
||||
</Item>
|
||||
|
||||
<Button full onPress={handleSubmit}>
|
||||
<Text>{t("signin.actions.signin")}</Text>
|
||||
</Button>
|
||||
</Form>
|
||||
<Item>
|
||||
<Label>{t("signin.fields.email")}</Label>
|
||||
<Input
|
||||
autoCapitalize="none"
|
||||
keyboardType="email-address"
|
||||
onChangeText={handleChange("email")}
|
||||
onBlur={handleBlur("email")}
|
||||
value={values.email}
|
||||
/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Label>{t("signin.fields.password")}</Label>
|
||||
<Input
|
||||
secureTextEntry={true}
|
||||
onChangeText={handleChange("password")}
|
||||
onBlur={handleBlur("password")}
|
||||
value={values.password}
|
||||
/>
|
||||
</Item>
|
||||
<SignInErrorAlertComponent />
|
||||
<Button full onPress={handleSubmit}>
|
||||
<Text>{t("signin.actions.signin")}</Text>
|
||||
{signingIn ? <ActivityIndicator size="large" /> : null}
|
||||
</Button>
|
||||
</View>
|
||||
)}
|
||||
</Formik>
|
||||
@@ -83,19 +94,11 @@ export function SignIn({ emailSignInStart }) {
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
contentContainer: {
|
||||
justifyContent: "center",
|
||||
flex: 1,
|
||||
},
|
||||
const localStyles = StyleSheet.create({
|
||||
content: {
|
||||
paddingBottom: 150,
|
||||
// flex: 1,
|
||||
// backgroundColor: "#fff",
|
||||
// alignItems: "center",
|
||||
//justifyContent: "space-between",
|
||||
// //justifyContent: "center",
|
||||
},
|
||||
logo: { width: 100, height: 100 },
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(SignIn);
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Container, Content, Text } from "native-base";
|
||||
import { View, StyleSheet } from "react-native";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectSignInError } from "../../redux/user/user.selectors";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
signInError: selectSignInError,
|
||||
});
|
||||
|
||||
export function SignInErrorAlertComponent({ signInError }) {
|
||||
const [errorText, setErrorText] = useState("");
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
let text;
|
||||
if (signInError && signInError.code)
|
||||
switch (signInError.code) {
|
||||
case "auth/user-not-found":
|
||||
text = t("signin.errors.usernotfound");
|
||||
break;
|
||||
case "auth/invalid-email":
|
||||
text = t("signin.errors.emailformat");
|
||||
break;
|
||||
case "auth/wrong-password":
|
||||
text = t("signin.errors.wrongpassword");
|
||||
break;
|
||||
default:
|
||||
text = signInError.code + " " + signInError.message;
|
||||
break;
|
||||
}
|
||||
|
||||
setErrorText(text);
|
||||
}, [signInError, setErrorText]);
|
||||
return (
|
||||
<View>
|
||||
{errorText ? <Text style={localStyles.alert}>{errorText}</Text> : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(SignInErrorAlertComponent);
|
||||
|
||||
const localStyles = StyleSheet.create({
|
||||
alert: {
|
||||
color: "red",
|
||||
textAlign: "center",
|
||||
margin: 15,
|
||||
padding: 15,
|
||||
},
|
||||
});
|
||||
15
components/styles.js
Normal file
15
components/styles.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { StyleSheet } from "react-native";
|
||||
import { Row } from "native-base";
|
||||
|
||||
export default StyleSheet.create({
|
||||
contentContainer__centered: {
|
||||
justifyContent: "center",
|
||||
flex: 1,
|
||||
},
|
||||
|
||||
evenlySpacedRow: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-evenly",
|
||||
alignItems: "center",
|
||||
},
|
||||
});
|
||||
@@ -6,39 +6,23 @@ const INITIAL_STATE = {
|
||||
},
|
||||
bodyshop: null,
|
||||
fingerprint: null,
|
||||
signingIn: false,
|
||||
error: null,
|
||||
conflict: false,
|
||||
passwordreset: {
|
||||
email: null,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
};
|
||||
|
||||
const userReducer = (state = INITIAL_STATE, action) => {
|
||||
switch (action.type) {
|
||||
// case UserActionTypes.VALIDATE_PASSWORD_RESET_START:
|
||||
// case UserActionTypes.SEND_PASSWORD_RESET_EMAIL_START:
|
||||
// return {
|
||||
// ...state,
|
||||
// passwordreset: {
|
||||
// email: action.payload,
|
||||
// error: null,
|
||||
// success: false,
|
||||
// },
|
||||
// };
|
||||
// case UserActionTypes.VALIDATE_PASSWORD_RESET_FAILURE:
|
||||
// case UserActionTypes.SEND_PASSWORD_RESET_EMAIL_FAILURE:
|
||||
// return { ...state, passwordreset: { error: action.payload } };
|
||||
// case UserActionTypes.VALIDATE_PASSWORD_RESET_SUCCESS:
|
||||
// case UserActionTypes.SEND_PASSWORD_RESET_EMAIL_SUCCESS:
|
||||
// return {
|
||||
// ...state,
|
||||
// passwordreset: { ...state.passwordreset, success: true },
|
||||
// };
|
||||
case UserActionTypes.EMAIL_SIGN_IN_START:
|
||||
return {
|
||||
...state,
|
||||
signingIn: true,
|
||||
error: null,
|
||||
};
|
||||
case UserActionTypes.SIGN_IN_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
signingIn: false,
|
||||
currentUser: action.payload,
|
||||
error: null,
|
||||
};
|
||||
@@ -54,11 +38,7 @@ const userReducer = (state = INITIAL_STATE, action) => {
|
||||
error: null,
|
||||
currentUser: { authorized: false },
|
||||
};
|
||||
// case UserActionTypes.SET_USER_LANGUAGE:
|
||||
// return {
|
||||
// ...state,
|
||||
// language: action.payload,
|
||||
// };
|
||||
|
||||
case UserActionTypes.UPDATE_USER_DETAILS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
@@ -75,6 +55,7 @@ const userReducer = (state = INITIAL_STATE, action) => {
|
||||
case UserActionTypes.EMAIL_SIGN_UP_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
signingIn: false,
|
||||
error: action.payload,
|
||||
};
|
||||
default:
|
||||
|
||||
@@ -26,3 +26,8 @@ export const selectPasswordReset = createSelector(
|
||||
[selectUser],
|
||||
(user) => user.passwordreset
|
||||
);
|
||||
|
||||
export const selectSigningIn = createSelector(
|
||||
[selectUser],
|
||||
(user) => user.signingIn
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const UserActionTypes = {
|
||||
SET_CURRENT_USER: "SET_CURRENT_USER",
|
||||
GOOGLE_SIGN_IN_START: "GOOGLE_SIGN_IN_START",
|
||||
SIGN_IN_SUCCESS: "SIGN_IN_SUCCESS",
|
||||
SIGN_IN_FAILURE: "SIGN_IN_FAILURE",
|
||||
EMAIL_SIGN_IN_START: "EMAIL_SIGN_IN_START",
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"translation": {
|
||||
"app": {
|
||||
"title": "ImEX Mobile"
|
||||
},
|
||||
"general": {
|
||||
"actions": {
|
||||
"signout": "Sign Out"
|
||||
@@ -27,6 +30,11 @@
|
||||
"actions": {
|
||||
"signin": "Sign In"
|
||||
},
|
||||
"errors": {
|
||||
"emailformat": "The email you have entered is not formatted correctly. ",
|
||||
"usernotfound": "No user found.",
|
||||
"wrongpassword": "The password you entered is not correct."
|
||||
},
|
||||
"fields": {
|
||||
"email": "Email",
|
||||
"password": "Password"
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"translation": {
|
||||
"app": {
|
||||
"title": ""
|
||||
},
|
||||
"general": {
|
||||
"actions": {
|
||||
"signout": ""
|
||||
@@ -27,6 +30,11 @@
|
||||
"actions": {
|
||||
"signin": ""
|
||||
},
|
||||
"errors": {
|
||||
"emailformat": "",
|
||||
"usernotfound": "",
|
||||
"wrongpassword": ""
|
||||
},
|
||||
"fields": {
|
||||
"email": "Email",
|
||||
"password": ""
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"translation": {
|
||||
"app": {
|
||||
"title": ""
|
||||
},
|
||||
"general": {
|
||||
"actions": {
|
||||
"signout": ""
|
||||
@@ -27,6 +30,11 @@
|
||||
"actions": {
|
||||
"signin": ""
|
||||
},
|
||||
"errors": {
|
||||
"emailformat": "",
|
||||
"usernotfound": "",
|
||||
"wrongpassword": ""
|
||||
},
|
||||
"fields": {
|
||||
"email": "Email",
|
||||
"password": ""
|
||||
|
||||
Reference in New Issue
Block a user