From aeaf41a42a270350466198b5bdf9074e14eb94c4 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Tue, 14 Sep 2021 21:23:12 +0700 Subject: [PATCH 01/24] Plain Form --- src/components/Forms/PlainForm.tsx | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/components/Forms/PlainForm.tsx diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx new file mode 100644 index 0000000..cf64473 --- /dev/null +++ b/src/components/Forms/PlainForm.tsx @@ -0,0 +1,46 @@ +import React, { useState } from "react"; +import { View, StyleSheet, TextInput, Dimensions } from "react-native"; + +const { height, width } = Dimensions.get("screen"); + +type props = { + text: string; + setText: React.Dispatch>; + placeholder: string; +}; + +const PlainForm = ({ text, setText, placeholder }: props) => { + return ( + + setText(n)} + style={styles.textStyle} + placeholderTextColor="#8c8c8c" + /> + + ); +}; + +const styles = StyleSheet.create({ + container: { + width: "100%", + paddingVertical: 12, + paddingHorizontal: 16, + backgroundColor: "#f0f0f0", + borderRadius: 22.5, + borderStyle: "solid", + borderWidth: 1, + borderColor: "#dedede", + }, + textStyle: { + height: 21, + fontSize: 16, + fontWeight: "300", + textAlign: "left", + color: "#000000", + }, +}); + +export default PlainForm; -- GitLab From f7d25abd016af09ff927794828da648bbf4414e9 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Wed, 15 Sep 2021 10:54:30 +0700 Subject: [PATCH 02/24] Color Code Change --- src/components/Forms/PlainForm.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx index cf64473..940b140 100644 --- a/src/components/Forms/PlainForm.tsx +++ b/src/components/Forms/PlainForm.tsx @@ -1,5 +1,6 @@ import React, { useState } from "react"; import { View, StyleSheet, TextInput, Dimensions } from "react-native"; +import Colors from "../../constants/Colors"; const { height, width } = Dimensions.get("screen"); @@ -17,7 +18,7 @@ const PlainForm = ({ text, setText, placeholder }: props) => { value={text} onChangeText={(n: string): void => setText(n)} style={styles.textStyle} - placeholderTextColor="#8c8c8c" + placeholderTextColor={Colors.text.disabled} /> ); @@ -28,18 +29,18 @@ const styles = StyleSheet.create({ width: "100%", paddingVertical: 12, paddingHorizontal: 16, - backgroundColor: "#f0f0f0", + backgroundColor: Colors.text.bg, borderRadius: 22.5, borderStyle: "solid", borderWidth: 1, - borderColor: "#dedede", + borderColor: Colors.text.line, }, textStyle: { height: 21, fontSize: 16, fontWeight: "300", textAlign: "left", - color: "#000000", + color: Colors.text.white, }, }); -- GitLab From 7fb6d4af96bd2949acaca27592587f8fede74d60 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Wed, 15 Sep 2021 10:56:19 +0700 Subject: [PATCH 03/24] Color Code Addition --- src/constants/Colors.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/constants/Colors.ts b/src/constants/Colors.ts index 12dc2d4..0695420 100644 --- a/src/constants/Colors.ts +++ b/src/constants/Colors.ts @@ -55,7 +55,9 @@ export default { body: Blacks.BLACK_4, disabled: Blacks.BLACK_3, line: Blacks.BLACK_2, + bg: Blacks.BLACK_1, link: BLUE, + white: WHITE, }, icon: { tab: { -- GitLab From 2277c14b0125ccf8ec7006d95eabfab772d6d498 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Wed, 15 Sep 2021 17:03:01 +0700 Subject: [PATCH 04/24] Plain Form Completion --- src/components/Forms/PlainForm.tsx | 42 +++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx index 940b140..a222a5e 100644 --- a/src/components/Forms/PlainForm.tsx +++ b/src/components/Forms/PlainForm.tsx @@ -1,25 +1,38 @@ import React, { useState } from "react"; import { View, StyleSheet, TextInput, Dimensions } from "react-native"; import Colors from "../../constants/Colors"; - -const { height, width } = Dimensions.get("screen"); +import { Text } from "../Themed"; type props = { + formTitle: string; text: string; setText: React.Dispatch>; placeholder: string; }; -const PlainForm = ({ text, setText, placeholder }: props) => { +const PlainForm = ({ formTitle, text, setText, placeholder }: props) => { + const [isFocused, setIsFocused] = useState(false); return ( - setText(n)} - style={styles.textStyle} - placeholderTextColor={Colors.text.disabled} - /> + {formTitle} + + setIsFocused(true)} + onEndEditing={() => setIsFocused(false)} + placeholder={placeholder} + value={text} + onChangeText={(n: string): void => setText(n)} + style={styles.textStyle} + placeholderTextColor={Colors.text.disabled} + /> + ); }; @@ -27,9 +40,14 @@ const PlainForm = ({ text, setText, placeholder }: props) => { const styles = StyleSheet.create({ container: { width: "100%", + }, + formTitle: { + paddingBottom: 8, + color: Colors.text.subtitle, + }, + formContainer: { paddingVertical: 12, paddingHorizontal: 16, - backgroundColor: Colors.text.bg, borderRadius: 22.5, borderStyle: "solid", borderWidth: 1, @@ -40,7 +58,7 @@ const styles = StyleSheet.create({ fontSize: 16, fontWeight: "300", textAlign: "left", - color: Colors.text.white, + color: Colors.text.subtitle, }, }); -- GitLab From 33f46c57f128524a3ca1ad6c8156920cc5da0e86 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Thu, 16 Sep 2021 21:12:49 +0700 Subject: [PATCH 05/24] PlainForm Complete, No Test --- src/components/Forms/PlainForm.test.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/components/Forms/PlainForm.test.tsx diff --git a/src/components/Forms/PlainForm.test.tsx b/src/components/Forms/PlainForm.test.tsx new file mode 100644 index 0000000..e69de29 -- GitLab From 08a7b8ed2e3f4f57d373e5e809919cbc9852749c Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Thu, 16 Sep 2021 22:10:57 +0700 Subject: [PATCH 06/24] PlainForm Title Conditional Edit --- src/components/Forms/PlainForm.tsx | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx index a222a5e..0289a77 100644 --- a/src/components/Forms/PlainForm.tsx +++ b/src/components/Forms/PlainForm.tsx @@ -1,26 +1,38 @@ import React, { useState } from "react"; -import { View, StyleSheet, TextInput, Dimensions } from "react-native"; +import { View, StyleSheet, TextInput } from "react-native"; import Colors from "../../constants/Colors"; import { Text } from "../Themed"; type props = { - formTitle: string; + formTitle?: string; text: string; setText: React.Dispatch>; placeholder: string; }; -const PlainForm = ({ formTitle, text, setText, placeholder }: props) => { +const PlainForm = ({ formTitle = "", text, setText, placeholder }: props) => { const [isFocused, setIsFocused] = useState(false); return ( - {formTitle} + {formTitle.length > 0 && ( + {formTitle} + )} Date: Thu, 16 Sep 2021 23:15:45 +0700 Subject: [PATCH 07/24] Plain Form Disabled Addition --- src/components/Forms/PlainForm.tsx | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx index 0289a77..2175d32 100644 --- a/src/components/Forms/PlainForm.tsx +++ b/src/components/Forms/PlainForm.tsx @@ -8,10 +8,24 @@ type props = { text: string; setText: React.Dispatch>; placeholder: string; + disabled?: boolean; }; -const PlainForm = ({ formTitle = "", text, setText, placeholder }: props) => { +const PlainForm = ({ + formTitle = "", + text, + setText, + placeholder, + disabled = false, +}: props) => { const [isFocused, setIsFocused] = useState(false); + let backgroundColor: string; + if (disabled) { + backgroundColor = Colors.form.disabled.bg; + } else { + backgroundColor = + isFocused || text ? Colors.form.filled.bg : Colors.form.empty.bg; + } return ( {formTitle.length > 0 && ( @@ -20,8 +34,7 @@ const PlainForm = ({ formTitle = "", text, setText, placeholder }: props) => { { onChangeText={(n: string): void => setText(n)} style={styles.textStyle} placeholderTextColor={Colors.text.disabled} + editable={!disabled} /> -- GitLab From 4941cf53e2520df57afad0929019d1c1b64a7454 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sat, 18 Sep 2021 13:47:50 +0700 Subject: [PATCH 08/24] Spacer Component --- src/components/Spacer/Spacer.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/components/Spacer/Spacer.tsx diff --git a/src/components/Spacer/Spacer.tsx b/src/components/Spacer/Spacer.tsx new file mode 100644 index 0000000..45d28c9 --- /dev/null +++ b/src/components/Spacer/Spacer.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import { View } from "react-native"; + +type props = { + variant: "small" | "big"; +}; + +const Spacer = ({ variant }: props) => { + return ; +}; + +export default Spacer; -- GitLab From f20cd8ab31ecf486440233da0c014f15caf58c47 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sat, 18 Sep 2021 14:07:14 +0700 Subject: [PATCH 09/24] PlainForm Phone addition and IconForm completion --- src/components/Forms/PlainForm.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx index 2175d32..fe5dea0 100644 --- a/src/components/Forms/PlainForm.tsx +++ b/src/components/Forms/PlainForm.tsx @@ -9,6 +9,7 @@ type props = { setText: React.Dispatch>; placeholder: string; disabled?: boolean; + phone?: boolean; }; const PlainForm = ({ @@ -17,6 +18,7 @@ const PlainForm = ({ setText, placeholder, disabled = false, + phone = false, }: props) => { const [isFocused, setIsFocused] = useState(false); let backgroundColor: string; @@ -57,6 +59,7 @@ const PlainForm = ({ style={styles.textStyle} placeholderTextColor={Colors.text.disabled} editable={!disabled} + keyboardType={phone ? "phone-pad" : "default"} /> -- GitLab From 79761e09f100eb84d4fec44136e4b4d6d0eb518c Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sat, 18 Sep 2021 14:13:53 +0700 Subject: [PATCH 10/24] IconForm completion --- src/components/Forms/IconForm.tsx | 120 ++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/components/Forms/IconForm.tsx diff --git a/src/components/Forms/IconForm.tsx b/src/components/Forms/IconForm.tsx new file mode 100644 index 0000000..9ac822d --- /dev/null +++ b/src/components/Forms/IconForm.tsx @@ -0,0 +1,120 @@ +import React, { useState } from "react"; +import { View, StyleSheet, TextInput, TouchableOpacity } from "react-native"; +import Colors from "../../constants/Colors"; +import { Text } from "../Themed"; +import { MaterialIcons } from "@expo/vector-icons"; + +type props = { + formTitle?: string; + text: string; + setText: React.Dispatch>; + placeholder: string; + disabled?: boolean; + validator?: (a: string) => boolean; + iconType: React.ComponentProps["name"]; + password?: boolean; +}; + +const IconForm = ({ + formTitle = "", + text, + setText, + placeholder, + disabled = false, + iconType, + password = false, +}: props) => { + const [isFocused, setIsFocused] = useState(false); + const [showPass, setShowPass] = useState(password); + let backgroundColor: string; + if (disabled) { + backgroundColor = Colors.form.disabled.bg; + } else { + backgroundColor = + isFocused || text ? Colors.form.filled.bg : Colors.form.empty.bg; + } + return ( + + {formTitle.length > 0 && ( + {formTitle} + )} + + + setIsFocused(true)} + onEndEditing={() => setIsFocused(false)} + placeholder={placeholder} + value={text} + onChangeText={(n: string): void => setText(n)} + style={styles.textStyle} + placeholderTextColor={Colors.text.disabled} + editable={!disabled} + secureTextEntry={showPass} + /> + + password && setShowPass(!showPass)}> + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + width: "100%", + }, + formTitle: { + paddingBottom: 8, + fontSize: 14, + width: "100%", + height: 21, + color: Colors.text.subtitle, + }, + formContainer: { + flexDirection: "row", + paddingVertical: 12, + paddingLeft: 16, + paddingRight: 16, + borderRadius: 22.5, + borderStyle: "solid", + borderWidth: 1, + borderColor: Colors.form.empty.border, + justifyContent: "space-between", + }, + textStyle: { + height: 21, + fontSize: 14, + fontWeight: "300", + textAlign: "left", + color: Colors.text.subtitle, + paddingRight: 12, + }, + textContainer: { + flex: 1, + }, +}); + +export default IconForm; -- GitLab From 2317512615ba8d85a89029da089d799a3a51fe25 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sun, 19 Sep 2021 17:12:13 +0700 Subject: [PATCH 11/24] PlainForm Test --- src/components/__tests__/PlainForm.test.tsx | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/components/__tests__/PlainForm.test.tsx diff --git a/src/components/__tests__/PlainForm.test.tsx b/src/components/__tests__/PlainForm.test.tsx new file mode 100644 index 0000000..8fbbade --- /dev/null +++ b/src/components/__tests__/PlainForm.test.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import { cleanup, render } from "@testing-library/react-native"; +import PlainForm from "../Forms/PlainForm"; + +afterEach(cleanup); + +describe("Plain Form Test", () => { + it("Should detect a form", () => { + const { getByTestId } = render(); + const foundForm = getByTestId("PlainTest"); + expect(foundForm).not.toBeNull(); + }); + it("Should detect a title if given", () => { + const { getByTestId } = render( + + ); + const foundForm = getByTestId("TitleTest"); + expect(foundForm).not.toBeNull(); + }); + it("Should detect a form container", () => { + const { getByTestId } = render(); + const foundForm = getByTestId("FormContainerTest"); + expect(foundForm).not.toBeNull(); + }); + it("Should detect a text input", () => { + const { getByTestId } = render(); + const foundForm = getByTestId("TextInputTest"); + expect(foundForm).not.toBeNull(); + }); + it("Should not detect a form title", () => { + const { queryByTestId } = render(); + const foundForm = queryByTestId("TitleTest"); + expect(foundForm).toBeNull(); + }); +}); -- GitLab From d503564c907d1f698b4eaeb0bd82d9d17577f503 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sun, 19 Sep 2021 17:50:05 +0700 Subject: [PATCH 12/24] Plain Form Test --- src/components/__tests__/PlainForm.test.tsx | 46 ++++++++++++--------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/components/__tests__/PlainForm.test.tsx b/src/components/__tests__/PlainForm.test.tsx index 8fbbade..29424a2 100644 --- a/src/components/__tests__/PlainForm.test.tsx +++ b/src/components/__tests__/PlainForm.test.tsx @@ -1,35 +1,43 @@ -import React from "react"; -import { cleanup, render } from "@testing-library/react-native"; +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import React, { useState } from "react"; +import { cleanup, render, fireEvent } from "@testing-library/react-native"; import PlainForm from "../Forms/PlainForm"; afterEach(cleanup); +const PlainFormWrapper = (props) => { + const [text, setText] = useState("Hello"); + return ; +}; + describe("Plain Form Test", () => { it("Should detect a form", () => { - const { getByTestId } = render(); - const foundForm = getByTestId("PlainTest"); - expect(foundForm).not.toBeNull(); + const { getByTestId } = render(); + expect(getByTestId("Plain")).not.toBeNull(); }); it("Should detect a title if given", () => { - const { getByTestId } = render( - - ); - const foundForm = getByTestId("TitleTest"); - expect(foundForm).not.toBeNull(); + const { getByTestId } = render(); + expect(getByTestId("Title")).not.toBeNull(); }); it("Should detect a form container", () => { - const { getByTestId } = render(); - const foundForm = getByTestId("FormContainerTest"); - expect(foundForm).not.toBeNull(); + const { getByTestId } = render(); + expect(getByTestId("Container")).not.toBeNull(); }); it("Should detect a text input", () => { - const { getByTestId } = render(); - const foundForm = getByTestId("TextInputTest"); - expect(foundForm).not.toBeNull(); + const { getByTestId } = render(); + expect(getByTestId("Input")).not.toBeNull(); + }); + it("Should not detect a form title", () => { + const { queryByTestId } = render(); + expect(queryByTestId("TitleTest")).toBeNull(); }); it("Should not detect a form title", () => { - const { queryByTestId } = render(); - const foundForm = queryByTestId("TitleTest"); - expect(foundForm).toBeNull(); + const { queryByTestId } = render(); + expect(queryByTestId("TitleTest")).toBeNull(); + }); + it("Should detect a send form text", () => { + const { getByTestId } = render(); + fireEvent.changeText(getByTestId("Input"), "Hello"); + expect(getByTestId("Input").props.value).toEqual("Hello"); }); }); -- GitLab From d8271764f25cd546c432e7515324cd8d5e7e1e7f Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sun, 19 Sep 2021 22:49:48 +0700 Subject: [PATCH 13/24] Height Fix and test --- src/components/Forms/IconForm.tsx | 15 ++++++++++++--- src/components/Forms/PlainForm.tsx | 20 +++++++++++++++----- src/components/__tests__/PlainForm.test.tsx | 10 +++++++--- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/components/Forms/IconForm.tsx b/src/components/Forms/IconForm.tsx index 9ac822d..54228fa 100644 --- a/src/components/Forms/IconForm.tsx +++ b/src/components/Forms/IconForm.tsx @@ -36,7 +36,11 @@ const IconForm = ({ return ( {formTitle.length > 0 && ( - {formTitle} + + + {formTitle} + + )} + {formTitle.length > 0 && ( - {formTitle} + + + {formTitle} + + )} setIsFocused(true)} @@ -60,6 +65,7 @@ const PlainForm = ({ placeholderTextColor={Colors.text.disabled} editable={!disabled} keyboardType={phone ? "phone-pad" : "default"} + testID="Input" /> @@ -70,11 +76,14 @@ const styles = StyleSheet.create({ container: { width: "100%", }, - formTitle: { + titleContainer: { paddingBottom: 8, + }, + formTitle: { + paddingTop: 2, + paddingBottom: 2, fontSize: 14, width: "100%", - height: 21, color: Colors.text.subtitle, }, formContainer: { @@ -86,7 +95,8 @@ const styles = StyleSheet.create({ borderColor: Colors.form.empty.border, }, textStyle: { - height: 21, + paddingTop: 2, + paddingBottom: 2, fontSize: 14, fontWeight: "300", textAlign: "left", diff --git a/src/components/__tests__/PlainForm.test.tsx b/src/components/__tests__/PlainForm.test.tsx index 29424a2..dd1c73b 100644 --- a/src/components/__tests__/PlainForm.test.tsx +++ b/src/components/__tests__/PlainForm.test.tsx @@ -15,6 +15,10 @@ describe("Plain Form Test", () => { const { getByTestId } = render(); expect(getByTestId("Plain")).not.toBeNull(); }); + it("Should detect a title container", () => { + const { getByTestId } = render(); + expect(getByTestId("TitleContainer")).not.toBeNull(); + }); it("Should detect a title if given", () => { const { getByTestId } = render(); expect(getByTestId("Title")).not.toBeNull(); @@ -27,13 +31,13 @@ describe("Plain Form Test", () => { const { getByTestId } = render(); expect(getByTestId("Input")).not.toBeNull(); }); - it("Should not detect a form title", () => { + it("Should not detect a container title", () => { const { queryByTestId } = render(); - expect(queryByTestId("TitleTest")).toBeNull(); + expect(queryByTestId("TitleContainer")).toBeNull(); }); it("Should not detect a form title", () => { const { queryByTestId } = render(); - expect(queryByTestId("TitleTest")).toBeNull(); + expect(queryByTestId("Title")).toBeNull(); }); it("Should detect a send form text", () => { const { getByTestId } = render(); -- GitLab From e9a3bde10aed12bf62df188941195f61fc716031 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Mon, 20 Sep 2021 10:17:31 +0700 Subject: [PATCH 14/24] IconForm Icon Position Fix to Center, PlainForm Text Height Fix, DropdownForm intialization --- src/components/Forms/DropdownForm.tsx | 6 ++++++ src/components/Forms/IconForm.tsx | 7 ++----- src/components/Forms/PlainForm.test.tsx | 0 src/components/Forms/PlainForm.tsx | 6 +----- 4 files changed, 9 insertions(+), 10 deletions(-) create mode 100644 src/components/Forms/DropdownForm.tsx delete mode 100644 src/components/Forms/PlainForm.test.tsx diff --git a/src/components/Forms/DropdownForm.tsx b/src/components/Forms/DropdownForm.tsx new file mode 100644 index 0000000..c1516d3 --- /dev/null +++ b/src/components/Forms/DropdownForm.tsx @@ -0,0 +1,6 @@ +import React, { useState } from "react"; +import { View, StyleSheet, TextInput, TouchableOpacity } from "react-native"; +import Colors from "../../constants/Colors"; +import { Text } from "../Themed"; +import { MaterialIcons } from "@expo/vector-icons"; +import DropDownPicker from "react-native-dropdown-picker"; diff --git a/src/components/Forms/IconForm.tsx b/src/components/Forms/IconForm.tsx index 54228fa..7580045 100644 --- a/src/components/Forms/IconForm.tsx +++ b/src/components/Forms/IconForm.tsx @@ -94,8 +94,6 @@ const styles = StyleSheet.create({ paddingBottom: 8, }, formTitle: { - paddingTop: 2, - paddingBottom: 2, fontSize: 14, width: "100%", height: 21, @@ -106,15 +104,14 @@ const styles = StyleSheet.create({ paddingVertical: 12, paddingLeft: 16, paddingRight: 16, - borderRadius: 22.5, + borderRadius: 100, borderStyle: "solid", borderWidth: 1, borderColor: Colors.form.empty.border, justifyContent: "space-between", + alignItems: "center", }, textStyle: { - paddingTop: 2, - paddingBottom: 2, fontSize: 14, fontWeight: "300", textAlign: "left", diff --git a/src/components/Forms/PlainForm.test.tsx b/src/components/Forms/PlainForm.test.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx index 4eb8e30..95ab13e 100644 --- a/src/components/Forms/PlainForm.tsx +++ b/src/components/Forms/PlainForm.tsx @@ -80,8 +80,6 @@ const styles = StyleSheet.create({ paddingBottom: 8, }, formTitle: { - paddingTop: 2, - paddingBottom: 2, fontSize: 14, width: "100%", color: Colors.text.subtitle, @@ -89,14 +87,12 @@ const styles = StyleSheet.create({ formContainer: { paddingVertical: 12, paddingHorizontal: 16, - borderRadius: 22.5, + borderRadius: 100, borderStyle: "solid", borderWidth: 1, borderColor: Colors.form.empty.border, }, textStyle: { - paddingTop: 2, - paddingBottom: 2, fontSize: 14, fontWeight: "300", textAlign: "left", -- GitLab From e05f0d7da86ed3523b8593659ee071ae29a580ca Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Mon, 20 Sep 2021 10:36:31 +0700 Subject: [PATCH 15/24] Spacer props edit and addition --- src/components/Spacer/Spacer.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/Spacer/Spacer.tsx b/src/components/Spacer/Spacer.tsx index 45d28c9..6021228 100644 --- a/src/components/Spacer/Spacer.tsx +++ b/src/components/Spacer/Spacer.tsx @@ -2,11 +2,21 @@ import React from "react"; import { View } from "react-native"; type props = { - variant: "small" | "big"; + variant: "s" | "m" | "l" | "xl"; }; const Spacer = ({ variant }: props) => { - return ; + let height: number; + if (variant == "s") { + height = 4; + } else if (variant == "m") { + height = 8; + } else if (variant == "l") { + height = 16; + } else if (variant == "xl") { + height = 24; + } + return ; }; export default Spacer; -- GitLab From aeba569c9c452cd56833168d5cbdd8db9a6ec899 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Mon, 20 Sep 2021 11:09:50 +0700 Subject: [PATCH 16/24] IconForm & Spacer tests --- src/components/Forms/IconForm.tsx | 12 +++-- src/components/__tests__/IconForm.test.tsx | 63 ++++++++++++++++++++++ src/components/__tests__/Spacer.test.tsx | 17 ++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/components/__tests__/IconForm.test.tsx create mode 100644 src/components/__tests__/Spacer.test.tsx diff --git a/src/components/Forms/IconForm.tsx b/src/components/Forms/IconForm.tsx index 7580045..e2432e3 100644 --- a/src/components/Forms/IconForm.tsx +++ b/src/components/Forms/IconForm.tsx @@ -34,7 +34,7 @@ const IconForm = ({ isFocused || text ? Colors.form.filled.bg : Colors.form.empty.bg; } return ( - + {formTitle.length > 0 && ( @@ -58,8 +58,9 @@ const IconForm = ({ shadowOpacity: isFocused ? 1 : 0, shadowRadius: isFocused ? 8 : 0, }} + testID="Container" > - + setIsFocused(true)} onEndEditing={() => setIsFocused(false)} @@ -70,15 +71,20 @@ const IconForm = ({ placeholderTextColor={Colors.text.disabled} editable={!disabled} secureTextEntry={showPass} + testID="Input" /> - password && setShowPass(!showPass)}> + password && setShowPass(!showPass)} + testID="Touchable" + > diff --git a/src/components/__tests__/IconForm.test.tsx b/src/components/__tests__/IconForm.test.tsx new file mode 100644 index 0000000..cf045ed --- /dev/null +++ b/src/components/__tests__/IconForm.test.tsx @@ -0,0 +1,63 @@ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import React, { useState } from "react"; +import { cleanup, render, fireEvent } from "@testing-library/react-native"; +import IconForm from "../Forms/IconForm"; + +afterEach(cleanup); + +const IconFormWrapper = (props) => { + const [text, setText] = useState("Hello"); + return ; +}; + +describe("Icon Form Test", () => { + it("Should detect a form", () => { + const { getByTestId } = render(); + expect(getByTestId("Icon")).not.toBeNull(); + }); + it("Should detect a title container", () => { + const { getByTestId } = render( + + ); + expect(getByTestId("TitleContainer")).not.toBeNull(); + }); + it("Should detect a title if given", () => { + const { getByTestId } = render( + + ); + expect(getByTestId("Title")).not.toBeNull(); + }); + it("Should detect a form container", () => { + const { getByTestId } = render(); + expect(getByTestId("Container")).not.toBeNull(); + }); + it("Should detect a container for input and icon", () => { + const { getByTestId } = render(); + expect(getByTestId("TextIcon")).not.toBeNull(); + }); + it("Should detect a text input", () => { + const { getByTestId } = render(); + expect(getByTestId("Input")).not.toBeNull(); + }); + it("Should detect a touchable", () => { + const { getByTestId } = render(); + expect(getByTestId("Touchable")).not.toBeNull(); + }); + it("Should detect a MaterialIcon", () => { + const { getByTestId } = render(); + expect(getByTestId("MaterialIcon")).not.toBeNull(); + }); + it("Should not detect a container title", () => { + const { queryByTestId } = render(); + expect(queryByTestId("TitleContainer")).toBeNull(); + }); + it("Should not detect a form title", () => { + const { queryByTestId } = render(); + expect(queryByTestId("Title")).toBeNull(); + }); + it("Should detect a send form text", () => { + const { getByTestId } = render(); + fireEvent.changeText(getByTestId("Input"), "Hello"); + expect(getByTestId("Input").props.value).toEqual("Hello"); + }); +}); diff --git a/src/components/__tests__/Spacer.test.tsx b/src/components/__tests__/Spacer.test.tsx new file mode 100644 index 0000000..a5a17b3 --- /dev/null +++ b/src/components/__tests__/Spacer.test.tsx @@ -0,0 +1,17 @@ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import React from "react"; +import { cleanup, render } from "@testing-library/react-native"; +import Spacer from "../Spacer/Spacer"; + +afterEach(cleanup); + +const SpacerWrapper = () => { + return ; +}; + +describe("Spacer Test", () => { + it("Should detect a spacer", () => { + const { getByTestId } = render(); + expect(getByTestId("Spacer")).not.toBeNull(); + }); +}); -- GitLab From b29e260bfb03d107427f4b675642137174b15188 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Mon, 20 Sep 2021 11:10:18 +0700 Subject: [PATCH 17/24] IconForm & Spacer tests --- src/components/Spacer/Spacer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Spacer/Spacer.tsx b/src/components/Spacer/Spacer.tsx index 6021228..9645d37 100644 --- a/src/components/Spacer/Spacer.tsx +++ b/src/components/Spacer/Spacer.tsx @@ -16,7 +16,7 @@ const Spacer = ({ variant }: props) => { } else if (variant == "xl") { height = 24; } - return ; + return ; }; export default Spacer; -- GitLab From ae7fc642f6aab09aa054a9e2100f9e766dd38799 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Mon, 20 Sep 2021 11:18:02 +0700 Subject: [PATCH 18/24] Delete repition for IconType props value --- src/components/__tests__/IconForm.test.tsx | 28 ++++++++++------------ 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/components/__tests__/IconForm.test.tsx b/src/components/__tests__/IconForm.test.tsx index cf045ed..66fd229 100644 --- a/src/components/__tests__/IconForm.test.tsx +++ b/src/components/__tests__/IconForm.test.tsx @@ -7,52 +7,50 @@ afterEach(cleanup); const IconFormWrapper = (props) => { const [text, setText] = useState("Hello"); - return ; + return ( + + ); }; describe("Icon Form Test", () => { it("Should detect a form", () => { - const { getByTestId } = render(); + const { getByTestId } = render(); expect(getByTestId("Icon")).not.toBeNull(); }); it("Should detect a title container", () => { - const { getByTestId } = render( - - ); + const { getByTestId } = render(); expect(getByTestId("TitleContainer")).not.toBeNull(); }); it("Should detect a title if given", () => { - const { getByTestId } = render( - - ); + const { getByTestId } = render(); expect(getByTestId("Title")).not.toBeNull(); }); it("Should detect a form container", () => { - const { getByTestId } = render(); + const { getByTestId } = render(); expect(getByTestId("Container")).not.toBeNull(); }); it("Should detect a container for input and icon", () => { - const { getByTestId } = render(); + const { getByTestId } = render(); expect(getByTestId("TextIcon")).not.toBeNull(); }); it("Should detect a text input", () => { - const { getByTestId } = render(); + const { getByTestId } = render(); expect(getByTestId("Input")).not.toBeNull(); }); it("Should detect a touchable", () => { - const { getByTestId } = render(); + const { getByTestId } = render(); expect(getByTestId("Touchable")).not.toBeNull(); }); it("Should detect a MaterialIcon", () => { - const { getByTestId } = render(); + const { getByTestId } = render(); expect(getByTestId("MaterialIcon")).not.toBeNull(); }); it("Should not detect a container title", () => { - const { queryByTestId } = render(); + const { queryByTestId } = render(); expect(queryByTestId("TitleContainer")).toBeNull(); }); it("Should not detect a form title", () => { - const { queryByTestId } = render(); + const { queryByTestId } = render(); expect(queryByTestId("Title")).toBeNull(); }); it("Should detect a send form text", () => { -- GitLab From a76081103516d4aae6a2ded28d3134581f9b708a Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Mon, 20 Sep 2021 12:53:41 +0700 Subject: [PATCH 19/24] New Package Installation --- package.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package.json b/package.json index 0566f4b..3fd73e5 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "react": "16.13.1", "react-dom": "16.13.1", "react-native": "https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz", + "react-native-dropdown-picker": "^5.1.27", "react-native-gesture-handler": "~1.10.2", "react-native-reanimated": "~2.2.0", "react-native-safe-area-context": "3.2.0", @@ -38,6 +39,9 @@ }, "devDependencies": { "@babel/core": "^7.9.0", + "@testing-library/jest-native": "^4.0.2", + "@testing-library/react-native": "^7.2.0", + "@types/jest": "^27.0.1", "@types/react": "~16.9.35", "@types/react-native": "~0.63.2", "@typescript-eslint/eslint-plugin": "^4.31.0", @@ -47,9 +51,11 @@ "eslint-plugin-react": "^7.25.1", "eslint-plugin-react-hooks": "^4.2.0", "husky": "^7.0.2", + "jest": "^27.2.0", "jest-expo": "~41.0.0-beta.0", "lint-staged": "^11.1.2", "prettier": "^2.4.0", + "react-test-renderer": "^17.0.2", "typescript": "~4.0.0" }, "private": true, -- GitLab From ef4038b49e33320a53c92e914ba3379fbe17062c Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Thu, 23 Sep 2021 11:27:21 +0700 Subject: [PATCH 20/24] Feat: Added Dropdown Form --- src/components/Forms/DropdownForm.tsx | 108 +++++++++++++++++- .../__tests__/Forms/IconForm.test.tsx | 62 ++++++++++ .../__tests__/Forms/PlainForm.test.tsx | 48 ++++++++ .../__tests__/Forms/Spacer.test.tsx | 18 +++ 4 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 src/components/__tests__/Forms/IconForm.test.tsx create mode 100644 src/components/__tests__/Forms/PlainForm.test.tsx create mode 100644 src/components/__tests__/Forms/Spacer.test.tsx diff --git a/src/components/Forms/DropdownForm.tsx b/src/components/Forms/DropdownForm.tsx index a94a2b6..4eb7135 100644 --- a/src/components/Forms/DropdownForm.tsx +++ b/src/components/Forms/DropdownForm.tsx @@ -1,13 +1,41 @@ import React, { useState } from "react"; +import { StyleSheet } from "react-native"; +import { MaterialIcons } from "@expo/vector-icons"; +import Colors from "../../constants/Colors"; import DropDownPicker from "react-native-dropdown-picker"; -const DropdownForm = () => { +type props = { + formPlaceholder: string; + blocked?: boolean; + searchPlaceholder: string; +}; + +const DropdownForm = ({ + formPlaceholder, + blocked = false, + searchPlaceholder, +}: props) => { const [open, setOpen] = useState(false); const [value, setValue] = useState(); const [items, setItems] = useState([ - { label: "Apple", value: "apple" }, - { label: "Banana", value: "banana" }, + { + label: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + value: "Agrikultur", + }, + { label: "Konstruksi", value: "Konstruksi" }, + { label: "Tambang", value: "Tambang" }, + { label: "Listrik", value: "Listrik" }, + { label: "Bahan Baku", value: "Bahan Baku" }, + { label: "Batu Bara", value: "Batu Bara" }, ]); + let backgroundColor: string; + if (blocked) { + backgroundColor = Colors.form.disabled.bg; + } else if (open) { + backgroundColor = Colors.form.filled.bg; + } else { + backgroundColor = value ? Colors.form.filled.bg : Colors.form.empty.bg; + } return ( { setOpen={setOpen} setValue={setValue} setItems={setItems} + placeholder={formPlaceholder} + placeholderStyle={styles.Placeholder} + showArrowIcon + showTickIcon + ArrowUpIconComponent={() => ( + + )} + ArrowDownIconComponent={() => ( + + )} + TickIconComponent={() => ( + + )} + searchable + searchPlaceholder={searchPlaceholder} + searchContainerStyle={styles.SearchContainer} + searchTextInputStyle={styles.SearchInput} + dropDownDirection="BOTTOM" + dropDownContainerStyle={styles.Container} + style={{ + ...styles.Main, + backgroundColor: backgroundColor, + }} + listItemLabelStyle={styles.ItemLabel} + maxHeight={300} + textStyle={styles.filled} + disabled={blocked} /> ); }; +const styles = StyleSheet.create({ + ItemLabel: { + color: Colors.text.subtitle, + paddingRight: 16, + }, + Main: { + borderRadius: 25, + borderColor: Colors.form.filled.border, + }, + Container: { + borderRadius: 25, + borderColor: Colors.form.filled.border, + zIndex: 1000, + }, + SearchInput: { + color: Colors.text.subtitle, + paddingVertical: 12, + paddingLeft: 16, + fontSize: 14, + borderColor: Colors.form.filled.border, + borderRadius: 50, + zIndex: 1, + }, + SearchContainer: { + paddingHorizontal: 12, + paddingVertical: 16, + }, + Placeholder: { + color: Colors.text.disabled, + paddingLeft: 8, + }, + filled: { + paddingLeft: 8, + fontSize: 14, + color: Colors.text.subtitle, + paddingRight: 8, + }, +}); + export default DropdownForm; diff --git a/src/components/__tests__/Forms/IconForm.test.tsx b/src/components/__tests__/Forms/IconForm.test.tsx new file mode 100644 index 0000000..797588f --- /dev/null +++ b/src/components/__tests__/Forms/IconForm.test.tsx @@ -0,0 +1,62 @@ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import React, { useState } from "react"; +import { cleanup, render, fireEvent } from "@testing-library/react-native"; +import IconForm from "../../Forms/IconForm"; + +afterEach(cleanup); + +const IconFormWrapper = (props) => { + const [text, setText] = useState("Hello"); + return ( + + ); +}; + +describe("Icon Form Test", () => { + it("Should detect a form", () => { + const { getByTestId } = render(); + expect(getByTestId("Icon")).not.toBeNull(); + }); + it("Should detect a title container", () => { + const { getByTestId } = render(); + expect(getByTestId("TitleContainer")).not.toBeNull(); + }); + it("Should detect a title if given", () => { + const { getByTestId } = render(); + expect(getByTestId("Title")).not.toBeNull(); + }); + it("Should detect a form container", () => { + const { getByTestId } = render(); + expect(getByTestId("Container")).not.toBeNull(); + }); + it("Should detect a container for input and icon", () => { + const { getByTestId } = render(); + expect(getByTestId("TextIcon")).not.toBeNull(); + }); + it("Should detect a text input", () => { + const { getByTestId } = render(); + expect(getByTestId("Input")).not.toBeNull(); + }); + it("Should detect a touchable", () => { + const { getByTestId } = render(); + expect(getByTestId("Touchable")).not.toBeNull(); + }); + it("Should detect a MaterialIcon", () => { + const { getByTestId } = render(); + expect(getByTestId("MaterialIcon")).not.toBeNull(); + }); + it("Should not detect a container title", () => { + const { queryByTestId } = render(); + expect(queryByTestId("TitleContainer")).toBeNull(); + }); + it("Should not detect a form title", () => { + const { queryByTestId } = render(); + expect(queryByTestId("Title")).toBeNull(); + }); + it("Should detect a send form text", () => { + const { getByTestId } = render(); + fireEvent.changeText(getByTestId("Input"), "Hello"); + expect(getByTestId("Input").props.value).toEqual("Hello"); + }); +}); diff --git a/src/components/__tests__/Forms/PlainForm.test.tsx b/src/components/__tests__/Forms/PlainForm.test.tsx new file mode 100644 index 0000000..646606d --- /dev/null +++ b/src/components/__tests__/Forms/PlainForm.test.tsx @@ -0,0 +1,48 @@ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import React, { useState } from "react"; +import { cleanup, render, fireEvent } from "@testing-library/react-native"; +import PlainForm from "../../Forms/PlainForm"; + +afterEach(cleanup); + +const PlainFormWrapper = (props) => { + const [text, setText] = useState("Hello"); + return ; +}; + +describe("Plain Form Test", () => { + it("Should detect a form", () => { + const { getByTestId } = render(); + expect(getByTestId("Plain")).not.toBeNull(); + }); + it("Should detect a title container", () => { + const { getByTestId } = render(); + expect(getByTestId("TitleContainer")).not.toBeNull(); + }); + it("Should detect a title if given", () => { + const { getByTestId } = render(); + expect(getByTestId("Title")).not.toBeNull(); + }); + it("Should detect a form container", () => { + const { getByTestId } = render(); + expect(getByTestId("Container")).not.toBeNull(); + }); + it("Should detect a text input", () => { + const { getByTestId } = render(); + expect(getByTestId("Input")).not.toBeNull(); + }); + it("Should not detect a container title", () => { + const { queryByTestId } = render(); + expect(queryByTestId("TitleContainer")).toBeNull(); + }); + it("Should not detect a form title", () => { + const { queryByTestId } = render(); + expect(queryByTestId("Title")).toBeNull(); + }); + it("Should detect a send form text", () => { + const { getByTestId } = render(); + fireEvent.changeText(getByTestId("Input"), "Hello"); + expect(getByTestId("Input").props.value).toEqual("Hello"); + }); +}); diff --git a/src/components/__tests__/Forms/Spacer.test.tsx b/src/components/__tests__/Forms/Spacer.test.tsx new file mode 100644 index 0000000..2ec9880 --- /dev/null +++ b/src/components/__tests__/Forms/Spacer.test.tsx @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import React from "react"; +import { cleanup, render } from "@testing-library/react-native"; +import Spacer from "../../Spacer/Spacer"; + +afterEach(cleanup); + +const SpacerWrapper = () => { + return ; +}; + +describe("Spacer Test", () => { + it("Should detect a spacer", () => { + const { getByTestId } = render(); + expect(getByTestId("Spacer")).not.toBeNull(); + }); +}); -- GitLab From c4a3776c5346e83ef23159b176644f262a846a00 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Thu, 23 Sep 2021 13:21:40 +0700 Subject: [PATCH 21/24] Feat: Implented editable content for DropdownForm --- src/components/Forms/DropdownForm.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/components/Forms/DropdownForm.tsx b/src/components/Forms/DropdownForm.tsx index 4eb7135..ab3fbf8 100644 --- a/src/components/Forms/DropdownForm.tsx +++ b/src/components/Forms/DropdownForm.tsx @@ -8,26 +8,24 @@ type props = { formPlaceholder: string; blocked?: boolean; searchPlaceholder: string; + value: string; + setValue: React.Dispatch>; + items: { label: string; value: string }[]; + setItems: React.Dispatch< + React.SetStateAction<{ label: string; value: string }[]> + >; }; const DropdownForm = ({ formPlaceholder, blocked = false, searchPlaceholder, + value, + setValue, + items, + setItems, }: props) => { const [open, setOpen] = useState(false); - const [value, setValue] = useState(); - const [items, setItems] = useState([ - { - label: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - value: "Agrikultur", - }, - { label: "Konstruksi", value: "Konstruksi" }, - { label: "Tambang", value: "Tambang" }, - { label: "Listrik", value: "Listrik" }, - { label: "Bahan Baku", value: "Bahan Baku" }, - { label: "Batu Bara", value: "Batu Bara" }, - ]); let backgroundColor: string; if (blocked) { backgroundColor = Colors.form.disabled.bg; -- GitLab From bb6f724972b0a9f58d768ecf4daf93903e4a9bbd Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Thu, 23 Sep 2021 14:38:41 +0700 Subject: [PATCH 22/24] Chore: Button Shadow Fix --- src/components/button/MainButton.tsx | 5 ----- src/components/button/SmallButton.tsx | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/components/button/MainButton.tsx b/src/components/button/MainButton.tsx index fdab4d2..a33afa0 100644 --- a/src/components/button/MainButton.tsx +++ b/src/components/button/MainButton.tsx @@ -50,11 +50,6 @@ const styles = StyleSheet.create({ paddingRight: 16, borderRadius: 24, width: "100%", - shadowColor: "rgba(7, 145, 249, 0.12)", - shadowOpacity: 1, - elevation: 8, - shadowRadius: 8, - shadowOffset: { width: 0, height: 4 }, borderWidth: 1, }, text: { diff --git a/src/components/button/SmallButton.tsx b/src/components/button/SmallButton.tsx index 86e0259..667e088 100644 --- a/src/components/button/SmallButton.tsx +++ b/src/components/button/SmallButton.tsx @@ -44,12 +44,7 @@ const styles = StyleSheet.create({ justifyContent: "center", paddingLeft: 12, paddingRight: 12, - shadowColor: "rgba(7, 14, 249, 0.12)", - shadowOpacity: 1, - elevation: 8, - shadowRadius: 8, alignSelf: "flex-start", - shadowOffset: { width: 0, height: 4 }, }, text: { fontSize: 14, -- GitLab From e2a0a4eec5ebe40326fa86accadc040035b2adc5 Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sat, 25 Sep 2021 17:19:48 +0700 Subject: [PATCH 23/24] Chore: Navigation Fix --- src/navigation/AuthStackNavigator.tsx | 23 +++++--- src/navigation/RootNavigator.tsx | 8 +-- src/screens/auth/ForgetPasswordScreen.tsx | 21 ------- src/screens/auth/ForgotPasswordDone.tsx | 56 +++++++++++++++++++ src/screens/auth/ForgotPasswordInput.tsx | 68 +++++++++++++++++++++++ src/screens/auth/LoginScreen.tsx | 15 +++-- src/screens/auth/OnBoardingScreen.tsx | 9 ++- src/types/navigation/AuthStack.ts | 3 +- src/types/navigation/RootStack.ts | 5 +- 9 files changed, 165 insertions(+), 43 deletions(-) delete mode 100644 src/screens/auth/ForgetPasswordScreen.tsx create mode 100644 src/screens/auth/ForgotPasswordDone.tsx create mode 100644 src/screens/auth/ForgotPasswordInput.tsx diff --git a/src/navigation/AuthStackNavigator.tsx b/src/navigation/AuthStackNavigator.tsx index 46f528d..6f8bcfe 100644 --- a/src/navigation/AuthStackNavigator.tsx +++ b/src/navigation/AuthStackNavigator.tsx @@ -4,21 +4,23 @@ import LoginScreen from "../screens/auth/LoginScreen"; import { AuthStackParamList } from "../types/navigation"; import RegisterGoogleFacebookScreen from "../screens/auth/RegisterGoogleFacebookScreen"; import RegisterScreen from "../screens/auth/RegisterScreen"; -import ForgetPasswordScreen from "../screens/auth/ForgetPasswordScreen"; import OnBoardingScreen from "../screens/auth/OnBoardingScreen"; import LandingScreen from "../screens/auth/LandingScreen"; +import ForgotPasswordInput from "../screens/auth/ForgotPasswordDone"; +import ForgotPasswordDone from "../screens/auth/ForgotPasswordDone"; + const AuthStack = createNativeStackNavigator(); const AuthStackNavigator = () => { return ( { options={{ title: "Register" }} /> + ); diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index 221ec51..68bd7eb 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -15,13 +15,13 @@ const RootNavigator = () => { return ( diff --git a/src/screens/auth/ForgetPasswordScreen.tsx b/src/screens/auth/ForgetPasswordScreen.tsx deleted file mode 100644 index a846191..0000000 --- a/src/screens/auth/ForgetPasswordScreen.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from "react"; -import { StyleSheet } from "react-native"; -import { Text, View } from "../../components/Themed"; -import { RootTabScreenProps } from "../../types/navigation"; -import { useNavigation } from "@react-navigation/core"; -const ForgetPasswordScreen = ({ navigation }: RootTabScreenProps<"TabOne">) => { - const nav = useNavigation(); - return ( - - Forget Password Screen - - ); -}; -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: "center", - justifyContent: "center", - }, -}); -export default ForgetPasswordScreen; diff --git a/src/screens/auth/ForgotPasswordDone.tsx b/src/screens/auth/ForgotPasswordDone.tsx new file mode 100644 index 0000000..35a5f29 --- /dev/null +++ b/src/screens/auth/ForgotPasswordDone.tsx @@ -0,0 +1,56 @@ +import { useNavigation } from "@react-navigation/core"; +import React from "react"; +import { StyleSheet, View, Text } from "react-native"; +import Colors from "../../constants/Colors"; +import { RootTabScreenProps } from "../../types/navigation"; +import Spacer from "../../components/Spacer/Spacer"; +import { MaterialIcons } from "@expo/vector-icons"; +import MainButton from "../../components/button/MainButton"; + +export default function ForgotPasswordDone({ + navigation, +}: RootTabScreenProps<"TabOne">) { + const nav = useNavigation(); + return ( + + + + + Lupa Password + + + + + Kami sudah mengirimkan email berisi link untuk mereset password, + silahkan cek email anda + + + + nav.navigate("Auth", { screen: "Login" })} + /> + + ); +} + +const styles = StyleSheet.create({ + MainContainer: { + padding: 24, + backgroundColor: Colors.text.white, + }, + TextContainer: { + width: "100%", + }, + Title: { + fontSize: 32, + fontWeight: "500", + color: Colors.text.title, + }, + Subtitle: { + fontSize: 20, + fontWeight: "300", + color: Colors.text.subtitle, + }, +}); diff --git a/src/screens/auth/ForgotPasswordInput.tsx b/src/screens/auth/ForgotPasswordInput.tsx new file mode 100644 index 0000000..67d19c3 --- /dev/null +++ b/src/screens/auth/ForgotPasswordInput.tsx @@ -0,0 +1,68 @@ +import { useNavigation } from "@react-navigation/core"; +import React from "react"; +import { useState } from "react"; +import { StyleSheet, View, Text } from "react-native"; +import Colors from "../../constants/Colors"; +import { RootTabScreenProps } from "../../types/navigation"; +import PlainForm from "../../components/Forms/PlainForm"; +import Spacer from "../../components/Spacer/Spacer"; +import { MaterialIcons } from "@expo/vector-icons"; +import MainButton from "../../components/button/MainButton"; +import firebase from "firebase"; + +export default function ForgotPasswordInput({ + navigation, +}: RootTabScreenProps<"TabOne">) { + const [email, setEmail] = useState(""); + const nav = useNavigation(); + return ( + + + + + Lupa Password + + + + + Silahkan masukkan email anda untuk mereset password + + + + + + { + firebase.auth().sendPasswordResetEmail(email); + }} + /> + + ); +} + +const styles = StyleSheet.create({ + MainContainer: { + padding: 24, + backgroundColor: Colors.text.white, + }, + TextContainer: { + width: "100%", + }, + Title: { + fontSize: 32, + fontWeight: "500", + color: Colors.text.title, + }, + Subtitle: { + fontSize: 20, + fontWeight: "300", + color: Colors.text.subtitle, + }, +}); diff --git a/src/screens/auth/LoginScreen.tsx b/src/screens/auth/LoginScreen.tsx index b93a401..764b190 100644 --- a/src/screens/auth/LoginScreen.tsx +++ b/src/screens/auth/LoginScreen.tsx @@ -45,14 +45,20 @@ const LoginScreen = ({ navigation }: RootTabScreenProps<"TabOne">) => { nav.navigate("ForgetPassword")} + onPress={() => + nav.navigate("Auth", { screen: "ForgotPasswordInput" }) + } > Lupa password anda? - {}} /> + nav.navigate("Auth", { screen: "Login" })} + /> @@ -76,9 +82,10 @@ const LoginScreen = ({ navigation }: RootTabScreenProps<"TabOne">) => { Belum Punya akun? nav.navigate("RegisterScreen")} + onPress={() => + nav.navigate("Auth", { screen: "ForgotPasswordInput" }) + } > - {" "} Daftar disini diff --git a/src/screens/auth/OnBoardingScreen.tsx b/src/screens/auth/OnBoardingScreen.tsx index cc2efe8..4769b8c 100644 --- a/src/screens/auth/OnBoardingScreen.tsx +++ b/src/screens/auth/OnBoardingScreen.tsx @@ -31,7 +31,7 @@ export default function OnBoardingScreen({ nav.navigate("Auth")} + onPress={() => nav.navigate("Auth", { screen: "Login" })} /> @@ -39,12 +39,15 @@ export default function OnBoardingScreen({ nav.navigate("Auth")} + onPress={() => nav.navigate("Auth", { screen: "RegisterScreen" })} /> - nav.navigate("Auth")}> + nav.navigate("Profile", { screen: "ProfileScreen" })} + > Lanjutkan sebagai tamu diff --git a/src/types/navigation/AuthStack.ts b/src/types/navigation/AuthStack.ts index b5e4289..7b00c1e 100644 --- a/src/types/navigation/AuthStack.ts +++ b/src/types/navigation/AuthStack.ts @@ -8,7 +8,8 @@ export type AuthStackParamList = { Login: undefined; RegisterGoogle: undefined; RegisterScreen: undefined; - ForgetPassword: undefined; + ForgotPasswordInput: undefined; + ForgotPasswordDone: undefined; onboarding: undefined; landing: undefined; }; diff --git a/src/types/navigation/RootStack.ts b/src/types/navigation/RootStack.ts index d424597..c42e49f 100644 --- a/src/types/navigation/RootStack.ts +++ b/src/types/navigation/RootStack.ts @@ -5,12 +5,13 @@ import { NavigatorScreenParams } from "@react-navigation/native"; import { NativeStackScreenProps } from "@react-navigation/native-stack"; +import { AuthStackParamList, ProfileStackParamList } from "."; import { RootTabParamList } from "./RootTab"; export type RootStackParamList = { MainTab: NavigatorScreenParams | undefined; - Auth: undefined; - Profile: undefined; + Auth: NavigatorScreenParams; + Profile: NavigatorScreenParams; Modal: undefined; NotFound: undefined; }; -- GitLab From 32488fc545a512639abd29bc94295c0ea39df6ac Mon Sep 17 00:00:00 2001 From: Bagus Prabowo Date: Sat, 25 Sep 2021 23:23:32 +0700 Subject: [PATCH 24/24] Chore: Finished form validation for multiple types --- src/components/Forms/IconForm.tsx | 74 ++++++++++++++--- src/components/Forms/PlainForm.test.tsx | 0 src/components/Forms/PlainForm.tsx | 62 +++++++++++++- src/components/__tests__/IconForm.test.tsx | 62 -------------- src/components/__tests__/PlainForm.test.tsx | 48 ----------- src/components/__tests__/Spacer.test.tsx | 18 ----- src/components/__tests__/StyledText-test.js | 10 --- .../__snapshots__/StyledText-test.js.snap | 18 ----- src/components/button/MainButton.tsx | 2 +- src/helpers/Validators.ts | 13 +++ src/navigation/AuthStackNavigator.tsx | 6 ++ src/screens/auth/ForgotPasswordDone.tsx | 15 ++-- ...swordInput.tsx => InputForgotPassword.tsx} | 41 ++++++---- src/screens/auth/LoginScreen.tsx | 59 +++++++------- src/screens/auth/OnBoardingScreen.tsx | 13 ++- .../auth/RegisterGoogleFacebookScreen.tsx | 13 +-- src/screens/auth/RegisterScreen.tsx | 59 +++++++++++--- src/screens/profile/AccountSettingsScreen.tsx | 81 ++++++++++++------- src/screens/profile/ChangePasswordScreen.tsx | 48 ++++++----- src/types/navigation/AuthStack.ts | 1 + 20 files changed, 346 insertions(+), 297 deletions(-) delete mode 100644 src/components/Forms/PlainForm.test.tsx delete mode 100644 src/components/__tests__/IconForm.test.tsx delete mode 100644 src/components/__tests__/PlainForm.test.tsx delete mode 100644 src/components/__tests__/Spacer.test.tsx delete mode 100644 src/components/__tests__/StyledText-test.js delete mode 100644 src/components/__tests__/__snapshots__/StyledText-test.js.snap create mode 100644 src/helpers/Validators.ts rename src/screens/auth/{ForgotPasswordInput.tsx => InputForgotPassword.tsx} (65%) diff --git a/src/components/Forms/IconForm.tsx b/src/components/Forms/IconForm.tsx index e2432e3..57e1024 100644 --- a/src/components/Forms/IconForm.tsx +++ b/src/components/Forms/IconForm.tsx @@ -3,6 +3,8 @@ import { View, StyleSheet, TextInput, TouchableOpacity } from "react-native"; import Colors from "../../constants/Colors"; import { Text } from "../Themed"; import { MaterialIcons } from "@expo/vector-icons"; +import { validateEmpty } from "../../helpers/Validators"; +import Spacer from "../Spacer/Spacer"; type props = { formTitle?: string; @@ -10,9 +12,10 @@ type props = { setText: React.Dispatch>; placeholder: string; disabled?: boolean; - validator?: (a: string) => boolean; - iconType: React.ComponentProps["name"]; + iconType?: React.ComponentProps["name"]; password?: boolean; + search?: boolean; + errorMessage?: string; }; const IconForm = ({ @@ -23,9 +26,13 @@ const IconForm = ({ disabled = false, iconType, password = false, + search = false, + errorMessage, }: props) => { const [isFocused, setIsFocused] = useState(false); const [showPass, setShowPass] = useState(password); + const [isError, setIsError] = useState(false); + let backgroundColor: string; if (disabled) { backgroundColor = Colors.form.disabled.bg; @@ -33,6 +40,44 @@ const IconForm = ({ backgroundColor = isFocused || text ? Colors.form.filled.bg : Colors.form.empty.bg; } + + let borderColor: string; + if (isFocused) { + borderColor = Colors.form.active.border; + } else if (!isFocused) { + if (isError) { + borderColor = Colors.button.warning.bg; + } else { + borderColor = Colors.form.filled.border; + } + } + + const endEdit = () => { + setIsFocused(false); + if (search || disabled) { + setIsError(false); + } else { + if (!validateEmpty(text)) { + setIsError(true); + } else { + setIsError(false); + } + } + }; + + let iconName: React.ComponentProps["name"]; + if (search) { + iconName = "search"; + } else if (password) { + if (showPass) { + iconName = "visibility"; + } else if (!showPass) { + iconName = "visibility-off"; + } + } else { + iconName = iconType; + } + return ( {formTitle.length > 0 && ( @@ -46,9 +91,7 @@ const IconForm = ({ style={{ ...styles.formContainer, backgroundColor: backgroundColor, - borderColor: isFocused - ? Colors.form.active.border - : Colors.form.filled.border, + borderColor: borderColor, shadowColor: isFocused ? "rgba(7, 145, 249, 0.12)" : "rgba(0, 0, 0, 0)", @@ -63,7 +106,7 @@ const IconForm = ({ setIsFocused(true)} - onEndEditing={() => setIsFocused(false)} + onEndEditing={endEdit} placeholder={placeholder} value={text} onChangeText={(n: string): void => setText(n)} @@ -72,6 +115,7 @@ const IconForm = ({ editable={!disabled} secureTextEntry={showPass} testID="Input" + autoCapitalize={password ? "none" : "sentences"} /> + {isError && ( + + + + {errorMessage} + + + )} ); }; @@ -127,6 +177,12 @@ const styles = StyleSheet.create({ textContainer: { flex: 1, }, + errorMessage: { + fontSize: 14, + fontWeight: "300", + textAlign: "left", + color: Colors.button.warning.bg, + }, }); export default IconForm; diff --git a/src/components/Forms/PlainForm.test.tsx b/src/components/Forms/PlainForm.test.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/Forms/PlainForm.tsx b/src/components/Forms/PlainForm.tsx index 95ab13e..d5505bf 100644 --- a/src/components/Forms/PlainForm.tsx +++ b/src/components/Forms/PlainForm.tsx @@ -2,6 +2,8 @@ import React, { useState } from "react"; import { View, StyleSheet, TextInput } from "react-native"; import Colors from "../../constants/Colors"; import { Text } from "../Themed"; +import { validateEmail, validateEmpty } from "../../helpers/Validators"; +import Spacer from "../Spacer/Spacer"; type props = { formTitle?: string; @@ -10,6 +12,8 @@ type props = { placeholder: string; disabled?: boolean; phone?: boolean; + email?: boolean; + errorMessage?: string; }; const PlainForm = ({ @@ -19,8 +23,12 @@ const PlainForm = ({ placeholder, disabled = false, phone = false, + errorMessage, + email = false, }: props) => { const [isFocused, setIsFocused] = useState(false); + const [isError, setIsError] = useState(false); + let backgroundColor: string; if (disabled) { backgroundColor = Colors.form.disabled.bg; @@ -28,6 +36,39 @@ const PlainForm = ({ backgroundColor = isFocused || text ? Colors.form.filled.bg : Colors.form.empty.bg; } + + let borderColor: string; + if (isFocused) { + borderColor = Colors.form.active.border; + } else if (!isFocused) { + if (isError) { + borderColor = Colors.button.warning.bg; + } else { + borderColor = Colors.form.filled.border; + } + } + + const endEdit = () => { + setIsFocused(false); + if (disabled) { + setIsError(false); + } else { + if (email) { + if (!validateEmail(text)) { + setIsError(true); + } else { + setIsError(false); + } + } else { + if (!validateEmpty(text)) { + setIsError(true); + } else { + setIsError(false); + } + } + } + }; + return ( {formTitle.length > 0 && ( @@ -41,9 +82,7 @@ const PlainForm = ({ style={{ ...styles.formContainer, backgroundColor: backgroundColor, - borderColor: isFocused - ? Colors.form.active.border - : Colors.form.filled.border, + borderColor: borderColor, shadowColor: isFocused ? "rgba(7, 145, 249, 0.12)" : "rgba(0, 0, 0, 0)", @@ -57,7 +96,7 @@ const PlainForm = ({ > setIsFocused(true)} - onEndEditing={() => setIsFocused(false)} + onEndEditing={endEdit} placeholder={placeholder} value={text} onChangeText={(n: string): void => setText(n)} @@ -66,8 +105,17 @@ const PlainForm = ({ editable={!disabled} keyboardType={phone ? "phone-pad" : "default"} testID="Input" + autoCapitalize={email ? "none" : "sentences"} /> + {isError && ( + + + + {errorMessage} + + + )} ); }; @@ -98,6 +146,12 @@ const styles = StyleSheet.create({ textAlign: "left", color: Colors.text.subtitle, }, + errorMessage: { + fontSize: 14, + fontWeight: "300", + textAlign: "left", + color: Colors.button.warning.bg, + }, }); export default PlainForm; diff --git a/src/components/__tests__/IconForm.test.tsx b/src/components/__tests__/IconForm.test.tsx deleted file mode 100644 index cece118..0000000 --- a/src/components/__tests__/IconForm.test.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import React, { useState } from "react"; -import { cleanup, render, fireEvent } from "@testing-library/react-native"; -import IconForm from "../Forms/IconForm"; - -afterEach(cleanup); - -const IconFormWrapper = (props) => { - const [text, setText] = useState("Hello"); - return ( - - ); -}; - -describe("Icon Form Test", () => { - it("Should detect a form", () => { - const { getByTestId } = render(); - expect(getByTestId("Icon")).not.toBeNull(); - }); - it("Should detect a title container", () => { - const { getByTestId } = render(); - expect(getByTestId("TitleContainer")).not.toBeNull(); - }); - it("Should detect a title if given", () => { - const { getByTestId } = render(); - expect(getByTestId("Title")).not.toBeNull(); - }); - it("Should detect a form container", () => { - const { getByTestId } = render(); - expect(getByTestId("Container")).not.toBeNull(); - }); - it("Should detect a container for input and icon", () => { - const { getByTestId } = render(); - expect(getByTestId("TextIcon")).not.toBeNull(); - }); - it("Should detect a text input", () => { - const { getByTestId } = render(); - expect(getByTestId("Input")).not.toBeNull(); - }); - it("Should detect a touchable", () => { - const { getByTestId } = render(); - expect(getByTestId("Touchable")).not.toBeNull(); - }); - it("Should detect a MaterialIcon", () => { - const { getByTestId } = render(); - expect(getByTestId("MaterialIcon")).not.toBeNull(); - }); - it("Should not detect a container title", () => { - const { queryByTestId } = render(); - expect(queryByTestId("TitleContainer")).toBeNull(); - }); - it("Should not detect a form title", () => { - const { queryByTestId } = render(); - expect(queryByTestId("Title")).toBeNull(); - }); - it("Should detect a send form text", () => { - const { getByTestId } = render(); - fireEvent.changeText(getByTestId("Input"), "Hello"); - expect(getByTestId("Input").props.value).toEqual("Hello"); - }); -}); diff --git a/src/components/__tests__/PlainForm.test.tsx b/src/components/__tests__/PlainForm.test.tsx deleted file mode 100644 index bf3bf0d..0000000 --- a/src/components/__tests__/PlainForm.test.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import React, { useState } from "react"; -import { cleanup, render, fireEvent } from "@testing-library/react-native"; -import PlainForm from "../Forms/PlainForm"; - -afterEach(cleanup); - -const PlainFormWrapper = (props) => { - const [text, setText] = useState("Hello"); - return ; -}; - -describe("Plain Form Test", () => { - it("Should detect a form", () => { - const { getByTestId } = render(); - expect(getByTestId("Plain")).not.toBeNull(); - }); - it("Should detect a title container", () => { - const { getByTestId } = render(); - expect(getByTestId("TitleContainer")).not.toBeNull(); - }); - it("Should detect a title if given", () => { - const { getByTestId } = render(); - expect(getByTestId("Title")).not.toBeNull(); - }); - it("Should detect a form container", () => { - const { getByTestId } = render(); - expect(getByTestId("Container")).not.toBeNull(); - }); - it("Should detect a text input", () => { - const { getByTestId } = render(); - expect(getByTestId("Input")).not.toBeNull(); - }); - it("Should not detect a container title", () => { - const { queryByTestId } = render(); - expect(queryByTestId("TitleContainer")).toBeNull(); - }); - it("Should not detect a form title", () => { - const { queryByTestId } = render(); - expect(queryByTestId("Title")).toBeNull(); - }); - it("Should detect a send form text", () => { - const { getByTestId } = render(); - fireEvent.changeText(getByTestId("Input"), "Hello"); - expect(getByTestId("Input").props.value).toEqual("Hello"); - }); -}); diff --git a/src/components/__tests__/Spacer.test.tsx b/src/components/__tests__/Spacer.test.tsx deleted file mode 100644 index 86599e2..0000000 --- a/src/components/__tests__/Spacer.test.tsx +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import React from "react"; -import { cleanup, render } from "@testing-library/react-native"; -import Spacer from "../Spacer/Spacer"; - -afterEach(cleanup); - -const SpacerWrapper = () => { - return ; -}; - -describe("Spacer Test", () => { - it("Should detect a spacer", () => { - const { getByTestId } = render(); - expect(getByTestId("Spacer")).not.toBeNull(); - }); -}); diff --git a/src/components/__tests__/StyledText-test.js b/src/components/__tests__/StyledText-test.js deleted file mode 100644 index 94be514..0000000 --- a/src/components/__tests__/StyledText-test.js +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from "react"; -import renderer from "react-test-renderer"; - -import { MonoText } from "../StyledText"; - -it(`renders correctly`, () => { - const tree = renderer.create(Snapshot test!).toJSON(); - - expect(tree).toMatchSnapshot(); -}); diff --git a/src/components/__tests__/__snapshots__/StyledText-test.js.snap b/src/components/__tests__/__snapshots__/StyledText-test.js.snap deleted file mode 100644 index 50edbb6..0000000 --- a/src/components/__tests__/__snapshots__/StyledText-test.js.snap +++ /dev/null @@ -1,18 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` - - Snapshot test! - -`; diff --git a/src/components/button/MainButton.tsx b/src/components/button/MainButton.tsx index a33afa0..3167c10 100644 --- a/src/components/button/MainButton.tsx +++ b/src/components/button/MainButton.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Text, View, StyleSheet, TouchableOpacity } from "react-native"; +import { Text, StyleSheet, TouchableOpacity } from "react-native"; import Colors from "../../constants/Colors"; type props = { diff --git a/src/helpers/Validators.ts b/src/helpers/Validators.ts new file mode 100644 index 0000000..b78a7f4 --- /dev/null +++ b/src/helpers/Validators.ts @@ -0,0 +1,13 @@ +export const validateEmail = (email: string): boolean => { + const re = + /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(String(email).toLowerCase()); +}; + +export const validateEmpty = (str: string): boolean => { + if (str.length > 0) { + return true; + } else { + return false; + } +}; diff --git a/src/navigation/AuthStackNavigator.tsx b/src/navigation/AuthStackNavigator.tsx index 6f8bcfe..ee531f6 100644 --- a/src/navigation/AuthStackNavigator.tsx +++ b/src/navigation/AuthStackNavigator.tsx @@ -8,6 +8,7 @@ import OnBoardingScreen from "../screens/auth/OnBoardingScreen"; import LandingScreen from "../screens/auth/LandingScreen"; import ForgotPasswordInput from "../screens/auth/ForgotPasswordDone"; import ForgotPasswordDone from "../screens/auth/ForgotPasswordDone"; +import InputForgotPassword from "../screens/auth/InputForgotPassword"; const AuthStack = createNativeStackNavigator(); const AuthStackNavigator = () => { @@ -48,6 +49,11 @@ const AuthStackNavigator = () => { component={ForgotPasswordDone} options={{ title: "Forgot Password Done" }} /> + ); }; diff --git a/src/screens/auth/ForgotPasswordDone.tsx b/src/screens/auth/ForgotPasswordDone.tsx index 35a5f29..aae92db 100644 --- a/src/screens/auth/ForgotPasswordDone.tsx +++ b/src/screens/auth/ForgotPasswordDone.tsx @@ -26,11 +26,13 @@ export default function ForgotPasswordDone({ - nav.navigate("Auth", { screen: "Login" })} - /> + + nav.navigate("Auth", { screen: "Login" })} + /> + ); } @@ -53,4 +55,7 @@ const styles = StyleSheet.create({ fontWeight: "300", color: Colors.text.subtitle, }, + componentWrapper: { + width: "100%", + }, }); diff --git a/src/screens/auth/ForgotPasswordInput.tsx b/src/screens/auth/InputForgotPassword.tsx similarity index 65% rename from src/screens/auth/ForgotPasswordInput.tsx rename to src/screens/auth/InputForgotPassword.tsx index 67d19c3..2776b37 100644 --- a/src/screens/auth/ForgotPasswordInput.tsx +++ b/src/screens/auth/InputForgotPassword.tsx @@ -9,8 +9,9 @@ import Spacer from "../../components/Spacer/Spacer"; import { MaterialIcons } from "@expo/vector-icons"; import MainButton from "../../components/button/MainButton"; import firebase from "firebase"; +import { validateEmail } from "../../helpers/Validators"; -export default function ForgotPasswordInput({ +export default function InputForgotPassword({ navigation, }: RootTabScreenProps<"TabOne">) { const [email, setEmail] = useState(""); @@ -29,20 +30,29 @@ export default function ForgotPasswordInput({ - + + + - { - firebase.auth().sendPasswordResetEmail(email); - }} - /> + + { + if (validateEmail(email)) { + firebase.auth().sendPasswordResetEmail(email); + nav.navigate("Auth", { screen: "ForgotPasswordDone" }); + } + }} + /> + ); } @@ -65,4 +75,7 @@ const styles = StyleSheet.create({ fontWeight: "300", color: Colors.text.subtitle, }, + componentWrapper: { + width: "100%", + }, }); diff --git a/src/screens/auth/LoginScreen.tsx b/src/screens/auth/LoginScreen.tsx index 764b190..c25e243 100644 --- a/src/screens/auth/LoginScreen.tsx +++ b/src/screens/auth/LoginScreen.tsx @@ -16,44 +16,50 @@ const LoginScreen = ({ navigation }: RootTabScreenProps<"TabOne">) => { const [password, setPassword] = useState(""); return ( - + Halo! - + Silahkan masukan email anda untuk masuk ke Click - + + + - + + + - + - nav.navigate("Auth", { screen: "ForgotPasswordInput" }) + nav.navigate("Auth", { screen: "InputForgotPassword" }) } > Lupa password anda? - + ) => { /> - + ) => { /> - + ) => { /> - + Belum Punya akun? - nav.navigate("Auth", { screen: "ForgotPasswordInput" }) - } + onPress={() => nav.navigate("Auth", { screen: "RegisterScreen" })} > Daftar disini @@ -106,9 +110,6 @@ const styles = StyleSheet.create({ paddingTop: 28, alignItems: "center", }, - textWrapper: { - width: "100%", - }, title: { color: Colors.text.title, fontWeight: "400", @@ -130,7 +131,7 @@ const styles = StyleSheet.create({ register: { color: Colors.text.link, }, - button: { + componentWrapper: { width: "100%", }, }); diff --git a/src/screens/auth/OnBoardingScreen.tsx b/src/screens/auth/OnBoardingScreen.tsx index 4769b8c..7b517b9 100644 --- a/src/screens/auth/OnBoardingScreen.tsx +++ b/src/screens/auth/OnBoardingScreen.tsx @@ -20,14 +20,14 @@ export default function OnBoardingScreen({ source={require("../../../assets/images/ClickLogo.png")} /> - + Click adalah aplikasi yang dapat membantu menemukan dan membuat ekosistem bisnis yang sesuai dengan kebutuhanmu. - + - + - + nav.navigate("Profile", { screen: "ProfileScreen" })} @@ -73,9 +73,6 @@ const styles = StyleSheet.create({ position: "relative", resizeMode: "contain", }, - textWraper: { - width: "100%", - }, textarea: { fontWeight: "300", fontSize: 20, @@ -85,7 +82,7 @@ const styles = StyleSheet.create({ fontSize: 16, color: Colors.text.link, }, - button: { + componentWrapper: { width: "100%", }, }); diff --git a/src/screens/auth/RegisterGoogleFacebookScreen.tsx b/src/screens/auth/RegisterGoogleFacebookScreen.tsx index 08d4574..b23a688 100644 --- a/src/screens/auth/RegisterGoogleFacebookScreen.tsx +++ b/src/screens/auth/RegisterGoogleFacebookScreen.tsx @@ -31,7 +31,7 @@ const RegisterGoogleFacebookScreen = ({ - + - + - + - + - + {}} /> @@ -120,7 +121,7 @@ const styles = StyleSheet.create({ letterSpacing: 0, textAlign: "left", }, - button: { + componentWrapper: { width: "100%", }, }); diff --git a/src/screens/auth/RegisterScreen.tsx b/src/screens/auth/RegisterScreen.tsx index 8f0c992..8d3da74 100644 --- a/src/screens/auth/RegisterScreen.tsx +++ b/src/screens/auth/RegisterScreen.tsx @@ -10,6 +10,7 @@ import MainButton from "../../components/button/MainButton"; import DropdownForm from "../../components/Forms/DropdownForm"; import { RootTabScreenProps } from "../../types/navigation"; import { useNavigation } from "@react-navigation/core"; +import { validateEmail, validateEmpty } from "../../helpers/Validators"; const RegisterScreen = ({ navigation }: RootTabScreenProps<"TabOne">) => { const nav = useNavigation(); @@ -20,13 +21,34 @@ const RegisterScreen = ({ navigation }: RootTabScreenProps<"TabOne">) => { const [phoneNo, setPhoneNo] = useState(""); const [picked, setPicked] = useState(""); const [list, setList] = useState(); + const [isError, setIsError] = useState(false); + + const handleSubmit = () => { + if ( + validateEmail(email) && + validateEmpty(firstName) && + validateEmpty(lastName) && + validateEmpty(phoneNo) && + validateEmpty(password) && + validateEmpty(picked) + ) { + setIsError(true); + } else { + setIsError(false); + } + if (!isError) { + //TODO: Register User + } + }; + return ( + //TODO: Page is unscrollable Selamat Datang! - + ) => { /> - + ) => { - + - + - + - + - + - + ) => { /> - + Dengan membuat akun Click, saya telah setuju dengan Syarat & Ketentuan serta Kebijakan Privasi yang telah ditetapkan oleh Click. - - {}} /> + + @@ -155,9 +182,15 @@ const styles = StyleSheet.create({ letterSpacing: 0, textAlign: "left", }, - button: { + componentWrapper: { width: "100%", }, + errorMessage: { + fontSize: 14, + fontWeight: "300", + textAlign: "left", + color: Colors.button.warning.bg, + }, }); export default RegisterScreen; diff --git a/src/screens/profile/AccountSettingsScreen.tsx b/src/screens/profile/AccountSettingsScreen.tsx index c10475e..7b7702e 100644 --- a/src/screens/profile/AccountSettingsScreen.tsx +++ b/src/screens/profile/AccountSettingsScreen.tsx @@ -31,48 +31,64 @@ export default function AccountSettingsScreen({ - + - + + + - + + + - + + + - + + + -