From aedce9ace7a0ba02f0bcafd2d5ed9535061268c8 Mon Sep 17 00:00:00 2001 From: De3bs Date: Sun, 30 Apr 2023 13:48:05 +0300 Subject: [PATCH] Feat : UI and Functionalities for onBoarding --- app/_layout.tsx | 23 +++++- app/components/AppTextInput.js | 61 ++++++++++++++ app/components/ErrorMessage.js | 12 +++ app/data/games.js | 26 ++++++ app/home/home.tsx | 32 ++++++-- app/onboarding/game-selection.tsx | 98 ++++++++++++++++++---- app/onboarding/signin.tsx | 130 ++++++++++++++++++++++++++++++ app/onboarding/signup.tsx | 71 ++++++++++++---- app/onboarding/tips.tsx | 31 +++++++ assets/logo.png | Bin 0 -> 3584 bytes package.json | 5 +- 11 files changed, 453 insertions(+), 36 deletions(-) create mode 100644 app/components/AppTextInput.js create mode 100644 app/components/ErrorMessage.js create mode 100644 app/data/games.js create mode 100644 app/onboarding/signin.tsx create mode 100644 app/onboarding/tips.tsx create mode 100644 assets/logo.png diff --git a/app/_layout.tsx b/app/_layout.tsx index ff2bddf..793145b 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,11 +1,32 @@ import { Stack } from "expo-router"; import { SafeAreaProvider } from "react-native-safe-area-context"; +import { Image, View } from "react-native"; +function LogoTitle() { + return ( + + + + ); +} export default function RootLayout() { return ( - + , + }} + /> ); } diff --git a/app/components/AppTextInput.js b/app/components/AppTextInput.js new file mode 100644 index 0000000..bcb0701 --- /dev/null +++ b/app/components/AppTextInput.js @@ -0,0 +1,61 @@ +import React from "react"; +import { View, TextInput, StyleSheet, TouchableOpacity } from "react-native"; +import { MaterialCommunityIcons } from "@expo/vector-icons"; + +function AppTextInput({ + icon, + hiddenIcon, + onPress, + width = "100%", + ...otherProps +}) { + return ( + + + + + + + {hiddenIcon && ( + + + + )} + + ); +} + +const styles = StyleSheet.create({ + container: { + backgroundColor: "black", + borderRadius: 8, + flexDirection: "row", + padding: 15, + marginVertical: 10, + borderWidth: 2, + borderColor: "#17b1f3", + justifyContent: "space-between", + }, + icon: { + marginRight: 10, + }, + text: { + fontSize: 18, + color: "#848d937f", + }, +}); + +export default AppTextInput; diff --git a/app/components/ErrorMessage.js b/app/components/ErrorMessage.js new file mode 100644 index 0000000..90bbbdb --- /dev/null +++ b/app/components/ErrorMessage.js @@ -0,0 +1,12 @@ +import React from "react"; +import { StyleSheet, Text } from "react-native"; + +function ErrorMessage({ error }) { + return {error}; +} + +const styles = StyleSheet.create({ + error: { color: "red", fontSize: 14 }, +}); + +export default ErrorMessage; diff --git a/app/data/games.js b/app/data/games.js new file mode 100644 index 0000000..0eec85a --- /dev/null +++ b/app/data/games.js @@ -0,0 +1,26 @@ +export const GAMES = [ + { + id: 1, + name: "Clash Royale", + }, + { + id: 2, + name: "Clash of Clans", + }, + { + id: 3, + name: "Clash Mini", + }, + { + id: 4, + name: "Tennis Clash", + }, + { + id: 5, + name: "Clash Quest", + }, + { + id: 6, + name: "Golf Clash", + }, +]; diff --git a/app/home/home.tsx b/app/home/home.tsx index 099255e..39cb93a 100644 --- a/app/home/home.tsx +++ b/app/home/home.tsx @@ -1,8 +1,10 @@ -import { Link, Stack } from "expo-router"; +import { Link, Stack, useSearchParams } from "expo-router"; import { StatusBar } from "expo-status-bar"; import { StyleSheet, Text, View } from "react-native"; export default function Signup() { + const { email, gameSelected } = useSearchParams(); + const options = { title: "Home", }; @@ -10,7 +12,16 @@ export default function Signup() { return ( - Home + + + User: + {email} + + + Game Selected: + {gameSelected} + + ); } @@ -18,8 +29,19 @@ export default function Signup() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: "#fff", - alignItems: "center", - justifyContent: "center", + backgroundColor: "black", + padding: 20, + }, + headerContainer: { + borderRadius: 8, + borderWidth: 1, + borderColor: "#17b1f3", + padding: 4, + }, + header: { + color: "#17b1f3", + fontSize: 18, + textAlign: "center", + margin: 5, }, }); diff --git a/app/onboarding/game-selection.tsx b/app/onboarding/game-selection.tsx index 30c2641..8a289ca 100644 --- a/app/onboarding/game-selection.tsx +++ b/app/onboarding/game-selection.tsx @@ -1,18 +1,58 @@ - -import { Link, Stack } from "expo-router"; -import { StyleSheet, Text, View } from "react-native"; +import React, { useState } from "react"; +import { Link, Stack, useRouter, useSearchParams } from "expo-router"; +import { + StyleSheet, + Text, + View, + FlatList, + TouchableOpacity, +} from "react-native"; +import { GAMES } from "../data/games"; export default function GameSelection() { + const { email } = useSearchParams(); + const [gameSelected, setGameSelected] = useState(""); const options = { title: "Game Selection", }; - + const router = useRouter(); + function renderGameItem(item: any) { + return ( + setGameSelected(item.name)}> + + {item.name} + + + ); + } + function handleNavigation() { + router.push("/home/home"); + router.setParams({ email: email, gameSelected: gameSelected }); + } return ( - - to home - + + Email : {email} + + item.id.toString()} + renderItem={({ item }) => renderGameItem(item)} + /> + + handleNavigation()} + > + HOME + ); } @@ -20,14 +60,42 @@ export default function GameSelection() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: "#fff", + backgroundColor: "black", + padding: 16, + justifyContent: "space-between", + }, + header: { + fontSize: 16, + fontWeight: "bold", + color: "white", + marginBottom: 20, + }, + info: { + color: "#17b1f3", + marginHorizontal: 20, + }, + gameContainer: { + flex: 1, alignItems: "center", - justifyContent: "center", + borderColor: "#17b1f3", + borderWidth: 1, + borderRadius: 8, + marginVertical: 10, + padding: 8, + }, + buttonText: { + marginBottom: 8, + fontSize: 18, + fontWeight: "bold", + color: "black", + fontFamily: "Roboto", + textAlign: "center", + }, + button: { + borderWidth: 1, + padding: 10, + borderRadius: 10, + margin: 2, + backgroundColor: "#17b1f3", }, - button: { - borderWidth: 1, - borderColor: 'black', - padding: 15, - borderRadius: 5, - } }); diff --git a/app/onboarding/signin.tsx b/app/onboarding/signin.tsx new file mode 100644 index 0000000..475e65d --- /dev/null +++ b/app/onboarding/signin.tsx @@ -0,0 +1,130 @@ +import React, { useEffect, useState } from "react"; +import { Link, Stack, useRouter } from "expo-router"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { Formik } from "formik"; +import * as Yup from "yup"; +import AppTextInput from "../components/AppTextInput"; +import ErrorMessage from "../components/ErrorMessage"; + +const validationSchema = Yup.object().shape({ + email: Yup.string().required().email().label("Email"), + password: Yup.string().required().min(6).label("Password"), +}); + +const signin = (props: any) => { + const [visible, setVisible] = useState(false); + const [isAuthenticated, setIsAuthenticated] = useState(false); + const router = useRouter(); + const options = { + title: "Sign in", + }; + function onShowPasswordHandler() { + visible ? setVisible(false) : setVisible(true); + } + + function handleNavigation({ email, password }) { + console.log(email, password); + setIsAuthenticated(true); + router.push("/onboarding/game-selection"); + router.setParams({ email: email, password: password }); + } + return ( + + + + handleNavigation(values)} + validationSchema={validationSchema} + > + {({ handleChange, handleSubmit, errors, setFieldTouched, touched }) => ( + <> + + Sign In + Sign in with email + + + setFieldTouched("email")} + onChangeText={handleChange("email")} + placeholder="Email" + textContentType="emailAddress" + hiddenIcon={null} + onPress={null} + /> + {touched.email && } + setFieldTouched("password")} + textContentType="password" + placeholder="Password" + secureTextEntry={visible ? false : true} + hiddenIcon={"eye"} + onPress={onShowPasswordHandler} + /> + {touched.password && } + + + + handleSubmit()} + > + SIGN IN + + + )} + + + ); +}; + +export default signin; +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "black", + justifyContent: "space-between", + }, + title: { + fontSize: 20, + fontWeight: "bold", + color: "white", + marginBottom: 2, + }, + subTitle: { + fontSize: 14, + marginBottom: 20, + color: "#848d937f", + }, + rootContainer: { + margin: 20, + flex: 1, + }, + inputContainer: { + justifyContent: "center", + flex: 0.7, + }, + buttonText: { + marginBottom: 8, + fontSize: 18, + fontWeight: "bold", + color: "black", + fontFamily: "Roboto", + textAlign: "center", + }, + button: { + borderWidth: 1, + padding: 10, + borderRadius: 10, + margin: 25, + backgroundColor: "#17b1f3", + }, +}); diff --git a/app/onboarding/signup.tsx b/app/onboarding/signup.tsx index 45c63f1..4480866 100644 --- a/app/onboarding/signup.tsx +++ b/app/onboarding/signup.tsx @@ -1,6 +1,6 @@ import { Link, Stack } from "expo-router"; -import { StatusBar } from "expo-status-bar"; -import { StyleSheet, Text, View } from "react-native"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { MaterialCommunityIcons } from "@expo/vector-icons"; export default function Signup() { const options = { @@ -10,9 +10,28 @@ export default function Signup() { return ( - - to game selection - + + + If you don't have an account, we will create one for you. + + + + + Sign in with email + + + ); } @@ -20,14 +39,38 @@ export default function Signup() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: "#fff", - alignItems: "center", - justifyContent: "center", + backgroundColor: "black", + padding: 16, + }, + rootContainer: { + margin: 10, + }, + header: { + marginBottom: 30, + fontSize: 18, + fontWeight: "bold", + color: "white", + }, + text: { + fontSize: 16, + fontWeight: "300", + color: "#848d937f", + }, + + button: { + borderWidth: 1, + borderColor: "white", + padding: 15, + borderRadius: 5, + flexDirection: "row", + }, + icon: { + marginRight: 10, }, - button: { - borderWidth: 1, - borderColor: 'black', - padding: 15, - borderRadius: 5, - } }); + +{ + /* + to game selection + */ +} diff --git a/app/onboarding/tips.tsx b/app/onboarding/tips.tsx new file mode 100644 index 0000000..7c9d887 --- /dev/null +++ b/app/onboarding/tips.tsx @@ -0,0 +1,31 @@ +import * as React from "react"; +import { Text, View, StyleSheet } from "react-native"; +import { Link, Stack, useSearchParams } from "expo-router"; + +const tips = (props: any) => { + const { email, password } = useSearchParams(); + const options = { + title: "Tips", + }; + return ( + + + + to game selection + + {email} + + ); +}; + +export default tips; + +const styles = StyleSheet.create({ + container: {}, + button: { + borderWidth: 1, + borderColor: "black", + padding: 15, + borderRadius: 5, + }, +}); diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..179e2899ca0096a6e743260ffbec099b4ae7a5c5 GIT binary patch literal 3584 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