app-expo-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +3 -0
- package/bun.lock +82 -0
- package/package.json +26 -0
- package/src/copy-template.js +156 -0
- package/src/create-expo.js +10 -0
- package/src/index.js +39 -0
- package/src/install-deps.js +22 -0
- package/src/utils/logger.js +29 -0
- package/tailwind.config.js +69 -0
- package/template/src/app/_layout.tsx +61 -0
- package/template/src/app/auth/_layout.tsx +41 -0
- package/template/src/app/auth/change_pass.tsx +138 -0
- package/template/src/app/auth/change_pass_modal.tsx +74 -0
- package/template/src/app/auth/forgot.tsx +124 -0
- package/template/src/app/auth/index.tsx +274 -0
- package/template/src/app/auth/opt_verify.tsx +145 -0
- package/template/src/app/auth/register.tsx +334 -0
- package/template/src/app/auth/reset_pass.tsx +152 -0
- package/template/src/app/common/image.tsx +202 -0
- package/template/src/app/common/openurl.tsx +42 -0
- package/template/src/app/home/_layout.tsx +29 -0
- package/template/src/app/home/drawer/_layout.tsx +27 -0
- package/template/src/app/home/tabs/_layout.tsx +75 -0
- package/template/src/app/home/tabs/index.tsx +11 -0
- package/template/src/app/index.tsx +11 -0
- package/template/src/app/modals/confirmation_logout_modal.tsx +78 -0
- package/template/src/app/modals/payment_modal.tsx +105 -0
- package/template/src/app/modals/success_modal.tsx +72 -0
- package/template/src/app/modals/toaster.tsx +31 -0
- package/template/src/app/settings/_layout.tsx +19 -0
- package/template/src/app/settings/about_us.tsx +61 -0
- package/template/src/app/settings/privacy_policy.tsx +61 -0
- package/template/src/app/settings/terms_and_conditions.tsx +60 -0
- package/template/src/hooks/useCheckLocation.ts +36 -0
- package/template/src/hooks/useDocPicker.ts +83 -0
- package/template/src/hooks/useImgePicker.ts +70 -0
- package/template/src/hooks/useSuggestionLocation.ts +36 -0
- package/template/src/hooks/useUploadProgress.ts +127 -0
- package/template/src/redux/api-config/baseApi.ts +89 -0
- package/template/src/redux/api-slices/authSlices.ts +175 -0
- package/template/src/redux/interface/common.ts +19 -0
- package/template/src/redux/interface/interface.ts +196 -0
- package/template/src/redux/interface/tag-types.ts +13 -0
- package/template/src/redux/service/demo.ts +27 -0
- package/template/src/redux/store.ts +17 -0
- package/template/src/utils/utils.ts +27 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as Yup from "yup";
|
|
2
|
+
|
|
3
|
+
import { ScrollView, View } from "react-native";
|
|
4
|
+
|
|
5
|
+
import { Icon } from "@/assets/icons/Icon";
|
|
6
|
+
import BackButton from "@/src/lib/backHeader/BackButton";
|
|
7
|
+
import TButton from "@/src/lib/buttons/TButton";
|
|
8
|
+
import InputText from "@/src/lib/inputs/InputText";
|
|
9
|
+
import tw from "@/src/lib/tailwind";
|
|
10
|
+
import { useChangePasswordMutation } from "@/src/redux/apiSlices/authSlices";
|
|
11
|
+
import { router } from "expo-router";
|
|
12
|
+
import { Formik } from "formik";
|
|
13
|
+
import React from "react";
|
|
14
|
+
|
|
15
|
+
// --- Icon Placeholders ---
|
|
16
|
+
|
|
17
|
+
// --- Yup Validation Schema ---
|
|
18
|
+
const ChangePasswordSchema = Yup.object().shape({
|
|
19
|
+
old_password: Yup.string().required("Current password is required"),
|
|
20
|
+
new_password: Yup.string()
|
|
21
|
+
.min(6, "Password must be at least 6 characters")
|
|
22
|
+
.required("New password is required")
|
|
23
|
+
.notOneOf(
|
|
24
|
+
[Yup.ref("old_password"), null],
|
|
25
|
+
"New password must be different from current password"
|
|
26
|
+
),
|
|
27
|
+
c_password: Yup.string()
|
|
28
|
+
.oneOf([Yup.ref("new_password"), null], "Passwords must match")
|
|
29
|
+
.required("Please confirm your new password"),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// --- Reusable Password Input Component ---
|
|
33
|
+
|
|
34
|
+
// --- Main Change Password Screen Component ---
|
|
35
|
+
const ChangePasswordScreen = () => {
|
|
36
|
+
// const []
|
|
37
|
+
|
|
38
|
+
const [changePass, { isLoading }] = useChangePasswordMutation();
|
|
39
|
+
|
|
40
|
+
const handleSaveChanges = async (values: any) => {
|
|
41
|
+
try {
|
|
42
|
+
const res = await changePass(values).unwrap();
|
|
43
|
+
|
|
44
|
+
if (res?.success) {
|
|
45
|
+
router.push(
|
|
46
|
+
"/auth/change_pass_modal?title=You’re All Set!&subtitle=Your password has been changed successfully!&buttonTitle=Back"
|
|
47
|
+
);
|
|
48
|
+
} else {
|
|
49
|
+
router.push(`/modals/toaster?content=${res?.message}`);
|
|
50
|
+
}
|
|
51
|
+
} catch (error: any) {
|
|
52
|
+
router.push(`/modals/toaster?content=${error?.message}`);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Formik
|
|
58
|
+
initialValues={{
|
|
59
|
+
old_password: "",
|
|
60
|
+
new_password: "",
|
|
61
|
+
c_password: "",
|
|
62
|
+
}}
|
|
63
|
+
validationSchema={ChangePasswordSchema}
|
|
64
|
+
onSubmit={handleSaveChanges}
|
|
65
|
+
>
|
|
66
|
+
{({
|
|
67
|
+
handleChange,
|
|
68
|
+
handleBlur,
|
|
69
|
+
handleSubmit,
|
|
70
|
+
values,
|
|
71
|
+
errors,
|
|
72
|
+
touched,
|
|
73
|
+
}) => (
|
|
74
|
+
<View style={tw`flex-1 bg-[#121212]`}>
|
|
75
|
+
{/* Header */}
|
|
76
|
+
<BackButton
|
|
77
|
+
onPress={() => router.dismiss()}
|
|
78
|
+
title="Change Password"
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
<ScrollView contentContainerStyle={tw`p-5 mt-4 gap-5`}>
|
|
82
|
+
<InputText
|
|
83
|
+
textInputProps={{
|
|
84
|
+
placeholder: "Current Password",
|
|
85
|
+
placeholderTextColor: "#A9A9A9",
|
|
86
|
+
}}
|
|
87
|
+
variant="password"
|
|
88
|
+
svgFirstIcon={Icon.lock}
|
|
89
|
+
value={values.old_password}
|
|
90
|
+
errorText={errors.old_password}
|
|
91
|
+
touched={touched.old_password}
|
|
92
|
+
onChangeText={handleChange("old_password")}
|
|
93
|
+
onBlur={handleBlur("old_password")}
|
|
94
|
+
/>
|
|
95
|
+
|
|
96
|
+
<InputText
|
|
97
|
+
textInputProps={{
|
|
98
|
+
placeholder: "New Password",
|
|
99
|
+
placeholderTextColor: "#A9A9A9",
|
|
100
|
+
}}
|
|
101
|
+
variant="password"
|
|
102
|
+
svgFirstIcon={Icon.lock}
|
|
103
|
+
value={values.new_password}
|
|
104
|
+
errorText={errors.new_password}
|
|
105
|
+
touched={touched.new_password}
|
|
106
|
+
onChangeText={handleChange("new_password")}
|
|
107
|
+
onBlur={handleBlur("new_password")}
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
<InputText
|
|
111
|
+
textInputProps={{
|
|
112
|
+
placeholder: "Confirm New Password",
|
|
113
|
+
placeholderTextColor: "#A9A9A9",
|
|
114
|
+
}}
|
|
115
|
+
variant="password"
|
|
116
|
+
svgFirstIcon={Icon.lock}
|
|
117
|
+
value={values.c_password}
|
|
118
|
+
errorText={errors.c_password}
|
|
119
|
+
touched={touched.c_password}
|
|
120
|
+
onChangeText={handleChange("c_password")}
|
|
121
|
+
onBlur={handleBlur("c_password")}
|
|
122
|
+
/>
|
|
123
|
+
</ScrollView>
|
|
124
|
+
|
|
125
|
+
{/* Save Changes Button */}
|
|
126
|
+
<TButton
|
|
127
|
+
isLoading={isLoading}
|
|
128
|
+
onPress={handleSubmit}
|
|
129
|
+
containerStyle={tw`m-5`}
|
|
130
|
+
title="Save Changes"
|
|
131
|
+
/>
|
|
132
|
+
</View>
|
|
133
|
+
)}
|
|
134
|
+
</Formik>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export default ChangePasswordScreen;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { router, useGlobalSearchParams } from "expo-router";
|
|
2
|
+
import { Platform, Pressable, Text, View } from "react-native";
|
|
3
|
+
|
|
4
|
+
import { Icon } from "@/assets/icons/Icon";
|
|
5
|
+
import TButton from "@/src/lib/buttons/TButton";
|
|
6
|
+
import tw from "@/src/lib/tailwind";
|
|
7
|
+
import { BlurView } from "expo-blur";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { SvgXml } from "react-native-svg";
|
|
10
|
+
|
|
11
|
+
const Change_pass_modal = () => {
|
|
12
|
+
const params = useGlobalSearchParams();
|
|
13
|
+
// ?title='You’re All Set!'&subtitle='Your password has been changed successfully!'&buttonTitle='Back to login'&route='/auth
|
|
14
|
+
const { title, subtitle, buttonTitle, route }: any = params;
|
|
15
|
+
const CommonContent = () => {
|
|
16
|
+
return (
|
|
17
|
+
<View style={tw`items-center gap-5 w-full`}>
|
|
18
|
+
<SvgXml xml={Icon.check} />
|
|
19
|
+
|
|
20
|
+
<View style={tw`gap-2 w-full items-center`}>
|
|
21
|
+
<Text style={tw`text-white text-xl font-semibold text-center`}>
|
|
22
|
+
{title || "You’re All Set!"}
|
|
23
|
+
</Text>
|
|
24
|
+
<Text style={tw`text-gray-400 text-sm font-semibold text-center`}>
|
|
25
|
+
{subtitle || "Your password has been changed successfully!"}
|
|
26
|
+
</Text>
|
|
27
|
+
</View>
|
|
28
|
+
|
|
29
|
+
<TButton
|
|
30
|
+
containerStyle={tw`w-4/5 mt-3 self-center`}
|
|
31
|
+
onPress={() => {
|
|
32
|
+
router?.dismiss();
|
|
33
|
+
// router.push("/profile_setup");
|
|
34
|
+
if (route as string) {
|
|
35
|
+
router.push(route as any);
|
|
36
|
+
} else {
|
|
37
|
+
router?.dismiss();
|
|
38
|
+
}
|
|
39
|
+
}}
|
|
40
|
+
title={buttonTitle || "Back to login"}
|
|
41
|
+
/>
|
|
42
|
+
</View>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<Pressable
|
|
48
|
+
onPress={() => {
|
|
49
|
+
router.dismiss();
|
|
50
|
+
}}
|
|
51
|
+
style={tw`flex-1 bg-black/45 items-center justify-center`}
|
|
52
|
+
>
|
|
53
|
+
{Platform.OS === "ios" ? (
|
|
54
|
+
<BlurView
|
|
55
|
+
style={tw`w-[90%] h-[80] rounded-xl overflow-hidden items-center justify-center p-4`}
|
|
56
|
+
tint="dark"
|
|
57
|
+
blurReductionFactor={5}
|
|
58
|
+
intensity={100}
|
|
59
|
+
experimentalBlurMethod="dimezisBlurView"
|
|
60
|
+
>
|
|
61
|
+
<CommonContent />
|
|
62
|
+
</BlurView>
|
|
63
|
+
) : (
|
|
64
|
+
<View
|
|
65
|
+
style={tw`w-[90%] h-[80] bg-black/85 border border-secondary rounded-xl overflow-hidden items-center justify-center p-4`}
|
|
66
|
+
>
|
|
67
|
+
<CommonContent />
|
|
68
|
+
</View>
|
|
69
|
+
)}
|
|
70
|
+
</Pressable>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default Change_pass_modal;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as Yup from "yup";
|
|
2
|
+
|
|
3
|
+
import { Image, Text, View } from "react-native";
|
|
4
|
+
|
|
5
|
+
import AppBgWrapper from "@/src/components/common/AppBgWrapper";
|
|
6
|
+
import BackButton from "@/src/lib/backHeader/BackButton";
|
|
7
|
+
import { Formik } from "formik";
|
|
8
|
+
import { Icon } from "@/assets/icons/Icon";
|
|
9
|
+
import { ImageAssets } from "@/assets/images/image";
|
|
10
|
+
import InputText from "@/src/lib/inputs/InputText";
|
|
11
|
+
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
|
|
12
|
+
import React from "react";
|
|
13
|
+
import TButton from "@/src/lib/buttons/TButton";
|
|
14
|
+
import { router } from "expo-router";
|
|
15
|
+
import tw from "@/src/lib/tailwind";
|
|
16
|
+
import { useForgotMutation } from "@/src/redux/apiSlices/authSlices";
|
|
17
|
+
|
|
18
|
+
const Forgot = () => {
|
|
19
|
+
const [forgot, { isLoading }] = useForgotMutation();
|
|
20
|
+
|
|
21
|
+
const handleForgot = async (values: any) => {
|
|
22
|
+
try {
|
|
23
|
+
const res = await forgot(values).unwrap();
|
|
24
|
+
if (res?.success) {
|
|
25
|
+
router.push(`/modals/toaster?content=${res?.message}`);
|
|
26
|
+
router.replace(`/auth/opt_verify?email=${values.email}&forgot=true`);
|
|
27
|
+
} else {
|
|
28
|
+
router.push(`/modals/toaster?content=${res?.message}`);
|
|
29
|
+
}
|
|
30
|
+
} catch (error: any) {
|
|
31
|
+
router.push(`/modals/toaster?content=${error?.message}`);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Define validation schema using Yup
|
|
36
|
+
const loginValidationSchema = Yup.object().shape({
|
|
37
|
+
email: Yup.string()
|
|
38
|
+
.email("Please enter a valid email")
|
|
39
|
+
.required("Email is required"),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<AppBgWrapper>
|
|
44
|
+
<BackButton
|
|
45
|
+
onPress={() => router.dismiss()}
|
|
46
|
+
containerStyle={tw`absolute top-5`}
|
|
47
|
+
/>
|
|
48
|
+
<KeyboardAwareScrollView
|
|
49
|
+
style={tw`z-10 flex-1`}
|
|
50
|
+
contentContainerStyle={tw`items-center justify-center flex-1`}
|
|
51
|
+
>
|
|
52
|
+
<View style={tw`z-10 flex-1 items-center justify-center p-5`}>
|
|
53
|
+
<View style={tw`justify-center items-center gap-2`}>
|
|
54
|
+
<Image
|
|
55
|
+
source={ImageAssets.logo}
|
|
56
|
+
style={tw`h-30 aspect-square mb-5`}
|
|
57
|
+
resizeMode="contain"
|
|
58
|
+
/>
|
|
59
|
+
<View style={tw`items-center justify-center gap-2`}>
|
|
60
|
+
<Text
|
|
61
|
+
style={tw`text-white font-InterSemiBold text-2xl -tracking-[1px]`}
|
|
62
|
+
>
|
|
63
|
+
Forgot password ?
|
|
64
|
+
</Text>
|
|
65
|
+
<Text
|
|
66
|
+
style={tw`text-white text-base text-center font-InterRegular -tracking-[1px]`}
|
|
67
|
+
>
|
|
68
|
+
Enter the email address that you used to create your account. We
|
|
69
|
+
will send an OTP to reset your password.
|
|
70
|
+
</Text>
|
|
71
|
+
</View>
|
|
72
|
+
</View>
|
|
73
|
+
|
|
74
|
+
{/* Formik Wrapper */}
|
|
75
|
+
<Formik
|
|
76
|
+
initialValues={{ email: "" }}
|
|
77
|
+
validationSchema={loginValidationSchema}
|
|
78
|
+
onSubmit={handleForgot}
|
|
79
|
+
>
|
|
80
|
+
{({
|
|
81
|
+
handleChange,
|
|
82
|
+
handleBlur,
|
|
83
|
+
handleSubmit,
|
|
84
|
+
values,
|
|
85
|
+
errors,
|
|
86
|
+
touched,
|
|
87
|
+
isValid,
|
|
88
|
+
}) => (
|
|
89
|
+
<View style={tw`w-full py-8 gap-6`}>
|
|
90
|
+
<View style={tw`gap-3`}>
|
|
91
|
+
<InputText
|
|
92
|
+
svgFirstIcon={Icon.email}
|
|
93
|
+
textInputProps={{
|
|
94
|
+
placeholder: "Email",
|
|
95
|
+
placeholderTextColor: "#A9A9A9",
|
|
96
|
+
}}
|
|
97
|
+
value={values.email}
|
|
98
|
+
onChangeText={handleChange("email")}
|
|
99
|
+
onBlur={handleBlur("email")}
|
|
100
|
+
touched={touched.email}
|
|
101
|
+
errorText={errors.email}
|
|
102
|
+
/>
|
|
103
|
+
</View>
|
|
104
|
+
|
|
105
|
+
{/* Submit button calls handleSubmit from Formik */}
|
|
106
|
+
<TButton
|
|
107
|
+
title="Get OTP"
|
|
108
|
+
isLoading={isLoading}
|
|
109
|
+
onPress={() => {
|
|
110
|
+
handleSubmit();
|
|
111
|
+
// router.push("/auth/opt_verify");
|
|
112
|
+
}}
|
|
113
|
+
disabled={!isValid}
|
|
114
|
+
/>
|
|
115
|
+
</View>
|
|
116
|
+
)}
|
|
117
|
+
</Formik>
|
|
118
|
+
</View>
|
|
119
|
+
</KeyboardAwareScrollView>
|
|
120
|
+
</AppBgWrapper>
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export default Forgot;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import * as Yup from "yup";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
useGoogleLoginMutation,
|
|
5
|
+
useLoginMutation,
|
|
6
|
+
} from "@/src/redux/apiSlices/authSlices";
|
|
7
|
+
import { Image, Text, TouchableOpacity, View } from "react-native";
|
|
8
|
+
|
|
9
|
+
import { Icon } from "@/assets/icons/Icon";
|
|
10
|
+
import { ImageAssets } from "@/assets/images/image";
|
|
11
|
+
import AppBgWrapper from "@/src/components/common/AppBgWrapper";
|
|
12
|
+
import IButton from "@/src/lib/buttons/IButton";
|
|
13
|
+
import Or from "@/src/lib/buttons/Or";
|
|
14
|
+
import TButton from "@/src/lib/buttons/TButton";
|
|
15
|
+
import CheckBox from "@/src/lib/inputs/CheckBox";
|
|
16
|
+
import InputText from "@/src/lib/inputs/InputText";
|
|
17
|
+
import tw from "@/src/lib/tailwind";
|
|
18
|
+
import { support } from "@/src/utils/utils";
|
|
19
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
20
|
+
import { router } from "expo-router";
|
|
21
|
+
import { Formik } from "formik";
|
|
22
|
+
import React from "react";
|
|
23
|
+
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
|
|
24
|
+
import { SvgXml } from "react-native-svg";
|
|
25
|
+
|
|
26
|
+
const Login = () => {
|
|
27
|
+
const [loginInfo, setLoginInfo] = React.useState<null | {
|
|
28
|
+
email: string;
|
|
29
|
+
password: string;
|
|
30
|
+
}>(null);
|
|
31
|
+
const [check, setCheck] = React.useState(false);
|
|
32
|
+
const [passShow, setPassShow] = React.useState(false);
|
|
33
|
+
|
|
34
|
+
const [login, results] = useLoginMutation();
|
|
35
|
+
const [loginWithGoogle, googleResults] = useGoogleLoginMutation();
|
|
36
|
+
|
|
37
|
+
const handleLogin = async (values: any) => {
|
|
38
|
+
try {
|
|
39
|
+
if (check) {
|
|
40
|
+
AsyncStorage.setItem("check", "true");
|
|
41
|
+
AsyncStorage.setItem("loginInfo", JSON.stringify(values));
|
|
42
|
+
} else {
|
|
43
|
+
AsyncStorage.removeItem("check");
|
|
44
|
+
AsyncStorage.removeItem("loginInfo");
|
|
45
|
+
}
|
|
46
|
+
const response = await login(values).unwrap();
|
|
47
|
+
if (response?.success) {
|
|
48
|
+
// console.log(response?.data);
|
|
49
|
+
|
|
50
|
+
await AsyncStorage.setItem("token", response?.data?.token);
|
|
51
|
+
router.replace("/auth/location_access");
|
|
52
|
+
} else {
|
|
53
|
+
router.push(`/modals/toaster?content=${response?.message}`);
|
|
54
|
+
}
|
|
55
|
+
} catch (error: any) {
|
|
56
|
+
console.log(error);
|
|
57
|
+
router.push(`/modals/toaster?content=${error?.message}`);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleLoginWithGoogle = async () => {
|
|
62
|
+
try {
|
|
63
|
+
const response = await loginWithGoogle({}).unwrap();
|
|
64
|
+
// console.log(response);
|
|
65
|
+
if (response?.success) {
|
|
66
|
+
// router.push("/home/tabs");
|
|
67
|
+
router.push(`/auth/google_login?url=${`${response?.data}`}`);
|
|
68
|
+
} else {
|
|
69
|
+
router.push(`/modals/toaster?content=${response?.message}`);
|
|
70
|
+
}
|
|
71
|
+
} catch (error: any) {
|
|
72
|
+
router.push(`/modals/toaster?content=${error?.message}`);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Define validation schema using Yup
|
|
77
|
+
const loginValidationSchema = Yup.object().shape({
|
|
78
|
+
email: Yup.string()
|
|
79
|
+
.email("Please enter a valid email")
|
|
80
|
+
.required("Email is required"),
|
|
81
|
+
password: Yup.string()
|
|
82
|
+
.min(6, ({ min }) => `Password must be at least ${min} characters`)
|
|
83
|
+
.required("Password is required"),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
React.useEffect(() => {
|
|
87
|
+
AsyncStorage.getItem("check").then((value) => {
|
|
88
|
+
if (value === "true") {
|
|
89
|
+
// console.log(value);
|
|
90
|
+
setCheck(true);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
AsyncStorage.getItem("loginInfo").then((value) => {
|
|
94
|
+
if (value) {
|
|
95
|
+
// console.log(value);
|
|
96
|
+
setLoginInfo(JSON.parse(value));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}, []);
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<AppBgWrapper>
|
|
103
|
+
<KeyboardAwareScrollView style={tw`z-10 `}>
|
|
104
|
+
<View style={tw`flex-1 items-center justify-center p-5`}>
|
|
105
|
+
<View style={tw`justify-center items-center mt-10 gap-2`}>
|
|
106
|
+
<Image
|
|
107
|
+
source={ImageAssets.logo}
|
|
108
|
+
style={tw`h-18 aspect-square mb-5`}
|
|
109
|
+
resizeMode="contain"
|
|
110
|
+
/>
|
|
111
|
+
<View style={tw`items-center justify-center gap-2`}>
|
|
112
|
+
<Text
|
|
113
|
+
style={tw`text-white font-InterSemiBold text-2xl -tracking-[1px]`}
|
|
114
|
+
>
|
|
115
|
+
Welcome Back
|
|
116
|
+
</Text>
|
|
117
|
+
<Text
|
|
118
|
+
style={tw`text-white text-base font-InterRegular -tracking-[1px]`}
|
|
119
|
+
>
|
|
120
|
+
Please use your credentials to sign in
|
|
121
|
+
</Text>
|
|
122
|
+
</View>
|
|
123
|
+
</View>
|
|
124
|
+
|
|
125
|
+
{/* Formik Wrapper */}
|
|
126
|
+
<Formik
|
|
127
|
+
initialValues={{
|
|
128
|
+
email: loginInfo?.email || "",
|
|
129
|
+
password: loginInfo?.password || "",
|
|
130
|
+
}}
|
|
131
|
+
enableReinitialize
|
|
132
|
+
validationSchema={loginValidationSchema}
|
|
133
|
+
onSubmit={handleLogin}
|
|
134
|
+
>
|
|
135
|
+
{({
|
|
136
|
+
handleChange,
|
|
137
|
+
handleBlur,
|
|
138
|
+
handleSubmit,
|
|
139
|
+
values,
|
|
140
|
+
errors,
|
|
141
|
+
touched,
|
|
142
|
+
isValid,
|
|
143
|
+
}) => (
|
|
144
|
+
<View style={tw`w-full py-8 gap-6`}>
|
|
145
|
+
<View style={tw`gap-3`}>
|
|
146
|
+
<InputText
|
|
147
|
+
svgFirstIcon={Icon.email}
|
|
148
|
+
textInputProps={{
|
|
149
|
+
placeholder: "Email",
|
|
150
|
+
placeholderTextColor: "#A9A9A9",
|
|
151
|
+
}}
|
|
152
|
+
value={values.email}
|
|
153
|
+
onChangeText={handleChange("email")}
|
|
154
|
+
onBlur={handleBlur("email")}
|
|
155
|
+
touched={touched.email}
|
|
156
|
+
errorText={errors.email}
|
|
157
|
+
/>
|
|
158
|
+
|
|
159
|
+
<InputText
|
|
160
|
+
svgFirstIcon={Icon.lock}
|
|
161
|
+
textInputProps={{
|
|
162
|
+
placeholder: "Password",
|
|
163
|
+
placeholderTextColor: "#A9A9A9",
|
|
164
|
+
secureTextEntry: !passShow,
|
|
165
|
+
}}
|
|
166
|
+
value={values.password}
|
|
167
|
+
onChangeText={handleChange("password")}
|
|
168
|
+
onBlur={handleBlur("password")}
|
|
169
|
+
touched={touched.password}
|
|
170
|
+
errorText={errors.password}
|
|
171
|
+
svgSecondIcon={passShow ? Icon.eye : Icon.eyeOff}
|
|
172
|
+
svgSecondOnPress={() => setPassShow(!passShow)}
|
|
173
|
+
/>
|
|
174
|
+
</View>
|
|
175
|
+
|
|
176
|
+
<View style={tw`flex-row justify-between items-center`}>
|
|
177
|
+
<View style={tw`flex-row items-center`}>
|
|
178
|
+
<CheckBox
|
|
179
|
+
checked={check}
|
|
180
|
+
onPress={() => setCheck(!check)}
|
|
181
|
+
title="Remember me"
|
|
182
|
+
/>
|
|
183
|
+
</View>
|
|
184
|
+
<TouchableOpacity
|
|
185
|
+
onPress={() => {
|
|
186
|
+
router.push("/auth/forgot");
|
|
187
|
+
}}
|
|
188
|
+
>
|
|
189
|
+
<Text style={tw`text-[#339DFF] underline`}>
|
|
190
|
+
Forgot Password?
|
|
191
|
+
</Text>
|
|
192
|
+
</TouchableOpacity>
|
|
193
|
+
</View>
|
|
194
|
+
|
|
195
|
+
{/* Submit button calls handleSubmit from Formik */}
|
|
196
|
+
<TButton
|
|
197
|
+
isLoading={results.isLoading}
|
|
198
|
+
title="Sign In"
|
|
199
|
+
onPress={() => {
|
|
200
|
+
handleSubmit();
|
|
201
|
+
// router.push("/home");
|
|
202
|
+
}}
|
|
203
|
+
disabled={!isValid}
|
|
204
|
+
/>
|
|
205
|
+
|
|
206
|
+
<Or title="Or continue with" />
|
|
207
|
+
<View style={tw`flex-row justify-center items-center gap-4`}>
|
|
208
|
+
<IButton
|
|
209
|
+
isLoading={googleResults.isLoading}
|
|
210
|
+
containerStyle={tw`w-16 h-16 bg-transparent `}
|
|
211
|
+
svg={Icon.google}
|
|
212
|
+
onPress={handleLoginWithGoogle}
|
|
213
|
+
/>
|
|
214
|
+
{/* <IButton
|
|
215
|
+
containerStyle={tw`w-16 h-16 bg-transparent `}
|
|
216
|
+
svg={Icon.apple}
|
|
217
|
+
onPress={handleLoginWithGoogle}
|
|
218
|
+
/> */}
|
|
219
|
+
</View>
|
|
220
|
+
|
|
221
|
+
<View style={tw`gap-2`}>
|
|
222
|
+
<View style={tw`flex-row justify-center `}>
|
|
223
|
+
<Text style={tw`text-white`}>Dont have an account?</Text>
|
|
224
|
+
<TouchableOpacity
|
|
225
|
+
onPress={() => {
|
|
226
|
+
router.push("/auth/register");
|
|
227
|
+
}}
|
|
228
|
+
style={tw`flex-row items-center gap-3`}
|
|
229
|
+
>
|
|
230
|
+
<Text style={tw`text-[#339DFF] underline ml-1`}>
|
|
231
|
+
Sign up
|
|
232
|
+
</Text>
|
|
233
|
+
<SvgXml xml={Icon.play} />
|
|
234
|
+
</TouchableOpacity>
|
|
235
|
+
</View>
|
|
236
|
+
<View>
|
|
237
|
+
<Text style={tw`text-white text-center leading-6`}>
|
|
238
|
+
Please read our{" "}
|
|
239
|
+
<Text
|
|
240
|
+
onPress={() =>
|
|
241
|
+
router.push("/settings/terms_and_conditions")
|
|
242
|
+
}
|
|
243
|
+
style={tw`text-[#339DFF] underline`}
|
|
244
|
+
>
|
|
245
|
+
Terms
|
|
246
|
+
</Text>{" "}
|
|
247
|
+
and{" "}
|
|
248
|
+
<Text
|
|
249
|
+
onPress={() => router.push("/settings/privacy_policy")}
|
|
250
|
+
style={tw`text-[#339DFF] underline`}
|
|
251
|
+
>
|
|
252
|
+
Privacy Policy
|
|
253
|
+
</Text>{" "}
|
|
254
|
+
and if you have any problems please contact our{" "}
|
|
255
|
+
<Text
|
|
256
|
+
onPress={() => support()}
|
|
257
|
+
style={tw`text-[#339DFF] underline`}
|
|
258
|
+
>
|
|
259
|
+
Support
|
|
260
|
+
</Text>
|
|
261
|
+
</Text>
|
|
262
|
+
</View>
|
|
263
|
+
</View>
|
|
264
|
+
</View>
|
|
265
|
+
)}
|
|
266
|
+
</Formik>
|
|
267
|
+
{/* End of Formik Wrapper */}
|
|
268
|
+
</View>
|
|
269
|
+
</KeyboardAwareScrollView>
|
|
270
|
+
</AppBgWrapper>
|
|
271
|
+
);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export default Login;
|