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.
Files changed (46) hide show
  1. package/bin/index.js +3 -0
  2. package/bun.lock +82 -0
  3. package/package.json +26 -0
  4. package/src/copy-template.js +156 -0
  5. package/src/create-expo.js +10 -0
  6. package/src/index.js +39 -0
  7. package/src/install-deps.js +22 -0
  8. package/src/utils/logger.js +29 -0
  9. package/tailwind.config.js +69 -0
  10. package/template/src/app/_layout.tsx +61 -0
  11. package/template/src/app/auth/_layout.tsx +41 -0
  12. package/template/src/app/auth/change_pass.tsx +138 -0
  13. package/template/src/app/auth/change_pass_modal.tsx +74 -0
  14. package/template/src/app/auth/forgot.tsx +124 -0
  15. package/template/src/app/auth/index.tsx +274 -0
  16. package/template/src/app/auth/opt_verify.tsx +145 -0
  17. package/template/src/app/auth/register.tsx +334 -0
  18. package/template/src/app/auth/reset_pass.tsx +152 -0
  19. package/template/src/app/common/image.tsx +202 -0
  20. package/template/src/app/common/openurl.tsx +42 -0
  21. package/template/src/app/home/_layout.tsx +29 -0
  22. package/template/src/app/home/drawer/_layout.tsx +27 -0
  23. package/template/src/app/home/tabs/_layout.tsx +75 -0
  24. package/template/src/app/home/tabs/index.tsx +11 -0
  25. package/template/src/app/index.tsx +11 -0
  26. package/template/src/app/modals/confirmation_logout_modal.tsx +78 -0
  27. package/template/src/app/modals/payment_modal.tsx +105 -0
  28. package/template/src/app/modals/success_modal.tsx +72 -0
  29. package/template/src/app/modals/toaster.tsx +31 -0
  30. package/template/src/app/settings/_layout.tsx +19 -0
  31. package/template/src/app/settings/about_us.tsx +61 -0
  32. package/template/src/app/settings/privacy_policy.tsx +61 -0
  33. package/template/src/app/settings/terms_and_conditions.tsx +60 -0
  34. package/template/src/hooks/useCheckLocation.ts +36 -0
  35. package/template/src/hooks/useDocPicker.ts +83 -0
  36. package/template/src/hooks/useImgePicker.ts +70 -0
  37. package/template/src/hooks/useSuggestionLocation.ts +36 -0
  38. package/template/src/hooks/useUploadProgress.ts +127 -0
  39. package/template/src/redux/api-config/baseApi.ts +89 -0
  40. package/template/src/redux/api-slices/authSlices.ts +175 -0
  41. package/template/src/redux/interface/common.ts +19 -0
  42. package/template/src/redux/interface/interface.ts +196 -0
  43. package/template/src/redux/interface/tag-types.ts +13 -0
  44. package/template/src/redux/service/demo.ts +27 -0
  45. package/template/src/redux/store.ts +17 -0
  46. package/template/src/utils/utils.ts +27 -0
@@ -0,0 +1,145 @@
1
+ import { Image, Text, View } from "react-native";
2
+ import { router, useGlobalSearchParams } from "expo-router";
3
+
4
+ import AppBgWrapper from "@/src/components/common/AppBgWrapper";
5
+ import AsyncStorage from "@react-native-async-storage/async-storage";
6
+ import { ImageAssets } from "@/assets/images/image";
7
+ import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
8
+ import { OtpInput } from "react-native-otp-entry";
9
+ import React from "react";
10
+ import TButton from "@/src/lib/buttons/TButton";
11
+ import tw from "@/src/lib/tailwind";
12
+ import { useEmailVerifyMutation } from "@/src/redux/apiSlices/authSlices";
13
+
14
+ const Otp_verify = () => {
15
+ // Define validation schema using Yup
16
+
17
+ const [Otp, setOtp] = React.useState("");
18
+ const [email, setEmail] = React.useState("");
19
+
20
+ const [emailVerify, { isLoading }] = useEmailVerifyMutation();
21
+
22
+ const params = useGlobalSearchParams();
23
+
24
+ console.log(params);
25
+
26
+ const handleVerify = async (value: any) => {
27
+ try {
28
+ const verifyInfo = {
29
+ email: params?.email,
30
+ code: value,
31
+ };
32
+
33
+ console.log(verifyInfo);
34
+ const res = await emailVerify(verifyInfo).unwrap();
35
+ if (res?.success) {
36
+ if (params?.forgot) {
37
+ router?.push(`/auth/reset_pass?email=${params?.email}`);
38
+ } else if (params?.account) {
39
+ console.log(res);
40
+ await AsyncStorage.setItem("token", res?.data?.token);
41
+ router?.replace(`/auth/location_access`);
42
+ } else {
43
+ router?.push(`/auth`);
44
+ }
45
+ } else {
46
+ router.push(`/modals/toaster?content=${res?.message}`);
47
+ }
48
+ } catch (error: any) {
49
+ router.push(`/modals/toaster?content=${error?.message}`);
50
+ }
51
+ };
52
+
53
+ React.useLayoutEffect(() => {
54
+ if (params?.email) {
55
+ setEmail(params?.email as any);
56
+ }
57
+ }, [params?.email]);
58
+
59
+ return (
60
+ <AppBgWrapper>
61
+ <KeyboardAwareScrollView
62
+ style={tw`z-10 flex-1`}
63
+ contentContainerStyle={tw`items-center justify-center flex-1`}
64
+ >
65
+ <View style={tw`z-10 flex-1 items-center justify-center gap-8 p-5 `}>
66
+ <View style={tw`justify-center items-center gap-2`}>
67
+ <Image
68
+ source={ImageAssets.logo}
69
+ style={tw`h-30 aspect-square mb-5`}
70
+ resizeMode="contain"
71
+ />
72
+ <View style={tw`items-center justify-center gap-2`}>
73
+ <Text
74
+ style={tw`text-white font-InterSemiBold text-2xl -tracking-[1px]`}
75
+ >
76
+ Enter OTP
77
+ </Text>
78
+ <Text
79
+ style={tw`text-white text-base text-center font-InterRegular -tracking-[1px]`}
80
+ >
81
+ We’ve sent you a 4 digit OTP to {`\n`}{" "}
82
+ {(email as any)?.split("@")[0]?.slice(0, 3) +
83
+ "****@" +
84
+ (email as any)?.split("@")[1]}
85
+ </Text>
86
+ </View>
87
+ </View>
88
+
89
+ <View style={tw` w-full items-center `}>
90
+ <View style={tw` w-full items-center`}>
91
+ {/* OTP Fields */}
92
+ <View style={tw` mb-4`}>
93
+ <OtpInput
94
+ numberOfDigits={4}
95
+ focusColor={tw.color("primary")}
96
+ autoFocus={false}
97
+ hideStick={true}
98
+ placeholder="-"
99
+ blurOnFilled={true}
100
+ disabled={false}
101
+ type="numeric"
102
+ secureTextEntry={false}
103
+ focusStickBlinkingDuration={500}
104
+ onTextChange={async (text) => {
105
+ // setValue(text);
106
+ setOtp(text);
107
+ }}
108
+ // onFocus={() => console.log("Focused")}
109
+ // onBlur={() => console.log("Blurred")}
110
+ // onTextChange={(text) => console.log(text)}
111
+ onFilled={async (text) => {
112
+ console.log(`OTP is ${text}`);
113
+ // router.push("/home/tabs");
114
+ handleVerify(text);
115
+ }}
116
+ textInputProps={{
117
+ accessibilityLabel: "One-Time Password",
118
+ }}
119
+ theme={{
120
+ containerStyle: tw`rounded-full px-2 gap-2.5 mb-4`,
121
+ pinCodeContainerStyle: tw`h-20 w-20 justify-center border-0 items-center bg-secondary rounded-2xl `,
122
+ pinCodeTextStyle: tw`text-white text-2xl font-InterSemiBold `,
123
+ placeholderTextStyle: tw`text-white text-2xl font-InterSemiBold `,
124
+ }}
125
+ />
126
+ </View>
127
+ {/* Verify Button */}
128
+ <TButton
129
+ isLoading={isLoading}
130
+ title="Verify"
131
+ onPress={() => {
132
+ // router.push("/auth/reset_pass");
133
+ handleVerify(Otp);
134
+ }}
135
+ containerStyle={tw`w-full`}
136
+ />
137
+ </View>
138
+ </View>
139
+ </View>
140
+ </KeyboardAwareScrollView>
141
+ </AppBgWrapper>
142
+ );
143
+ };
144
+
145
+ export default Otp_verify;
@@ -0,0 +1,334 @@
1
+ import * as Yup from "yup";
2
+
3
+ import { Image, Text, TouchableOpacity, View } from "react-native";
4
+ import {
5
+ useGoogleLoginMutation,
6
+ useSignUpMutation,
7
+ } from "@/src/redux/apiSlices/authSlices";
8
+
9
+ import AppBgWrapper from "@/src/components/common/AppBgWrapper";
10
+ import BackButton from "@/src/lib/backHeader/BackButton";
11
+ import CheckBox from "@/src/lib/inputs/CheckBox";
12
+ import { Formik } from "formik";
13
+ import { Icon } from "@/assets/icons/Icon";
14
+ import { ImageAssets } from "@/assets/images/image";
15
+ import InputText from "@/src/lib/inputs/InputText";
16
+ import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
17
+ import Or from "@/src/lib/buttons/Or";
18
+ import React from "react";
19
+ import { SvgXml } from "react-native-svg";
20
+ import TButton from "@/src/lib/buttons/TButton";
21
+ import { router } from "expo-router";
22
+ import tw from "@/src/lib/tailwind";
23
+
24
+ const Register = () => {
25
+ const [showPassword, setShowPassword] = React.useState(false);
26
+ const [showPasswordTwo, setShowPasswordTwo] = React.useState(false);
27
+
28
+ const [checked, setChecked] = React.useState(false);
29
+
30
+ const [register, { isLoading }] = useSignUpMutation();
31
+ const [loginWithGoogle, googleResults] = useGoogleLoginMutation();
32
+
33
+ const handleRegister = async (values: any) => {
34
+ try {
35
+ // delete values?.confirmPassword;
36
+ // create new data without confirm password
37
+ const sendData = {
38
+ email: values.email,
39
+ password: values.password,
40
+ confirmPassword: values.confirmPassword,
41
+ name: values.name,
42
+ display_name: values.display_name,
43
+ gender: values.gender,
44
+ };
45
+ const res = await register(sendData).unwrap();
46
+ if (res?.success) {
47
+ router.push(`/auth/opt_verify?email=${values.email}&account=true`);
48
+ }
49
+ console.log(res);
50
+ } catch (error: any) {
51
+ // console.log(error);
52
+ router.push(`/modals/toaster?content=${error?.message}&time=4000`);
53
+ }
54
+ };
55
+
56
+ const handleLoginWithGoogle = async () => {
57
+ try {
58
+ const response = await loginWithGoogle({}).unwrap();
59
+ // console.log(response);
60
+ if (response?.success) {
61
+ // router.push("/home/tabs");
62
+ router.replace(`/auth/google_login?url=${`${response?.data}`}`);
63
+ } else {
64
+ router.push(`/modals/toaster?content=${response?.message}`);
65
+ }
66
+ } catch (error: any) {
67
+ router.push(`/modals/toaster?content=${error?.message}`);
68
+ }
69
+ };
70
+
71
+ // Define validation schema using Yup
72
+ const loginValidationSchema = Yup.object().shape({
73
+ email: Yup.string()
74
+ .email("Please enter a valid email")
75
+ .required("Email is required"),
76
+ password: Yup.string()
77
+ .min(6, ({ min }) => `Password must be at least ${min} characters`)
78
+ .required("Password is required"),
79
+ confirmPassword: Yup.string()
80
+ .min(6, ({ min }) => `Password must be at least ${min} characters`)
81
+ .required("Password is required")
82
+ .oneOf([Yup.ref("password")], "Passwords do not match"),
83
+ // show match password to confirm password
84
+
85
+ name: Yup.string().required("Fullname is required"),
86
+ display_name: Yup.string().required("Display name is required"),
87
+ });
88
+
89
+ return (
90
+ <AppBgWrapper>
91
+ <KeyboardAwareScrollView style={tw`z-10 `}>
92
+ <BackButton
93
+ onPress={() => router.dismiss()}
94
+ containerStyle={tw`absolute top-0`}
95
+ />
96
+ <View style={tw`flex-1 items-center justify-center p-5`}>
97
+ <View style={tw`justify-center items-center gap-2`}>
98
+ <Image
99
+ source={ImageAssets.logo}
100
+ style={tw`h-28 aspect-square `}
101
+ resizeMode="contain"
102
+ />
103
+ <View style={tw`items-center justify-center gap-1`}>
104
+ <Text
105
+ style={tw`text-white font-InterSemiBold text-2xl -tracking-[1px]`}
106
+ >
107
+ Create a new account
108
+ </Text>
109
+ <Text
110
+ style={tw`text-white text-base font-InterRegular -tracking-[1px]`}
111
+ >
112
+ Please input your details to sign up
113
+ </Text>
114
+ </View>
115
+ </View>
116
+
117
+ {/* Formik Wrapper */}
118
+ <Formik
119
+ initialValues={{
120
+ email: "",
121
+ password: "",
122
+ confirmPassword: "",
123
+ name: "",
124
+ display_name: "",
125
+ gender: "male",
126
+ }}
127
+ validationSchema={loginValidationSchema}
128
+ onSubmit={handleRegister}
129
+ >
130
+ {({
131
+ handleChange,
132
+ handleBlur,
133
+ handleSubmit,
134
+ values,
135
+ errors,
136
+ touched,
137
+ isValid,
138
+ setFieldValue,
139
+ }) => (
140
+ <View style={tw`w-full py-8 gap-6`}>
141
+ <View style={tw`gap-3`}>
142
+ <InputText
143
+ svgFirstIcon={Icon.user}
144
+ textInputProps={{
145
+ placeholder: "Your Full Name",
146
+ placeholderTextColor: "#A9A9A9",
147
+ }}
148
+ value={values.name}
149
+ onChangeText={handleChange("name")}
150
+ onBlur={handleBlur("name")}
151
+ touched={touched.name}
152
+ errorText={errors.name}
153
+ />
154
+ <InputText
155
+ svgFirstIcon={Icon.display_name}
156
+ textInputProps={{
157
+ placeholder: "Enter your display name",
158
+ placeholderTextColor: "#A9A9A9",
159
+ }}
160
+ value={values.display_name}
161
+ onChangeText={handleChange("display_name")}
162
+ onBlur={handleBlur("display_name")}
163
+ touched={touched.display_name}
164
+ errorText={errors.display_name}
165
+ />
166
+ <InputText
167
+ svgFirstIcon={Icon.email}
168
+ textInputProps={{
169
+ placeholder: "Email",
170
+ placeholderTextColor: "#A9A9A9",
171
+ }}
172
+ value={values.email}
173
+ onChangeText={handleChange("email")}
174
+ onBlur={handleBlur("email")}
175
+ touched={touched.email}
176
+ errorText={errors.email}
177
+ />
178
+ <View style={tw` px-4`}>
179
+ <Text style={tw`text-white font-InterRegular mb-2 `}>
180
+ Gender
181
+ </Text>
182
+ <View style={tw`flex-row items-center gap-3`}>
183
+ <TouchableOpacity
184
+ onPress={() => setFieldValue("gender", "male")}
185
+ style={
186
+ values.gender === "male"
187
+ ? tw`px-4 py-2 rounded-full bg-blue-500`
188
+ : tw`px-4 py-2 rounded-full bg-[#3D3D3D]`
189
+ }
190
+ >
191
+ <Text style={tw`text-white`}>Male</Text>
192
+ </TouchableOpacity>
193
+ <TouchableOpacity
194
+ onPress={() => setFieldValue("gender", "female")}
195
+ style={
196
+ values.gender === "female"
197
+ ? tw`px-4 py-2 rounded-full bg-blue-500`
198
+ : tw`px-4 py-2 rounded-full bg-[#3D3D3D]`
199
+ }
200
+ >
201
+ <Text style={tw`text-white`}>Female</Text>
202
+ </TouchableOpacity>
203
+ </View>
204
+ </View>
205
+ <InputText
206
+ svgFirstIcon={Icon.lock}
207
+ textInputProps={{
208
+ placeholder: "Password",
209
+ placeholderTextColor: "#A9A9A9",
210
+ secureTextEntry: !showPassword,
211
+ }}
212
+ svgSecondIcon={!showPassword ? Icon.eyeOff : Icon.eye}
213
+ svgSecondOnPress={() => setShowPassword(!showPassword)}
214
+ value={values.password}
215
+ onChangeText={handleChange("password")}
216
+ onBlur={handleBlur("password")}
217
+ touched={touched.password}
218
+ errorText={errors.password}
219
+ />
220
+ <InputText
221
+ svgFirstIcon={Icon.lock}
222
+ textInputProps={{
223
+ placeholder: "Confirm Password",
224
+ placeholderTextColor: "#A9A9A9",
225
+ secureTextEntry: !showPasswordTwo,
226
+ }}
227
+ svgSecondIcon={!showPasswordTwo ? Icon.eyeOff : Icon.eye}
228
+ svgSecondOnPress={() =>
229
+ setShowPasswordTwo(!showPasswordTwo)
230
+ }
231
+ value={values.confirmPassword}
232
+ onChangeText={handleChange("confirmPassword")}
233
+ onBlur={handleBlur("confirmPassword")}
234
+ touched={touched.confirmPassword}
235
+ errorText={errors.confirmPassword}
236
+ />
237
+ </View>
238
+
239
+ <View style={tw`flex-row justify-between items-center`}>
240
+ <View style={tw`flex-row items-center`}>
241
+ <CheckBox
242
+ checked={checked}
243
+ onPress={() => setChecked(!checked)}
244
+ containerStyle={tw`items-center flex-1`}
245
+ titleComponent={
246
+ <View style={tw` flex-row items-center gap-1`}>
247
+ <Text
248
+ style={tw`text-white font-InterRegular text-[13px]`}
249
+ >
250
+ Agree to
251
+ </Text>
252
+ <Text
253
+ onPress={() =>
254
+ router.push("/settings/terms_and_conditions")
255
+ }
256
+ style={tw`text-blue-500 underline font-InterRegular text-[13px]`}
257
+ >
258
+ Terms & conditions
259
+ </Text>
260
+ <Text
261
+ style={tw`text-white font-InterRegular text-[13px]`}
262
+ >
263
+ and
264
+ </Text>
265
+ <Text
266
+ onPress={() =>
267
+ router.push("/settings/privacy_policy")
268
+ }
269
+ style={tw` text-blue-500 underline font-InterRegular text-[13px]`}
270
+ >
271
+ Privacy policy
272
+ </Text>
273
+ <Text
274
+ style={tw`text-white font-InterRegular text-[13px]`}
275
+ >
276
+ .
277
+ </Text>
278
+ </View>
279
+ }
280
+ />
281
+ </View>
282
+ </View>
283
+
284
+ {/* Submit button calls handleSubmit from Formik */}
285
+ <TButton
286
+ isLoading={isLoading}
287
+ title="Sign Up"
288
+ onPress={() => {
289
+ handleSubmit();
290
+ // router.push("/auth/opt_verify");
291
+ }}
292
+ disabled={!isValid || !checked}
293
+ />
294
+
295
+ <Or title="Or continue with" />
296
+ <View style={tw`flex-row justify-center items-center gap-5`}>
297
+ <TouchableOpacity
298
+ onPress={handleLoginWithGoogle}
299
+ style={tw`w-16 h-16 rounded-full bg-[#3D3D3D] items-center justify-center`}
300
+ >
301
+ <SvgXml xml={Icon.google} />
302
+ </TouchableOpacity>
303
+ {/* <TouchableOpacity
304
+ style={tw`w-16 h-16 rounded-full bg-[#3D3D3D] items-center justify-center`}
305
+ >
306
+ <SvgXml xml={Icon.apple} />
307
+ </TouchableOpacity> */}
308
+ </View>
309
+
310
+ <View style={tw`flex-row justify-center mt-6`}>
311
+ <Text style={tw`text-white`}>Already have an account?</Text>
312
+ <TouchableOpacity
313
+ onPress={() => {
314
+ router.replace("/auth");
315
+ }}
316
+ style={tw`flex-row items-center gap-3`}
317
+ >
318
+ <Text style={tw`text-[#339DFF] underline ml-1`}>
319
+ Sign In
320
+ </Text>
321
+ <SvgXml xml={Icon.play} />
322
+ </TouchableOpacity>
323
+ </View>
324
+ </View>
325
+ )}
326
+ </Formik>
327
+ {/* End of Formik Wrapper */}
328
+ </View>
329
+ </KeyboardAwareScrollView>
330
+ </AppBgWrapper>
331
+ );
332
+ };
333
+
334
+ export default Register;
@@ -0,0 +1,152 @@
1
+ import * as Yup from "yup";
2
+
3
+ import { Image, Text, View } from "react-native";
4
+ import { router, useGlobalSearchParams } from "expo-router";
5
+
6
+ import AppBgWrapper from "@/src/components/common/AppBgWrapper";
7
+ import BackButton from "@/src/lib/backHeader/BackButton";
8
+ import { Formik } from "formik";
9
+ import { Icon } from "@/assets/icons/Icon";
10
+ import { ImageAssets } from "@/assets/images/image";
11
+ import InputText from "@/src/lib/inputs/InputText";
12
+ import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
13
+ import React from "react";
14
+ import TButton from "@/src/lib/buttons/TButton";
15
+ import tw from "@/src/lib/tailwind";
16
+ import { useResetPasswordMutation } from "@/src/redux/apiSlices/authSlices";
17
+
18
+ const Rest_pass = () => {
19
+ const [showPassword, setShowPassword] = React.useState(false);
20
+ const [showPasswordTwo, setShowPasswordTwo] = React.useState(false);
21
+ const [resetPassword, { isLoading }] = useResetPasswordMutation();
22
+ const { email } = useGlobalSearchParams();
23
+ const handleResetPassword = async (values: any) => {
24
+ try {
25
+ values.email = email;
26
+
27
+ const res = await resetPassword(values).unwrap();
28
+ if (res?.success) {
29
+ router.push(
30
+ "/auth/change_pass_modal?title=You’re All Set!&subtitle=Your password has been changed successfully!&buttonTitle=Back to login&route=/auth"
31
+ );
32
+ } else {
33
+ router.push(`/modals/toaster?content=${res?.message}`);
34
+ }
35
+ } catch (error: any) {
36
+ router.push(`/modals/toaster?content=${error?.message}`);
37
+ }
38
+ };
39
+
40
+ // Define validation schema using Yup
41
+ const loginValidationSchema = Yup.object().shape({
42
+ new_password: Yup.string()
43
+ .min(6, ({ min }) => `Password must be at least ${min} characters`)
44
+ .required("Password is required"),
45
+ c_password: Yup.string()
46
+ .min(6, ({ min }) => `Password must be at least ${min} characters`)
47
+ .required("Password is required")
48
+ .oneOf([Yup.ref("new_password")], "Passwords do not match"),
49
+ // show match password to confirm password
50
+ });
51
+
52
+ return (
53
+ <AppBgWrapper>
54
+ <BackButton
55
+ onPress={() => router.dismiss()}
56
+ containerStyle={tw`absolute top-5`}
57
+ />
58
+ <KeyboardAwareScrollView
59
+ style={tw`z-10 flex-1`}
60
+ contentContainerStyle={tw`items-center justify-center flex-1`}
61
+ >
62
+ <View style={tw`z-10 flex-1 items-center justify-center p-5`}>
63
+ <View style={tw`justify-center items-center gap-2`}>
64
+ <Image
65
+ source={ImageAssets.logo}
66
+ style={tw`h-30 aspect-square mb-5`}
67
+ resizeMode="contain"
68
+ />
69
+ <View style={tw`items-center justify-center gap-2`}>
70
+ <Text
71
+ style={tw`text-white font-InterSemiBold text-2xl -tracking-[1px]`}
72
+ >
73
+ Reset Password
74
+ </Text>
75
+ <Text
76
+ style={tw`text-white text-base text-center font-InterRegular -tracking-[1px]`}
77
+ >
78
+ Enter a new password for your account
79
+ </Text>
80
+ </View>
81
+ </View>
82
+
83
+ {/* Formik Wrapper */}
84
+ <Formik
85
+ initialValues={{ new_password: "", c_password: "" }}
86
+ validationSchema={loginValidationSchema}
87
+ onSubmit={handleResetPassword}
88
+ >
89
+ {({
90
+ handleChange,
91
+ handleBlur,
92
+ handleSubmit,
93
+ values,
94
+ errors,
95
+ touched,
96
+ isValid,
97
+ }) => (
98
+ <View style={tw`w-full py-8 gap-6`}>
99
+ <View style={tw`gap-3`}>
100
+ <InputText
101
+ svgFirstIcon={Icon.lock}
102
+ textInputProps={{
103
+ placeholder: "New Password",
104
+ placeholderTextColor: "#A9A9A9",
105
+ secureTextEntry: !showPassword,
106
+ }}
107
+ svgSecondIcon={showPassword ? Icon.eye : Icon.eyeOff}
108
+ svgSecondOnPress={() => setShowPassword(!showPassword)}
109
+ value={values.new_password}
110
+ onChangeText={handleChange("new_password")}
111
+ onBlur={handleBlur("new_password")}
112
+ touched={touched.new_password}
113
+ errorText={errors.new_password}
114
+ />
115
+ <InputText
116
+ svgFirstIcon={Icon.lock}
117
+ textInputProps={{
118
+ placeholder: "Confirm New Password",
119
+ placeholderTextColor: "#A9A9A9",
120
+ secureTextEntry: !showPasswordTwo,
121
+ }}
122
+ svgSecondIcon={showPasswordTwo ? Icon.eye : Icon.eyeOff}
123
+ svgSecondOnPress={() =>
124
+ setShowPasswordTwo(!showPasswordTwo)
125
+ }
126
+ value={values.c_password}
127
+ onChangeText={handleChange("c_password")}
128
+ onBlur={handleBlur("c_password")}
129
+ touched={touched.c_password}
130
+ errorText={errors.c_password}
131
+ />
132
+ </View>
133
+
134
+ {/* Submit button calls handleSubmit from Formik */}
135
+ <TButton
136
+ isLoading={isLoading}
137
+ title="Change password"
138
+ onPress={() => {
139
+ handleSubmit();
140
+ }}
141
+ disabled={!isValid}
142
+ />
143
+ </View>
144
+ )}
145
+ </Formik>
146
+ </View>
147
+ </KeyboardAwareScrollView>
148
+ </AppBgWrapper>
149
+ );
150
+ };
151
+
152
+ export default Rest_pass;