diff --git a/.vscode/imexmobilesnippets.code-snippets b/.vscode/imexmobilesnippets.code-snippets
new file mode 100644
index 0000000..396d589
--- /dev/null
+++ b/.vscode/imexmobilesnippets.code-snippets
@@ -0,0 +1,51 @@
+{
+ // Place your bodyshop workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
+ // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
+ // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
+ // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
+ // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
+ // Placeholders with the same ids are connected.
+ // Example:
+ // "Print to console": {
+ // "scope": "javascript,typescript",
+ // "prefix": "log",
+ // "body": [
+ // "console.log('$1');",
+ // "$2"
+ // ],
+ // "description": "Log output to console"
+ // }
+ "Const T useTranslation": {
+ "prefix": "ttt",
+ "body": ["const { t } = useTranslation();"],
+ "description": "Use Translation Destructing."
+ },
+ " useTranslation import": {
+ "prefix": "tti",
+ "body": ["import { useTranslation } from \"react-i18next\";"],
+ "description": "Use Translation import."
+ },
+ "Redux Setup": {
+ "prefix": "rdx",
+ "body": [
+ "import { connect } from \"react-redux\";",
+ "import { createStructuredSelector } from \"reselect\";",
+ "const mapStateToProps = createStructuredSelector({",
+ " //currentUser: selectCurrentUser",
+ "});",
+ "const mapDispatchToProps = dispatch => ({",
+ " //setUserLanguage: language => dispatch(setUserLanguage(language))",
+ "});",
+ "export default connect (mapStateToProps,mapDispatchToProps)();"
+ ],
+ "description": "General Redux."
+ },
+ " Apollo Loading Error Handling import": {
+ "prefix": "ale",
+ "body": [
+ "if (loading) return ;",
+ "if (error) return ;"
+ ],
+ "description": "Apollo Loading Error Handling import."
+ }
+}
diff --git a/App.js b/App.js
index ceb523c..c9bc9f9 100644
--- a/App.js
+++ b/App.js
@@ -1,31 +1,44 @@
-import { StatusBar } from "expo-status-bar";
+import { Ionicons } from "@expo/vector-icons";
+import { AppLoading } from "expo";
+import * as Font from "expo-font";
import React from "react";
-import {
- SafeAreaView,
- StatusBar as rnStatusBar,
- StyleSheet,
- Text,
- View,
-} from "react-native";
-import { store, persistor } from "./redux/store";
+import { StatusBar as rnStatusBar, StyleSheet } from "react-native";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
-import SignIn from "./components/signin.component";
+import ScreenMainComponent from "./components/screen-main/screen-main.component";
+import { persistor, store } from "./redux/store";
+import "./translations/i18n";
-export default function App() {
- return (
-
-
-
-
- Open up App.js to start working on your app! ttt
-
-
-
-
-
-
- );
+export default class App extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ isReady: false,
+ };
+ }
+
+ async componentDidMount() {
+ await Font.loadAsync({
+ Roboto: require("native-base/Fonts/Roboto.ttf"),
+ Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
+ ...Ionicons.font,
+ });
+ this.setState({ isReady: true });
+ }
+
+ render() {
+ if (!this.state.isReady) {
+ return ;
+ }
+
+ return (
+
+
+
+
+
+ );
+ }
}
const styles = StyleSheet.create({
diff --git a/babel-translations.babel b/babel-translations.babel
new file mode 100644
index 0000000..5a0bee0
--- /dev/null
+++ b/babel-translations.babel
@@ -0,0 +1,301 @@
+
+
+
+ i18next
+ babel-translations.babel
+ .
+
+
+
+
+ common
+
+
+ translation
+
+
+ general
+
+
+ actions
+
+
+ signout
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
+
+
+
+ joblist
+
+
+ labels
+
+
+ activejobs
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
+
+ titles
+
+
+ jobtab
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
+
+
+
+ messaging
+
+
+ titles
+
+
+ messagingtab
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
+
+
+
+ settings
+
+
+ titles
+
+
+ settings
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
+
+
+
+ signin
+
+
+ actions
+
+
+ signin
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
+
+ fields
+
+
+ email
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ password
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+ en-US
+
+ translations/en-US
+
+
+ es-MX
+
+ translations/es-MX
+
+
+ fr-CA
+
+ translations/fr-CA
+
+
+
+
+ translations/en-US
+
+
+ translations/es-MX
+
+
+ translations/fr-CA
+
+
+
+ true
+
+ '%1'
+ { this.props.t('%1') }
+ { t('%1') }
+
+
+ en-US
+
+ tab
+ namespaced-json
+
+
diff --git a/components/screen-job-detail/screen-job-detail.component.jsx b/components/screen-job-detail/screen-job-detail.component.jsx
new file mode 100644
index 0000000..a4ddfc6
--- /dev/null
+++ b/components/screen-job-detail/screen-job-detail.component.jsx
@@ -0,0 +1,10 @@
+import React from "react";
+import { View, Text } from "react-native";
+
+export default function ScreenJobDetail({ navigation, ...restProps }) {
+ return (
+
+ The is the detail of the job.
+
+ );
+}
diff --git a/components/screen-job-list/screen-job-list.component.jsx b/components/screen-job-list/screen-job-list.component.jsx
new file mode 100644
index 0000000..5f9b678
--- /dev/null
+++ b/components/screen-job-list/screen-job-list.component.jsx
@@ -0,0 +1,12 @@
+import React from "react";
+import { View, Text } from "react-native";
+import { useTranslation } from "react-i18next";
+export default function ScreenJobList({ navigation }) {
+ const { t } = useTranslation();
+ return (
+
+ This is the Job List.
+ {t("joblist.labels.activejobs")}
+
+ );
+}
diff --git a/components/screen-main/screen-main.component.jsx b/components/screen-main/screen-main.component.jsx
new file mode 100644
index 0000000..d38d125
--- /dev/null
+++ b/components/screen-main/screen-main.component.jsx
@@ -0,0 +1,113 @@
+import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
+import { NavigationContainer } from "@react-navigation/native";
+import { createStackNavigator } from "@react-navigation/stack";
+import { createDrawerNavigator } from "@react-navigation/drawer";
+import i18n from "i18next";
+import React from "react";
+import { useTranslation } from "react-i18next";
+import { StatusBar as rnStatusBar, StyleSheet } from "react-native";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { emailSignInStart, signOutStart } from "../../redux/user/user.actions";
+import {
+ selectBodyshop,
+ selectCurrentUser,
+} from "../../redux/user/user.selectors";
+import ScreenJobDetail from "../screen-job-detail/screen-job-detail.component";
+import ScreenJobList from "../screen-job-list/screen-job-list.component";
+import ScreenMessagingConversation from "../screen-messaging-conversation/screen-messaging-conversation.component";
+import ScreenMessagingList from "../screen-messaging-list/screen-messaging-list.component";
+import ScreenSignIn from "../screen-sign-in/screen-sign-in.component";
+import ScreenSettingsComponent from "../screen-settings/screen-settings.component";
+const JobStack = createStackNavigator();
+const MessagingStack = createStackNavigator();
+const BottomTabs = createBottomTabNavigator();
+const Drawer = createDrawerNavigator();
+
+const mapStateToProps = createStructuredSelector({
+ bodyshop: selectBodyshop,
+ currentUser: selectCurrentUser,
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ emailSignInStart: (email, password) =>
+ dispatch(emailSignInStart({ email, password })),
+ signOutStart: () => dispatch(signOutStart()),
+});
+
+const JobStackNavigator = () => (
+
+ ({
+ title: `${i18n.t("joblist.labels.activejobs")} ${
+ JSON.stringify(route.params) | "X"
+ }`,
+ })}
+ component={ScreenJobList}
+ />
+
+
+);
+
+const MessagingStackNavigator = () => (
+
+
+
+
+);
+
+const BottomTabsNavigator = () => (
+
+
+
+
+);
+
+const DrawerNavigator = () => (
+
+
+
+
+);
+
+export function ScreenMainComponent({ currentUser }) {
+ const { t } = useTranslation();
+ return (
+
+ {currentUser.authorized ? : }
+
+ );
+}
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ScreenMainComponent);
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: "#fff",
+ alignItems: "center",
+ justifyContent: "center",
+ paddingTop: Platform.OS === "android" ? rnStatusBar.currentHeight : 0,
+ },
+});
diff --git a/components/screen-messaging-conversation/screen-messaging-conversation.component.jsx b/components/screen-messaging-conversation/screen-messaging-conversation.component.jsx
new file mode 100644
index 0000000..feeac47
--- /dev/null
+++ b/components/screen-messaging-conversation/screen-messaging-conversation.component.jsx
@@ -0,0 +1,10 @@
+import React from "react";
+import { View, Text } from "react-native";
+
+export default function ScreenMessagingConversation({ navigation }) {
+ return (
+
+ The detailed conversation
+
+ );
+}
diff --git a/components/screen-messaging-list/screen-messaging-list.component.jsx b/components/screen-messaging-list/screen-messaging-list.component.jsx
new file mode 100644
index 0000000..069ff23
--- /dev/null
+++ b/components/screen-messaging-list/screen-messaging-list.component.jsx
@@ -0,0 +1,10 @@
+import React from "react";
+import { View, Text } from "react-native";
+
+export default function ScreenMessagingList() {
+ return (
+
+ A list of conversations.
+
+ );
+}
diff --git a/components/screen-settings/screen-settings.component.jsx b/components/screen-settings/screen-settings.component.jsx
new file mode 100644
index 0000000..4f7a784
--- /dev/null
+++ b/components/screen-settings/screen-settings.component.jsx
@@ -0,0 +1,15 @@
+import React from "react";
+import { View, Text, SafeAreaView, Button } from "react-native";
+import SignOutButton from "../sign-out-button/sign-out-button.component";
+import { purgeStoredState } from "redux-persist";
+export default function ScreenSettingsComponent() {
+ return (
+
+
+ The settings Screen
+
+
+
+ );
+}
diff --git a/components/screen-sign-in/screen-sign-in.component.jsx b/components/screen-sign-in/screen-sign-in.component.jsx
new file mode 100644
index 0000000..00f0c61
--- /dev/null
+++ b/components/screen-sign-in/screen-sign-in.component.jsx
@@ -0,0 +1,101 @@
+import { Formik } from "formik";
+import {
+ Input,
+ Header,
+ Item,
+ Label,
+ Form,
+ Button,
+ Text,
+ Container,
+ Content,
+} from "native-base";
+import React from "react";
+import { useTranslation } from "react-i18next";
+import { SafeAreaView, TextInput, View } 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";
+
+const mapStateToProps = createStructuredSelector({
+ currentUser: selectCurrentUser,
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ emailSignInStart: (email, password) =>
+ dispatch(emailSignInStart({ email, password })),
+});
+
+export function SignIn({ emailSignInStart }) {
+ const { t } = useTranslation();
+
+ const formSubmit = (values) => {
+ const { email, password } = values;
+ emailSignInStart(email, password);
+ };
+
+ return (
+
+
+
+ {({ handleChange, handleBlur, handleSubmit, values }) => (
+
+
+
+ )}
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ contentContainer: {
+ justifyContent: "center",
+ flex: 1,
+ },
+ content: {
+ paddingBottom: 150,
+ // flex: 1,
+ // backgroundColor: "#fff",
+ // alignItems: "center",
+ //justifyContent: "space-between",
+ // //justifyContent: "center",
+ },
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(SignIn);
diff --git a/components/sign-out-button/sign-out-button.component.jsx b/components/sign-out-button/sign-out-button.component.jsx
new file mode 100644
index 0000000..86a23f2
--- /dev/null
+++ b/components/sign-out-button/sign-out-button.component.jsx
@@ -0,0 +1,24 @@
+import React from "react";
+import { useTranslation } from "react-i18next";
+import { Button } from "react-native";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { signOutStart } from "../../redux/user/user.actions";
+const mapStateToProps = createStructuredSelector({
+ //currentUser: selectCurrentUser
+});
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+ signOutStart: () => dispatch(signOutStart()),
+});
+
+export function SignOutButton({ signOutStart }) {
+ const { t } = useTranslation();
+ return (
+