@thetechfossil/auth2 1.2.19 → 1.2.21

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 (38) hide show
  1. package/README.md +1 -1
  2. package/dist/index.components.d.mts +1 -0
  3. package/dist/index.components.d.ts +1 -0
  4. package/dist/index.components.js +275 -11
  5. package/dist/index.components.js.map +1 -1
  6. package/dist/index.components.mjs +275 -11
  7. package/dist/index.components.mjs.map +1 -1
  8. package/dist/index.d.mts +111 -3
  9. package/dist/index.d.ts +111 -3
  10. package/dist/index.js +470 -30
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +471 -32
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/index.next.d.mts +54 -1
  15. package/dist/index.next.d.ts +54 -1
  16. package/dist/index.next.js +332 -26
  17. package/dist/index.next.js.map +1 -1
  18. package/dist/index.next.mjs +332 -26
  19. package/dist/index.next.mjs.map +1 -1
  20. package/dist/index.next.server.d.mts +81 -2
  21. package/dist/index.next.server.d.ts +81 -2
  22. package/dist/index.next.server.js +406 -9
  23. package/dist/index.next.server.js.map +1 -1
  24. package/dist/index.next.server.mjs +403 -10
  25. package/dist/index.next.server.mjs.map +1 -1
  26. package/dist/index.node.d.mts +81 -2
  27. package/dist/index.node.d.ts +81 -2
  28. package/dist/index.node.js +406 -9
  29. package/dist/index.node.js.map +1 -1
  30. package/dist/index.node.mjs +403 -10
  31. package/dist/index.node.mjs.map +1 -1
  32. package/dist/index.react-native.d.mts +227 -0
  33. package/dist/index.react-native.d.ts +227 -0
  34. package/dist/index.react-native.js +1684 -0
  35. package/dist/index.react-native.js.map +1 -0
  36. package/dist/index.react-native.mjs +1648 -0
  37. package/dist/index.react-native.mjs.map +1 -0
  38. package/package.json +119 -102
@@ -0,0 +1,1648 @@
1
+ import { createContext, useState, useEffect, useCallback, useContext, useRef } from 'react';
2
+ import * as SecureStore from 'expo-secure-store';
3
+ import axios from 'axios';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+ import { StyleSheet, View, Text, TextInput, TouchableOpacity, ActivityIndicator, KeyboardAvoidingView, ScrollView, Platform, Image } from 'react-native';
6
+
7
+ // src/react-native/AuthProvider.tsx
8
+ var AuthServiceRN = class {
9
+ constructor(config) {
10
+ this.token = null;
11
+ this.config = config;
12
+ this.client = axios.create({
13
+ baseURL: config.baseUrl,
14
+ timeout: 3e4,
15
+ headers: {
16
+ "Content-Type": "application/json"
17
+ }
18
+ });
19
+ this.client.interceptors.request.use((config2) => {
20
+ if (this.token) {
21
+ config2.headers.Authorization = `Bearer ${this.token}`;
22
+ }
23
+ return config2;
24
+ });
25
+ }
26
+ setToken(token) {
27
+ this.token = token;
28
+ }
29
+ getToken() {
30
+ return this.token;
31
+ }
32
+ isAuthenticated() {
33
+ return !!this.token;
34
+ }
35
+ getCurrentUser() {
36
+ if (!this.token) return null;
37
+ try {
38
+ const payload = JSON.parse(atob(this.token.split(".")[1]));
39
+ return payload.user || null;
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+ async login(data) {
45
+ try {
46
+ const response = await this.client.post("/api/v1/auth/login", data);
47
+ if (response.data.success && response.data.token) {
48
+ this.token = response.data.token;
49
+ }
50
+ return response.data;
51
+ } catch (error) {
52
+ return {
53
+ success: false,
54
+ message: error.response?.data?.message || error.message || "Login failed"
55
+ };
56
+ }
57
+ }
58
+ async register(data) {
59
+ try {
60
+ const response = await this.client.post("/api/v1/auth/register", data);
61
+ return response.data;
62
+ } catch (error) {
63
+ return {
64
+ success: false,
65
+ message: error.response?.data?.message || error.message || "Registration failed"
66
+ };
67
+ }
68
+ }
69
+ async verify(data) {
70
+ try {
71
+ const response = await this.client.post("/api/v1/auth/verify", data);
72
+ if (response.data.success && response.data.token) {
73
+ this.token = response.data.token;
74
+ }
75
+ return response.data;
76
+ } catch (error) {
77
+ return {
78
+ success: false,
79
+ message: error.response?.data?.message || error.message || "Verification failed"
80
+ };
81
+ }
82
+ }
83
+ async logout() {
84
+ try {
85
+ await this.client.post("/api/v1/auth/logout", {});
86
+ } catch {
87
+ }
88
+ this.token = null;
89
+ }
90
+ async getProfile() {
91
+ const response = await this.client.get("/api/v1/user/me");
92
+ return response.data.user;
93
+ }
94
+ async updateProfile(data) {
95
+ try {
96
+ const response = await this.client.post("/api/v1/user/update/profile", data);
97
+ if (response.data.success && response.data.token) {
98
+ this.token = response.data.token;
99
+ }
100
+ return response.data;
101
+ } catch (error) {
102
+ return {
103
+ success: false,
104
+ message: error.response?.data?.message || error.message || "Update failed"
105
+ };
106
+ }
107
+ }
108
+ async forgotPassword(email) {
109
+ try {
110
+ const response = await this.client.post("/api/v1/auth/forgot-password", { email });
111
+ return response.data;
112
+ } catch (error) {
113
+ return {
114
+ success: false,
115
+ message: error.response?.data?.message || error.message || "Request failed"
116
+ };
117
+ }
118
+ }
119
+ async resetPassword(token, password) {
120
+ try {
121
+ const response = await this.client.post("/api/v1/auth/reset-password", { token, password });
122
+ return response.data;
123
+ } catch (error) {
124
+ return {
125
+ success: false,
126
+ message: error.response?.data?.message || error.message || "Reset failed"
127
+ };
128
+ }
129
+ }
130
+ async changePassword(oldPassword, newPassword) {
131
+ try {
132
+ const response = await this.client.post("/api/v1/user/change-password", {
133
+ oldPassword,
134
+ newPassword
135
+ });
136
+ return response.data;
137
+ } catch (error) {
138
+ return {
139
+ success: false,
140
+ message: error.response?.data?.message || error.message || "Change password failed"
141
+ };
142
+ }
143
+ }
144
+ };
145
+ var AuthContext = createContext(void 0);
146
+ var STORAGE_KEYS = {
147
+ TOKEN: "auth_token",
148
+ USER: "auth_user"
149
+ };
150
+ var AuthProvider = ({ children, config }) => {
151
+ const authConfig = {
152
+ baseUrl: config?.baseUrl || process.env.EXPO_PUBLIC_AUTH_API_URL || "http://localhost:7000",
153
+ localStorageKey: config?.localStorageKey || STORAGE_KEYS.TOKEN,
154
+ csrfEnabled: false
155
+ };
156
+ const [authService] = useState(() => new AuthServiceRN(authConfig));
157
+ const [user, setUser] = useState(null);
158
+ const [token, setToken] = useState(null);
159
+ const [isLoaded, setIsLoaded] = useState(false);
160
+ const [loading, setLoading] = useState(false);
161
+ useEffect(() => {
162
+ loadStoredAuth();
163
+ }, []);
164
+ const loadStoredAuth = async () => {
165
+ try {
166
+ const storedToken = await SecureStore.getItemAsync(STORAGE_KEYS.TOKEN);
167
+ const storedUser = await SecureStore.getItemAsync(STORAGE_KEYS.USER);
168
+ if (storedToken && storedUser) {
169
+ const parsedUser = JSON.parse(storedUser);
170
+ setToken(storedToken);
171
+ setUser(parsedUser);
172
+ authService.setToken(storedToken);
173
+ }
174
+ } catch (error) {
175
+ console.warn("[Auth SDK RN] Failed to load stored auth:", error);
176
+ } finally {
177
+ setIsLoaded(true);
178
+ }
179
+ };
180
+ const saveAuth = async (authToken, authUser) => {
181
+ await SecureStore.setItemAsync(STORAGE_KEYS.TOKEN, authToken);
182
+ await SecureStore.setItemAsync(STORAGE_KEYS.USER, JSON.stringify(authUser));
183
+ setToken(authToken);
184
+ setUser(authUser);
185
+ authService.setToken(authToken);
186
+ };
187
+ const clearAuth = async () => {
188
+ await SecureStore.deleteItemAsync(STORAGE_KEYS.TOKEN);
189
+ await SecureStore.deleteItemAsync(STORAGE_KEYS.USER);
190
+ setToken(null);
191
+ setUser(null);
192
+ authService.setToken(null);
193
+ };
194
+ const signIn = useCallback(async (data) => {
195
+ setLoading(true);
196
+ try {
197
+ const response = await authService.login(data);
198
+ if (response.success && response.user && response.token) {
199
+ await saveAuth(response.token, response.user);
200
+ }
201
+ return response;
202
+ } finally {
203
+ setLoading(false);
204
+ }
205
+ }, [authService]);
206
+ const signUp = useCallback(async (data) => {
207
+ setLoading(true);
208
+ try {
209
+ return await authService.register(data);
210
+ } finally {
211
+ setLoading(false);
212
+ }
213
+ }, [authService]);
214
+ const signOut = useCallback(async () => {
215
+ setLoading(true);
216
+ try {
217
+ await authService.logout();
218
+ await clearAuth();
219
+ } finally {
220
+ setLoading(false);
221
+ }
222
+ }, [authService]);
223
+ const verify = useCallback(async (data) => {
224
+ setLoading(true);
225
+ try {
226
+ const response = await authService.verify(data);
227
+ if (response.success && response.user && response.token) {
228
+ await saveAuth(response.token, response.user);
229
+ }
230
+ return response;
231
+ } finally {
232
+ setLoading(false);
233
+ }
234
+ }, [authService]);
235
+ const updateProfile = useCallback(async (data) => {
236
+ setLoading(true);
237
+ try {
238
+ const response = await authService.updateProfile(data);
239
+ if (response.success && response.user) {
240
+ setUser(response.user);
241
+ await SecureStore.setItemAsync(STORAGE_KEYS.USER, JSON.stringify(response.user));
242
+ }
243
+ return response;
244
+ } finally {
245
+ setLoading(false);
246
+ }
247
+ }, [authService]);
248
+ const getProfile = useCallback(async () => {
249
+ setLoading(true);
250
+ try {
251
+ const userData = await authService.getProfile();
252
+ setUser(userData);
253
+ await SecureStore.setItemAsync(STORAGE_KEYS.USER, JSON.stringify(userData));
254
+ return userData;
255
+ } finally {
256
+ setLoading(false);
257
+ }
258
+ }, [authService]);
259
+ const forgotPassword = useCallback(async (email) => {
260
+ setLoading(true);
261
+ try {
262
+ return await authService.forgotPassword(email);
263
+ } finally {
264
+ setLoading(false);
265
+ }
266
+ }, [authService]);
267
+ const resetPassword = useCallback(async (resetToken, password) => {
268
+ setLoading(true);
269
+ try {
270
+ return await authService.resetPassword(resetToken, password);
271
+ } finally {
272
+ setLoading(false);
273
+ }
274
+ }, [authService]);
275
+ const changePassword = useCallback(async (oldPassword, newPassword) => {
276
+ setLoading(true);
277
+ try {
278
+ return await authService.changePassword(oldPassword, newPassword);
279
+ } finally {
280
+ setLoading(false);
281
+ }
282
+ }, [authService]);
283
+ const value = {
284
+ user,
285
+ isLoaded,
286
+ isSignedIn: !!user,
287
+ loading,
288
+ token,
289
+ signIn,
290
+ signUp,
291
+ signOut,
292
+ verify,
293
+ updateProfile,
294
+ getProfile,
295
+ forgotPassword,
296
+ resetPassword,
297
+ changePassword,
298
+ authService
299
+ };
300
+ return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
301
+ };
302
+ var useAuth = () => {
303
+ const context = useContext(AuthContext);
304
+ if (context === void 0) {
305
+ throw new Error("useAuth must be used within an AuthProvider");
306
+ }
307
+ return context;
308
+ };
309
+ var Input = ({
310
+ label,
311
+ error,
312
+ containerStyle,
313
+ isPassword,
314
+ style,
315
+ theme,
316
+ ...props
317
+ }) => {
318
+ const [showPassword, setShowPassword] = useState(false);
319
+ const colors = {
320
+ backgroundColor: theme?.backgroundColor ?? "#F8FAFC",
321
+ borderColor: theme?.borderColor ?? "#E2E8F0",
322
+ textColor: theme?.textColor ?? "#1E293B",
323
+ labelColor: theme?.labelColor ?? "#374151",
324
+ placeholderColor: theme?.placeholderColor ?? "#9CA3AF",
325
+ accentColor: theme?.accentColor ?? "#4F46E5"
326
+ };
327
+ return /* @__PURE__ */ jsxs(View, { style: [styles.container, containerStyle], children: [
328
+ label && /* @__PURE__ */ jsx(Text, { style: [styles.label, { color: colors.labelColor }], children: label }),
329
+ /* @__PURE__ */ jsxs(View, { style: styles.inputWrapper, children: [
330
+ /* @__PURE__ */ jsx(
331
+ TextInput,
332
+ {
333
+ style: [
334
+ styles.input,
335
+ {
336
+ backgroundColor: colors.backgroundColor,
337
+ borderColor: error ? "#EF4444" : colors.borderColor,
338
+ color: colors.textColor
339
+ },
340
+ style
341
+ ],
342
+ placeholderTextColor: colors.placeholderColor,
343
+ secureTextEntry: isPassword && !showPassword,
344
+ ...props
345
+ }
346
+ ),
347
+ isPassword && /* @__PURE__ */ jsx(
348
+ TouchableOpacity,
349
+ {
350
+ style: styles.eyeButton,
351
+ onPress: () => setShowPassword(!showPassword),
352
+ children: /* @__PURE__ */ jsx(Text, { style: [styles.eyeText, { color: colors.accentColor }], children: showPassword ? "Hide" : "Show" })
353
+ }
354
+ )
355
+ ] }),
356
+ error && /* @__PURE__ */ jsx(Text, { style: styles.errorText, children: error })
357
+ ] });
358
+ };
359
+ var styles = StyleSheet.create({
360
+ container: {
361
+ marginBottom: 16,
362
+ width: "100%"
363
+ },
364
+ label: {
365
+ fontSize: 14,
366
+ fontWeight: "600",
367
+ marginBottom: 8
368
+ },
369
+ inputWrapper: {
370
+ position: "relative",
371
+ width: "100%"
372
+ },
373
+ input: {
374
+ borderWidth: 1.5,
375
+ borderRadius: 12,
376
+ paddingHorizontal: 16,
377
+ paddingVertical: 14,
378
+ fontSize: 16,
379
+ width: "100%"
380
+ },
381
+ eyeButton: {
382
+ position: "absolute",
383
+ right: 14,
384
+ top: 0,
385
+ bottom: 0,
386
+ justifyContent: "center"
387
+ },
388
+ eyeText: {
389
+ fontSize: 14,
390
+ fontWeight: "600"
391
+ },
392
+ errorText: {
393
+ color: "#EF4444",
394
+ fontSize: 12,
395
+ marginTop: 4
396
+ }
397
+ });
398
+ var Button = ({
399
+ title,
400
+ onPress,
401
+ loading = false,
402
+ disabled = false,
403
+ variant = "primary",
404
+ style,
405
+ textStyle,
406
+ theme
407
+ }) => {
408
+ const isDisabled = disabled || loading;
409
+ const colors = {
410
+ primaryColor: theme?.primaryColor ?? "#4F46E5",
411
+ primaryTextColor: theme?.primaryTextColor ?? "#FFFFFF",
412
+ secondaryColor: theme?.secondaryColor ?? "#F1F5F9",
413
+ secondaryTextColor: theme?.secondaryTextColor ?? "#374151"
414
+ };
415
+ const getButtonStyle = () => {
416
+ switch (variant) {
417
+ case "secondary":
418
+ return { backgroundColor: colors.secondaryColor };
419
+ case "outline":
420
+ return { backgroundColor: "transparent", borderWidth: 2, borderColor: colors.primaryColor };
421
+ case "ghost":
422
+ return { backgroundColor: "transparent" };
423
+ default:
424
+ return {
425
+ backgroundColor: colors.primaryColor,
426
+ shadowColor: colors.primaryColor,
427
+ shadowOffset: { width: 0, height: 4 },
428
+ shadowOpacity: 0.3,
429
+ shadowRadius: 8,
430
+ elevation: 4
431
+ };
432
+ }
433
+ };
434
+ const getTextColor = () => {
435
+ switch (variant) {
436
+ case "secondary":
437
+ return colors.secondaryTextColor;
438
+ case "outline":
439
+ case "ghost":
440
+ return colors.primaryColor;
441
+ default:
442
+ return colors.primaryTextColor;
443
+ }
444
+ };
445
+ return /* @__PURE__ */ jsx(
446
+ TouchableOpacity,
447
+ {
448
+ style: [
449
+ styles2.button,
450
+ getButtonStyle(),
451
+ isDisabled && styles2.disabled,
452
+ style
453
+ ],
454
+ onPress,
455
+ disabled: isDisabled,
456
+ activeOpacity: 0.7,
457
+ children: loading ? /* @__PURE__ */ jsx(
458
+ ActivityIndicator,
459
+ {
460
+ color: variant === "primary" ? colors.primaryTextColor : colors.primaryColor,
461
+ size: "small"
462
+ }
463
+ ) : /* @__PURE__ */ jsx(Text, { style: [styles2.text, { color: getTextColor() }, textStyle], children: title })
464
+ }
465
+ );
466
+ };
467
+ var styles2 = StyleSheet.create({
468
+ button: {
469
+ paddingVertical: 16,
470
+ paddingHorizontal: 24,
471
+ borderRadius: 14,
472
+ alignItems: "center",
473
+ justifyContent: "center",
474
+ minHeight: 52,
475
+ width: "100%"
476
+ },
477
+ disabled: {
478
+ opacity: 0.6
479
+ },
480
+ text: {
481
+ fontSize: 16,
482
+ fontWeight: "700"
483
+ }
484
+ });
485
+ var LoginForm = ({
486
+ onSuccess,
487
+ onOtpRequired,
488
+ onRegisterPress,
489
+ onForgotPasswordPress,
490
+ showRegisterLink = true,
491
+ showForgotPassword = true,
492
+ usePasswordLogin = true,
493
+ theme
494
+ }) => {
495
+ const { signIn, loading } = useAuth();
496
+ const [email, setEmail] = useState("");
497
+ const [password, setPassword] = useState("");
498
+ const [useOtp, setUseOtp] = useState(!usePasswordLogin);
499
+ const [error, setError] = useState(null);
500
+ const colors = {
501
+ textColor: theme?.textColor ?? "#111827",
502
+ secondaryTextColor: theme?.secondaryTextColor ?? "#6B7280",
503
+ mutedTextColor: theme?.mutedTextColor ?? "#9CA3AF",
504
+ accentColor: theme?.accentColor ?? "#4F46E5",
505
+ borderColor: theme?.borderColor ?? "#E5E7EB",
506
+ inputBackgroundColor: theme?.inputBackgroundColor ?? "#F8FAFC",
507
+ inputBorderColor: theme?.inputBorderColor ?? "#E2E8F0"
508
+ };
509
+ const inputTheme = {
510
+ backgroundColor: colors.inputBackgroundColor,
511
+ borderColor: colors.inputBorderColor,
512
+ textColor: colors.textColor,
513
+ labelColor: colors.secondaryTextColor,
514
+ placeholderColor: colors.mutedTextColor,
515
+ accentColor: colors.accentColor
516
+ };
517
+ const buttonTheme = {
518
+ primaryColor: colors.accentColor,
519
+ secondaryColor: colors.inputBackgroundColor,
520
+ secondaryTextColor: colors.textColor
521
+ };
522
+ const handleSubmit = async () => {
523
+ if (!email.trim()) {
524
+ setError("Email is required");
525
+ return;
526
+ }
527
+ if (!useOtp && !password.trim()) {
528
+ setError("Password is required");
529
+ return;
530
+ }
531
+ setError(null);
532
+ try {
533
+ const loginData = { email: email.trim() };
534
+ if (!useOtp) {
535
+ loginData.password = password;
536
+ }
537
+ const response = await signIn(loginData);
538
+ if (response.success) {
539
+ if (response.message?.includes("OTP sent")) {
540
+ onOtpRequired?.(email);
541
+ } else {
542
+ onSuccess?.(response);
543
+ }
544
+ } else {
545
+ setError(response.message || "Login failed");
546
+ }
547
+ } catch (err) {
548
+ setError(err instanceof Error ? err.message : "An error occurred");
549
+ }
550
+ };
551
+ return /* @__PURE__ */ jsx(
552
+ KeyboardAvoidingView,
553
+ {
554
+ behavior: Platform.OS === "ios" ? "padding" : "height",
555
+ style: styles3.container,
556
+ children: /* @__PURE__ */ jsx(
557
+ ScrollView,
558
+ {
559
+ contentContainerStyle: styles3.scrollContent,
560
+ keyboardShouldPersistTaps: "handled",
561
+ children: /* @__PURE__ */ jsxs(View, { style: styles3.card, children: [
562
+ /* @__PURE__ */ jsx(Text, { style: [styles3.title, { color: colors.textColor }], children: useOtp ? "Login with OTP" : "Login" }),
563
+ error && /* @__PURE__ */ jsx(View, { style: styles3.errorContainer, children: /* @__PURE__ */ jsx(Text, { style: styles3.errorText, children: error }) }),
564
+ /* @__PURE__ */ jsx(
565
+ Input,
566
+ {
567
+ label: "Email",
568
+ value: email,
569
+ onChangeText: setEmail,
570
+ placeholder: "Enter your email",
571
+ keyboardType: "email-address",
572
+ autoCapitalize: "none",
573
+ autoCorrect: false,
574
+ editable: !loading,
575
+ theme: inputTheme
576
+ }
577
+ ),
578
+ !useOtp && /* @__PURE__ */ jsx(
579
+ Input,
580
+ {
581
+ label: "Password",
582
+ value: password,
583
+ onChangeText: setPassword,
584
+ placeholder: "Enter your password",
585
+ isPassword: true,
586
+ editable: !loading,
587
+ theme: inputTheme
588
+ }
589
+ ),
590
+ /* @__PURE__ */ jsx(
591
+ Button,
592
+ {
593
+ title: loading ? "Please wait..." : useOtp ? "Send OTP" : "Login",
594
+ onPress: handleSubmit,
595
+ loading,
596
+ disabled: loading,
597
+ theme: buttonTheme
598
+ }
599
+ ),
600
+ /* @__PURE__ */ jsx(
601
+ TouchableOpacity,
602
+ {
603
+ style: styles3.switchMethod,
604
+ onPress: () => setUseOtp(!useOtp),
605
+ disabled: loading,
606
+ children: /* @__PURE__ */ jsx(Text, { style: [styles3.switchMethodText, { color: colors.accentColor }], children: useOtp ? "Login with password instead" : "Login with OTP instead" })
607
+ }
608
+ ),
609
+ showForgotPassword && !useOtp && /* @__PURE__ */ jsx(
610
+ TouchableOpacity,
611
+ {
612
+ style: styles3.forgotPassword,
613
+ onPress: onForgotPasswordPress,
614
+ disabled: loading,
615
+ children: /* @__PURE__ */ jsx(Text, { style: [styles3.forgotPasswordText, { color: colors.secondaryTextColor }], children: "Forgot password?" })
616
+ }
617
+ ),
618
+ showRegisterLink && /* @__PURE__ */ jsxs(View, { style: [styles3.registerContainer, { borderTopColor: colors.borderColor }], children: [
619
+ /* @__PURE__ */ jsxs(Text, { style: [styles3.registerText, { color: colors.secondaryTextColor }], children: [
620
+ "Don't have an account?",
621
+ " "
622
+ ] }),
623
+ /* @__PURE__ */ jsx(TouchableOpacity, { onPress: onRegisterPress, disabled: loading, children: /* @__PURE__ */ jsx(Text, { style: [styles3.registerLink, { color: colors.accentColor }], children: "Register" }) })
624
+ ] })
625
+ ] })
626
+ }
627
+ )
628
+ }
629
+ );
630
+ };
631
+ var styles3 = StyleSheet.create({
632
+ container: {
633
+ flex: 1,
634
+ width: "100%"
635
+ },
636
+ scrollContent: {
637
+ flexGrow: 1
638
+ },
639
+ card: {
640
+ width: "100%"
641
+ },
642
+ title: {
643
+ fontSize: 24,
644
+ fontWeight: "700",
645
+ textAlign: "center",
646
+ marginBottom: 24
647
+ },
648
+ errorContainer: {
649
+ backgroundColor: "#FEE2E2",
650
+ borderWidth: 1,
651
+ borderColor: "#FECACA",
652
+ borderRadius: 8,
653
+ padding: 12,
654
+ marginBottom: 16
655
+ },
656
+ errorText: {
657
+ color: "#DC2626",
658
+ fontSize: 14,
659
+ textAlign: "center"
660
+ },
661
+ switchMethod: {
662
+ marginTop: 16,
663
+ alignItems: "center"
664
+ },
665
+ switchMethodText: {
666
+ fontSize: 14,
667
+ fontWeight: "600"
668
+ },
669
+ forgotPassword: {
670
+ marginTop: 12,
671
+ alignItems: "center"
672
+ },
673
+ forgotPasswordText: {
674
+ fontSize: 14
675
+ },
676
+ registerContainer: {
677
+ flexDirection: "row",
678
+ justifyContent: "center",
679
+ marginTop: 24,
680
+ paddingTop: 16,
681
+ borderTopWidth: 1
682
+ },
683
+ registerText: {
684
+ fontSize: 14
685
+ },
686
+ registerLink: {
687
+ fontSize: 14,
688
+ fontWeight: "600"
689
+ }
690
+ });
691
+ var RegisterForm = ({
692
+ onSuccess,
693
+ onOtpRequired,
694
+ onLoginPress,
695
+ showLoginLink = true
696
+ }) => {
697
+ const { signUp, loading } = useAuth();
698
+ const [name, setName] = useState("");
699
+ const [email, setEmail] = useState("");
700
+ const [password, setPassword] = useState("");
701
+ const [confirmPassword, setConfirmPassword] = useState("");
702
+ const [error, setError] = useState(null);
703
+ const handleSubmit = async () => {
704
+ if (!name.trim()) {
705
+ setError("Name is required");
706
+ return;
707
+ }
708
+ if (!email.trim()) {
709
+ setError("Email is required");
710
+ return;
711
+ }
712
+ if (!password.trim()) {
713
+ setError("Password is required");
714
+ return;
715
+ }
716
+ if (password !== confirmPassword) {
717
+ setError("Passwords do not match");
718
+ return;
719
+ }
720
+ if (password.length < 6) {
721
+ setError("Password must be at least 6 characters");
722
+ return;
723
+ }
724
+ setError(null);
725
+ try {
726
+ const response = await signUp({
727
+ name: name.trim(),
728
+ email: email.trim(),
729
+ password
730
+ });
731
+ if (response.success) {
732
+ if (response.message?.includes("OTP") || response.message?.includes("Verification")) {
733
+ onOtpRequired?.(email);
734
+ } else {
735
+ onSuccess?.(response);
736
+ }
737
+ } else {
738
+ setError(response.message || "Registration failed");
739
+ }
740
+ } catch (err) {
741
+ setError(err instanceof Error ? err.message : "An error occurred");
742
+ }
743
+ };
744
+ return /* @__PURE__ */ jsx(
745
+ KeyboardAvoidingView,
746
+ {
747
+ behavior: Platform.OS === "ios" ? "padding" : "height",
748
+ style: styles4.container,
749
+ children: /* @__PURE__ */ jsx(
750
+ ScrollView,
751
+ {
752
+ contentContainerStyle: styles4.scrollContent,
753
+ keyboardShouldPersistTaps: "handled",
754
+ children: /* @__PURE__ */ jsxs(View, { style: styles4.card, children: [
755
+ /* @__PURE__ */ jsx(Text, { style: styles4.title, children: "Create Account" }),
756
+ error && /* @__PURE__ */ jsx(View, { style: styles4.errorContainer, children: /* @__PURE__ */ jsx(Text, { style: styles4.errorText, children: error }) }),
757
+ /* @__PURE__ */ jsx(
758
+ Input,
759
+ {
760
+ label: "Full Name",
761
+ value: name,
762
+ onChangeText: setName,
763
+ placeholder: "Enter your name",
764
+ autoCapitalize: "words",
765
+ editable: !loading
766
+ }
767
+ ),
768
+ /* @__PURE__ */ jsx(
769
+ Input,
770
+ {
771
+ label: "Email",
772
+ value: email,
773
+ onChangeText: setEmail,
774
+ placeholder: "Enter your email",
775
+ keyboardType: "email-address",
776
+ autoCapitalize: "none",
777
+ autoCorrect: false,
778
+ editable: !loading
779
+ }
780
+ ),
781
+ /* @__PURE__ */ jsx(
782
+ Input,
783
+ {
784
+ label: "Password",
785
+ value: password,
786
+ onChangeText: setPassword,
787
+ placeholder: "Create a password",
788
+ isPassword: true,
789
+ editable: !loading
790
+ }
791
+ ),
792
+ /* @__PURE__ */ jsx(
793
+ Input,
794
+ {
795
+ label: "Confirm Password",
796
+ value: confirmPassword,
797
+ onChangeText: setConfirmPassword,
798
+ placeholder: "Confirm your password",
799
+ isPassword: true,
800
+ editable: !loading
801
+ }
802
+ ),
803
+ /* @__PURE__ */ jsx(
804
+ Button,
805
+ {
806
+ title: loading ? "Creating account..." : "Register",
807
+ onPress: handleSubmit,
808
+ loading,
809
+ disabled: loading
810
+ }
811
+ ),
812
+ showLoginLink && /* @__PURE__ */ jsxs(View, { style: styles4.loginContainer, children: [
813
+ /* @__PURE__ */ jsx(Text, { style: styles4.loginText, children: "Already have an account? " }),
814
+ /* @__PURE__ */ jsx(TouchableOpacity, { onPress: onLoginPress, disabled: loading, children: /* @__PURE__ */ jsx(Text, { style: styles4.loginLink, children: "Login" }) })
815
+ ] })
816
+ ] })
817
+ }
818
+ )
819
+ }
820
+ );
821
+ };
822
+ var styles4 = StyleSheet.create({
823
+ container: {
824
+ flex: 1
825
+ },
826
+ scrollContent: {
827
+ flexGrow: 1,
828
+ justifyContent: "center",
829
+ padding: 20
830
+ },
831
+ card: {
832
+ backgroundColor: "#FFFFFF",
833
+ borderRadius: 16,
834
+ padding: 24,
835
+ shadowColor: "#000",
836
+ shadowOffset: { width: 0, height: 2 },
837
+ shadowOpacity: 0.1,
838
+ shadowRadius: 8,
839
+ elevation: 4
840
+ },
841
+ title: {
842
+ fontSize: 24,
843
+ fontWeight: "700",
844
+ color: "#111827",
845
+ textAlign: "center",
846
+ marginBottom: 24
847
+ },
848
+ errorContainer: {
849
+ backgroundColor: "#FEE2E2",
850
+ borderWidth: 1,
851
+ borderColor: "#FECACA",
852
+ borderRadius: 8,
853
+ padding: 12,
854
+ marginBottom: 16
855
+ },
856
+ errorText: {
857
+ color: "#DC2626",
858
+ fontSize: 14,
859
+ textAlign: "center"
860
+ },
861
+ loginContainer: {
862
+ flexDirection: "row",
863
+ justifyContent: "center",
864
+ marginTop: 24,
865
+ paddingTop: 16,
866
+ borderTopWidth: 1,
867
+ borderTopColor: "#E5E7EB"
868
+ },
869
+ loginText: {
870
+ color: "#6B7280",
871
+ fontSize: 14
872
+ },
873
+ loginLink: {
874
+ color: "#4F46E5",
875
+ fontSize: 14,
876
+ fontWeight: "600"
877
+ }
878
+ });
879
+ var OtpForm = ({
880
+ email,
881
+ onSuccess,
882
+ onResendOtp,
883
+ onBackPress,
884
+ otpLength = 6,
885
+ theme
886
+ }) => {
887
+ const { verify, signIn, loading } = useAuth();
888
+ const [otp, setOtp] = useState(Array(otpLength).fill(""));
889
+ const [error, setError] = useState(null);
890
+ const [resendTimer, setResendTimer] = useState(30);
891
+ const inputRefs = useRef([]);
892
+ const colors = {
893
+ textColor: theme?.textColor ?? "#111827",
894
+ secondaryTextColor: theme?.secondaryTextColor ?? "#6B7280",
895
+ accentColor: theme?.accentColor ?? "#4F46E5",
896
+ inputBackgroundColor: theme?.inputBackgroundColor ?? "#F9FAFB",
897
+ inputBorderColor: theme?.inputBorderColor ?? "#D1D5DB",
898
+ inputFilledBackgroundColor: theme?.inputFilledBackgroundColor ?? "#EEF2FF"
899
+ };
900
+ const buttonTheme = {
901
+ primaryColor: colors.accentColor
902
+ };
903
+ useEffect(() => {
904
+ if (resendTimer > 0) {
905
+ const timer = setTimeout(() => setResendTimer(resendTimer - 1), 1e3);
906
+ return () => clearTimeout(timer);
907
+ }
908
+ return void 0;
909
+ }, [resendTimer]);
910
+ const handleOtpChange = (value, index) => {
911
+ if (value.length > 1) {
912
+ const pastedOtp = value.slice(0, otpLength).split("");
913
+ const newOtp = [...otp];
914
+ pastedOtp.forEach((char, i) => {
915
+ if (index + i < otpLength) {
916
+ newOtp[index + i] = char;
917
+ }
918
+ });
919
+ setOtp(newOtp);
920
+ const nextIndex = Math.min(index + pastedOtp.length, otpLength - 1);
921
+ inputRefs.current[nextIndex]?.focus();
922
+ } else {
923
+ const newOtp = [...otp];
924
+ newOtp[index] = value;
925
+ setOtp(newOtp);
926
+ if (value && index < otpLength - 1) {
927
+ inputRefs.current[index + 1]?.focus();
928
+ }
929
+ }
930
+ setError(null);
931
+ };
932
+ const handleKeyPress = (e, index) => {
933
+ if (e.nativeEvent.key === "Backspace" && !otp[index] && index > 0) {
934
+ inputRefs.current[index - 1]?.focus();
935
+ }
936
+ };
937
+ const handleSubmit = async () => {
938
+ const otpCode = otp.join("");
939
+ if (otpCode.length !== otpLength) {
940
+ setError(`Please enter all ${otpLength} digits`);
941
+ return;
942
+ }
943
+ setError(null);
944
+ try {
945
+ const response = await verify({ email, otp: otpCode });
946
+ if (response.success) {
947
+ onSuccess?.(response);
948
+ } else {
949
+ setError(response.message || "Verification failed");
950
+ }
951
+ } catch (err) {
952
+ setError(err instanceof Error ? err.message : "An error occurred");
953
+ }
954
+ };
955
+ const handleResend = async () => {
956
+ setError(null);
957
+ setResendTimer(30);
958
+ try {
959
+ await signIn({ email });
960
+ onResendOtp?.();
961
+ } catch (err) {
962
+ setError("Failed to resend OTP");
963
+ }
964
+ };
965
+ return /* @__PURE__ */ jsx(
966
+ KeyboardAvoidingView,
967
+ {
968
+ behavior: Platform.OS === "ios" ? "padding" : "height",
969
+ style: styles5.container,
970
+ children: /* @__PURE__ */ jsxs(View, { style: styles5.card, children: [
971
+ /* @__PURE__ */ jsx(Text, { style: [styles5.title, { color: colors.textColor }], children: "Verify OTP" }),
972
+ /* @__PURE__ */ jsxs(Text, { style: [styles5.subtitle, { color: colors.secondaryTextColor }], children: [
973
+ "Enter the ",
974
+ otpLength,
975
+ "-digit code sent to",
976
+ "\n",
977
+ /* @__PURE__ */ jsx(Text, { style: [styles5.email, { color: colors.accentColor }], children: email })
978
+ ] }),
979
+ error && /* @__PURE__ */ jsx(View, { style: styles5.errorContainer, children: /* @__PURE__ */ jsx(Text, { style: styles5.errorText, children: error }) }),
980
+ /* @__PURE__ */ jsx(View, { style: styles5.otpContainer, children: otp.map((digit, index) => /* @__PURE__ */ jsx(
981
+ TextInput,
982
+ {
983
+ ref: (ref) => {
984
+ inputRefs.current[index] = ref;
985
+ },
986
+ style: [
987
+ styles5.otpInput,
988
+ {
989
+ backgroundColor: colors.inputBackgroundColor,
990
+ borderColor: colors.inputBorderColor,
991
+ color: colors.textColor
992
+ },
993
+ digit && {
994
+ borderColor: colors.accentColor,
995
+ backgroundColor: colors.inputFilledBackgroundColor
996
+ }
997
+ ],
998
+ value: digit,
999
+ onChangeText: (value) => handleOtpChange(value, index),
1000
+ onKeyPress: (e) => handleKeyPress(e, index),
1001
+ keyboardType: "number-pad",
1002
+ maxLength: otpLength,
1003
+ editable: !loading,
1004
+ selectTextOnFocus: true
1005
+ },
1006
+ index
1007
+ )) }),
1008
+ /* @__PURE__ */ jsx(
1009
+ Button,
1010
+ {
1011
+ title: loading ? "Verifying..." : "Verify",
1012
+ onPress: handleSubmit,
1013
+ loading,
1014
+ disabled: loading || otp.join("").length !== otpLength,
1015
+ theme: buttonTheme
1016
+ }
1017
+ ),
1018
+ /* @__PURE__ */ jsx(View, { style: styles5.resendContainer, children: resendTimer > 0 ? /* @__PURE__ */ jsxs(Text, { style: [styles5.resendTimer, { color: colors.secondaryTextColor }], children: [
1019
+ "Resend OTP in ",
1020
+ resendTimer,
1021
+ "s"
1022
+ ] }) : /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleResend, disabled: loading, children: /* @__PURE__ */ jsx(Text, { style: [styles5.resendLink, { color: colors.accentColor }], children: "Resend OTP" }) }) }),
1023
+ onBackPress && /* @__PURE__ */ jsx(TouchableOpacity, { style: styles5.backButton, onPress: onBackPress, children: /* @__PURE__ */ jsx(Text, { style: [styles5.backText, { color: colors.secondaryTextColor }], children: "\u2190 Back to login" }) })
1024
+ ] })
1025
+ }
1026
+ );
1027
+ };
1028
+ var styles5 = StyleSheet.create({
1029
+ container: {
1030
+ flex: 1,
1031
+ justifyContent: "center"
1032
+ },
1033
+ card: {
1034
+ width: "100%"
1035
+ },
1036
+ title: {
1037
+ fontSize: 24,
1038
+ fontWeight: "700",
1039
+ textAlign: "center",
1040
+ marginBottom: 8
1041
+ },
1042
+ subtitle: {
1043
+ fontSize: 14,
1044
+ textAlign: "center",
1045
+ marginBottom: 24,
1046
+ lineHeight: 20
1047
+ },
1048
+ email: {
1049
+ fontWeight: "600"
1050
+ },
1051
+ errorContainer: {
1052
+ backgroundColor: "#FEE2E2",
1053
+ borderWidth: 1,
1054
+ borderColor: "#FECACA",
1055
+ borderRadius: 8,
1056
+ padding: 12,
1057
+ marginBottom: 16
1058
+ },
1059
+ errorText: {
1060
+ color: "#DC2626",
1061
+ fontSize: 14,
1062
+ textAlign: "center"
1063
+ },
1064
+ otpContainer: {
1065
+ flexDirection: "row",
1066
+ justifyContent: "space-between",
1067
+ marginBottom: 24
1068
+ },
1069
+ otpInput: {
1070
+ width: 45,
1071
+ height: 55,
1072
+ borderWidth: 2,
1073
+ borderRadius: 10,
1074
+ fontSize: 24,
1075
+ fontWeight: "700",
1076
+ textAlign: "center"
1077
+ },
1078
+ resendContainer: {
1079
+ alignItems: "center",
1080
+ marginTop: 16
1081
+ },
1082
+ resendTimer: {
1083
+ fontSize: 14
1084
+ },
1085
+ resendLink: {
1086
+ fontSize: 14,
1087
+ fontWeight: "600"
1088
+ },
1089
+ backButton: {
1090
+ marginTop: 16,
1091
+ alignItems: "center"
1092
+ },
1093
+ backText: {
1094
+ fontSize: 14
1095
+ }
1096
+ });
1097
+ var ForgotPassword = ({
1098
+ onSuccess,
1099
+ onBackPress
1100
+ }) => {
1101
+ const { forgotPassword, loading } = useAuth();
1102
+ const [email, setEmail] = useState("");
1103
+ const [error, setError] = useState(null);
1104
+ const [success, setSuccess] = useState(false);
1105
+ const handleSubmit = async () => {
1106
+ if (!email.trim()) {
1107
+ setError("Email is required");
1108
+ return;
1109
+ }
1110
+ setError(null);
1111
+ try {
1112
+ const response = await forgotPassword(email.trim());
1113
+ if (response.success) {
1114
+ setSuccess(true);
1115
+ onSuccess?.(email);
1116
+ } else {
1117
+ setError(response.message || "Failed to send reset email");
1118
+ }
1119
+ } catch (err) {
1120
+ setError(err instanceof Error ? err.message : "An error occurred");
1121
+ }
1122
+ };
1123
+ if (success) {
1124
+ return /* @__PURE__ */ jsx(View, { style: styles6.container, children: /* @__PURE__ */ jsxs(View, { style: styles6.card, children: [
1125
+ /* @__PURE__ */ jsx(View, { style: styles6.successIcon, children: /* @__PURE__ */ jsx(Text, { style: styles6.successIconText, children: "\u2713" }) }),
1126
+ /* @__PURE__ */ jsx(Text, { style: styles6.title, children: "Check Your Email" }),
1127
+ /* @__PURE__ */ jsxs(Text, { style: styles6.subtitle, children: [
1128
+ "We've sent a password reset link to",
1129
+ "\n",
1130
+ /* @__PURE__ */ jsx(Text, { style: styles6.email, children: email })
1131
+ ] }),
1132
+ /* @__PURE__ */ jsx(
1133
+ Button,
1134
+ {
1135
+ title: "Back to Login",
1136
+ onPress: onBackPress || (() => {
1137
+ }),
1138
+ variant: "outline"
1139
+ }
1140
+ )
1141
+ ] }) });
1142
+ }
1143
+ return /* @__PURE__ */ jsx(
1144
+ KeyboardAvoidingView,
1145
+ {
1146
+ behavior: Platform.OS === "ios" ? "padding" : "height",
1147
+ style: styles6.container,
1148
+ children: /* @__PURE__ */ jsxs(View, { style: styles6.card, children: [
1149
+ /* @__PURE__ */ jsx(Text, { style: styles6.title, children: "Forgot Password" }),
1150
+ /* @__PURE__ */ jsx(Text, { style: styles6.subtitle, children: "Enter your email address and we'll send you a link to reset your password." }),
1151
+ error && /* @__PURE__ */ jsx(View, { style: styles6.errorContainer, children: /* @__PURE__ */ jsx(Text, { style: styles6.errorText, children: error }) }),
1152
+ /* @__PURE__ */ jsx(
1153
+ Input,
1154
+ {
1155
+ label: "Email",
1156
+ value: email,
1157
+ onChangeText: setEmail,
1158
+ placeholder: "Enter your email",
1159
+ keyboardType: "email-address",
1160
+ autoCapitalize: "none",
1161
+ autoCorrect: false,
1162
+ editable: !loading
1163
+ }
1164
+ ),
1165
+ /* @__PURE__ */ jsx(
1166
+ Button,
1167
+ {
1168
+ title: loading ? "Sending..." : "Send Reset Link",
1169
+ onPress: handleSubmit,
1170
+ loading,
1171
+ disabled: loading
1172
+ }
1173
+ ),
1174
+ onBackPress && /* @__PURE__ */ jsx(TouchableOpacity, { style: styles6.backButton, onPress: onBackPress, children: /* @__PURE__ */ jsx(Text, { style: styles6.backText, children: "\u2190 Back to login" }) })
1175
+ ] })
1176
+ }
1177
+ );
1178
+ };
1179
+ var styles6 = StyleSheet.create({
1180
+ container: {
1181
+ flex: 1,
1182
+ justifyContent: "center",
1183
+ padding: 20
1184
+ },
1185
+ card: {
1186
+ backgroundColor: "#FFFFFF",
1187
+ borderRadius: 16,
1188
+ padding: 24,
1189
+ shadowColor: "#000",
1190
+ shadowOffset: { width: 0, height: 2 },
1191
+ shadowOpacity: 0.1,
1192
+ shadowRadius: 8,
1193
+ elevation: 4
1194
+ },
1195
+ title: {
1196
+ fontSize: 24,
1197
+ fontWeight: "700",
1198
+ color: "#111827",
1199
+ textAlign: "center",
1200
+ marginBottom: 8
1201
+ },
1202
+ subtitle: {
1203
+ fontSize: 14,
1204
+ color: "#6B7280",
1205
+ textAlign: "center",
1206
+ marginBottom: 24,
1207
+ lineHeight: 20
1208
+ },
1209
+ email: {
1210
+ color: "#4F46E5",
1211
+ fontWeight: "600"
1212
+ },
1213
+ errorContainer: {
1214
+ backgroundColor: "#FEE2E2",
1215
+ borderWidth: 1,
1216
+ borderColor: "#FECACA",
1217
+ borderRadius: 8,
1218
+ padding: 12,
1219
+ marginBottom: 16
1220
+ },
1221
+ errorText: {
1222
+ color: "#DC2626",
1223
+ fontSize: 14,
1224
+ textAlign: "center"
1225
+ },
1226
+ backButton: {
1227
+ marginTop: 16,
1228
+ alignItems: "center"
1229
+ },
1230
+ backText: {
1231
+ color: "#6B7280",
1232
+ fontSize: 14
1233
+ },
1234
+ successIcon: {
1235
+ width: 60,
1236
+ height: 60,
1237
+ borderRadius: 30,
1238
+ backgroundColor: "#D1FAE5",
1239
+ alignItems: "center",
1240
+ justifyContent: "center",
1241
+ alignSelf: "center",
1242
+ marginBottom: 16
1243
+ },
1244
+ successIconText: {
1245
+ fontSize: 28,
1246
+ color: "#059669"
1247
+ }
1248
+ });
1249
+ var ResetPassword = ({
1250
+ token,
1251
+ onSuccess,
1252
+ onBackPress
1253
+ }) => {
1254
+ const { resetPassword, loading } = useAuth();
1255
+ const [password, setPassword] = useState("");
1256
+ const [confirmPassword, setConfirmPassword] = useState("");
1257
+ const [error, setError] = useState(null);
1258
+ const [success, setSuccess] = useState(false);
1259
+ const handleSubmit = async () => {
1260
+ if (!password.trim()) {
1261
+ setError("Password is required");
1262
+ return;
1263
+ }
1264
+ if (password.length < 6) {
1265
+ setError("Password must be at least 6 characters");
1266
+ return;
1267
+ }
1268
+ if (password !== confirmPassword) {
1269
+ setError("Passwords do not match");
1270
+ return;
1271
+ }
1272
+ setError(null);
1273
+ try {
1274
+ const response = await resetPassword(token, password);
1275
+ if (response.success) {
1276
+ setSuccess(true);
1277
+ onSuccess?.();
1278
+ } else {
1279
+ setError(response.message || "Failed to reset password");
1280
+ }
1281
+ } catch (err) {
1282
+ setError(err instanceof Error ? err.message : "An error occurred");
1283
+ }
1284
+ };
1285
+ if (success) {
1286
+ return /* @__PURE__ */ jsx(View, { style: styles7.container, children: /* @__PURE__ */ jsxs(View, { style: styles7.card, children: [
1287
+ /* @__PURE__ */ jsx(View, { style: styles7.successIcon, children: /* @__PURE__ */ jsx(Text, { style: styles7.successIconText, children: "\u2713" }) }),
1288
+ /* @__PURE__ */ jsx(Text, { style: styles7.title, children: "Password Reset" }),
1289
+ /* @__PURE__ */ jsx(Text, { style: styles7.subtitle, children: "Your password has been successfully reset. You can now login with your new password." }),
1290
+ /* @__PURE__ */ jsx(
1291
+ Button,
1292
+ {
1293
+ title: "Back to Login",
1294
+ onPress: onBackPress || (() => {
1295
+ })
1296
+ }
1297
+ )
1298
+ ] }) });
1299
+ }
1300
+ return /* @__PURE__ */ jsx(
1301
+ KeyboardAvoidingView,
1302
+ {
1303
+ behavior: Platform.OS === "ios" ? "padding" : "height",
1304
+ style: styles7.container,
1305
+ children: /* @__PURE__ */ jsx(
1306
+ ScrollView,
1307
+ {
1308
+ contentContainerStyle: styles7.scrollContent,
1309
+ keyboardShouldPersistTaps: "handled",
1310
+ children: /* @__PURE__ */ jsxs(View, { style: styles7.card, children: [
1311
+ /* @__PURE__ */ jsx(Text, { style: styles7.title, children: "Reset Password" }),
1312
+ /* @__PURE__ */ jsx(Text, { style: styles7.subtitle, children: "Enter your new password below." }),
1313
+ error && /* @__PURE__ */ jsx(View, { style: styles7.errorContainer, children: /* @__PURE__ */ jsx(Text, { style: styles7.errorText, children: error }) }),
1314
+ /* @__PURE__ */ jsx(
1315
+ Input,
1316
+ {
1317
+ label: "New Password",
1318
+ value: password,
1319
+ onChangeText: setPassword,
1320
+ placeholder: "Enter new password",
1321
+ isPassword: true,
1322
+ editable: !loading
1323
+ }
1324
+ ),
1325
+ /* @__PURE__ */ jsx(
1326
+ Input,
1327
+ {
1328
+ label: "Confirm Password",
1329
+ value: confirmPassword,
1330
+ onChangeText: setConfirmPassword,
1331
+ placeholder: "Confirm new password",
1332
+ isPassword: true,
1333
+ editable: !loading
1334
+ }
1335
+ ),
1336
+ /* @__PURE__ */ jsx(
1337
+ Button,
1338
+ {
1339
+ title: loading ? "Resetting..." : "Reset Password",
1340
+ onPress: handleSubmit,
1341
+ loading,
1342
+ disabled: loading
1343
+ }
1344
+ )
1345
+ ] })
1346
+ }
1347
+ )
1348
+ }
1349
+ );
1350
+ };
1351
+ var styles7 = StyleSheet.create({
1352
+ container: {
1353
+ flex: 1
1354
+ },
1355
+ scrollContent: {
1356
+ flexGrow: 1,
1357
+ justifyContent: "center",
1358
+ padding: 20
1359
+ },
1360
+ card: {
1361
+ backgroundColor: "#FFFFFF",
1362
+ borderRadius: 16,
1363
+ padding: 24,
1364
+ shadowColor: "#000",
1365
+ shadowOffset: { width: 0, height: 2 },
1366
+ shadowOpacity: 0.1,
1367
+ shadowRadius: 8,
1368
+ elevation: 4
1369
+ },
1370
+ title: {
1371
+ fontSize: 24,
1372
+ fontWeight: "700",
1373
+ color: "#111827",
1374
+ textAlign: "center",
1375
+ marginBottom: 8
1376
+ },
1377
+ subtitle: {
1378
+ fontSize: 14,
1379
+ color: "#6B7280",
1380
+ textAlign: "center",
1381
+ marginBottom: 24,
1382
+ lineHeight: 20
1383
+ },
1384
+ errorContainer: {
1385
+ backgroundColor: "#FEE2E2",
1386
+ borderWidth: 1,
1387
+ borderColor: "#FECACA",
1388
+ borderRadius: 8,
1389
+ padding: 12,
1390
+ marginBottom: 16
1391
+ },
1392
+ errorText: {
1393
+ color: "#DC2626",
1394
+ fontSize: 14,
1395
+ textAlign: "center"
1396
+ },
1397
+ successIcon: {
1398
+ width: 60,
1399
+ height: 60,
1400
+ borderRadius: 30,
1401
+ backgroundColor: "#D1FAE5",
1402
+ alignItems: "center",
1403
+ justifyContent: "center",
1404
+ alignSelf: "center",
1405
+ marginBottom: 16
1406
+ },
1407
+ successIconText: {
1408
+ fontSize: 28,
1409
+ color: "#059669"
1410
+ }
1411
+ });
1412
+ var UserProfile = ({
1413
+ onEditPress,
1414
+ onLogoutPress,
1415
+ showLogoutButton = true
1416
+ }) => {
1417
+ const { user, signOut, loading } = useAuth();
1418
+ const handleLogout = async () => {
1419
+ await signOut();
1420
+ onLogoutPress?.();
1421
+ };
1422
+ if (!user) {
1423
+ return /* @__PURE__ */ jsx(View, { style: styles8.container, children: /* @__PURE__ */ jsx(Text, { style: styles8.notLoggedIn, children: "Not logged in" }) });
1424
+ }
1425
+ const getInitials = (name, email) => {
1426
+ if (name) {
1427
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
1428
+ }
1429
+ return email?.charAt(0).toUpperCase() || "?";
1430
+ };
1431
+ return /* @__PURE__ */ jsx(View, { style: styles8.container, children: /* @__PURE__ */ jsxs(View, { style: styles8.card, children: [
1432
+ /* @__PURE__ */ jsxs(View, { style: styles8.header, children: [
1433
+ user.avatar ? /* @__PURE__ */ jsx(Image, { source: { uri: user.avatar }, style: styles8.avatar }) : /* @__PURE__ */ jsx(View, { style: styles8.avatarPlaceholder, children: /* @__PURE__ */ jsx(Text, { style: styles8.avatarText, children: getInitials(user.name, user.email) }) }),
1434
+ /* @__PURE__ */ jsxs(View, { style: styles8.userInfo, children: [
1435
+ user.name && /* @__PURE__ */ jsx(Text, { style: styles8.name, children: user.name }),
1436
+ /* @__PURE__ */ jsx(Text, { style: styles8.email, children: user.email })
1437
+ ] }),
1438
+ onEditPress && /* @__PURE__ */ jsx(TouchableOpacity, { style: styles8.editButton, onPress: onEditPress, children: /* @__PURE__ */ jsx(Text, { style: styles8.editText, children: "Edit" }) })
1439
+ ] }),
1440
+ /* @__PURE__ */ jsx(View, { style: styles8.divider }),
1441
+ /* @__PURE__ */ jsxs(View, { style: styles8.details, children: [
1442
+ /* @__PURE__ */ jsxs(View, { style: styles8.detailRow, children: [
1443
+ /* @__PURE__ */ jsx(Text, { style: styles8.detailLabel, children: "Email" }),
1444
+ /* @__PURE__ */ jsx(Text, { style: styles8.detailValue, children: user.email })
1445
+ ] }),
1446
+ user.phoneNumber && /* @__PURE__ */ jsxs(View, { style: styles8.detailRow, children: [
1447
+ /* @__PURE__ */ jsx(Text, { style: styles8.detailLabel, children: "Phone" }),
1448
+ /* @__PURE__ */ jsx(Text, { style: styles8.detailValue, children: user.phoneNumber })
1449
+ ] }),
1450
+ /* @__PURE__ */ jsxs(View, { style: styles8.detailRow, children: [
1451
+ /* @__PURE__ */ jsx(Text, { style: styles8.detailLabel, children: "Email Verified" }),
1452
+ /* @__PURE__ */ jsx(View, { style: [styles8.badge, user.emailVerified ? styles8.badgeSuccess : styles8.badgeWarning], children: /* @__PURE__ */ jsx(Text, { style: [styles8.badgeText, user.emailVerified ? styles8.badgeTextSuccess : styles8.badgeTextWarning], children: user.emailVerified ? "Verified" : "Not Verified" }) })
1453
+ ] }),
1454
+ user.twoFactorEnabled !== void 0 && /* @__PURE__ */ jsxs(View, { style: styles8.detailRow, children: [
1455
+ /* @__PURE__ */ jsx(Text, { style: styles8.detailLabel, children: "2FA" }),
1456
+ /* @__PURE__ */ jsx(View, { style: [styles8.badge, user.twoFactorEnabled ? styles8.badgeSuccess : styles8.badgeNeutral], children: /* @__PURE__ */ jsx(Text, { style: [styles8.badgeText, user.twoFactorEnabled ? styles8.badgeTextSuccess : styles8.badgeTextNeutral], children: user.twoFactorEnabled ? "Enabled" : "Disabled" }) })
1457
+ ] })
1458
+ ] }),
1459
+ showLogoutButton && /* @__PURE__ */ jsxs(Fragment, { children: [
1460
+ /* @__PURE__ */ jsx(View, { style: styles8.divider }),
1461
+ /* @__PURE__ */ jsx(
1462
+ Button,
1463
+ {
1464
+ title: loading ? "Logging out..." : "Logout",
1465
+ onPress: handleLogout,
1466
+ loading,
1467
+ variant: "outline",
1468
+ style: styles8.logoutButton,
1469
+ textStyle: styles8.logoutText
1470
+ }
1471
+ )
1472
+ ] })
1473
+ ] }) });
1474
+ };
1475
+ var styles8 = StyleSheet.create({
1476
+ container: {
1477
+ padding: 20
1478
+ },
1479
+ card: {
1480
+ backgroundColor: "#FFFFFF",
1481
+ borderRadius: 16,
1482
+ padding: 20,
1483
+ shadowColor: "#000",
1484
+ shadowOffset: { width: 0, height: 2 },
1485
+ shadowOpacity: 0.1,
1486
+ shadowRadius: 8,
1487
+ elevation: 4
1488
+ },
1489
+ header: {
1490
+ flexDirection: "row",
1491
+ alignItems: "center"
1492
+ },
1493
+ avatar: {
1494
+ width: 60,
1495
+ height: 60,
1496
+ borderRadius: 30
1497
+ },
1498
+ avatarPlaceholder: {
1499
+ width: 60,
1500
+ height: 60,
1501
+ borderRadius: 30,
1502
+ backgroundColor: "#4F46E5",
1503
+ alignItems: "center",
1504
+ justifyContent: "center"
1505
+ },
1506
+ avatarText: {
1507
+ color: "#FFFFFF",
1508
+ fontSize: 20,
1509
+ fontWeight: "700"
1510
+ },
1511
+ userInfo: {
1512
+ flex: 1,
1513
+ marginLeft: 16
1514
+ },
1515
+ name: {
1516
+ fontSize: 18,
1517
+ fontWeight: "600",
1518
+ color: "#111827"
1519
+ },
1520
+ email: {
1521
+ fontSize: 14,
1522
+ color: "#6B7280",
1523
+ marginTop: 2
1524
+ },
1525
+ editButton: {
1526
+ padding: 8
1527
+ },
1528
+ editText: {
1529
+ color: "#4F46E5",
1530
+ fontSize: 14,
1531
+ fontWeight: "600"
1532
+ },
1533
+ divider: {
1534
+ height: 1,
1535
+ backgroundColor: "#E5E7EB",
1536
+ marginVertical: 16
1537
+ },
1538
+ details: {
1539
+ gap: 12
1540
+ },
1541
+ detailRow: {
1542
+ flexDirection: "row",
1543
+ justifyContent: "space-between",
1544
+ alignItems: "center"
1545
+ },
1546
+ detailLabel: {
1547
+ fontSize: 14,
1548
+ color: "#6B7280"
1549
+ },
1550
+ detailValue: {
1551
+ fontSize: 14,
1552
+ color: "#111827",
1553
+ fontWeight: "500"
1554
+ },
1555
+ badge: {
1556
+ paddingHorizontal: 10,
1557
+ paddingVertical: 4,
1558
+ borderRadius: 12
1559
+ },
1560
+ badgeSuccess: {
1561
+ backgroundColor: "#D1FAE5"
1562
+ },
1563
+ badgeWarning: {
1564
+ backgroundColor: "#FEF3C7"
1565
+ },
1566
+ badgeNeutral: {
1567
+ backgroundColor: "#F3F4F6"
1568
+ },
1569
+ badgeText: {
1570
+ fontSize: 12,
1571
+ fontWeight: "600"
1572
+ },
1573
+ badgeTextSuccess: {
1574
+ color: "#059669"
1575
+ },
1576
+ badgeTextWarning: {
1577
+ color: "#D97706"
1578
+ },
1579
+ badgeTextNeutral: {
1580
+ color: "#6B7280"
1581
+ },
1582
+ logoutButton: {
1583
+ borderColor: "#EF4444"
1584
+ },
1585
+ logoutText: {
1586
+ color: "#EF4444"
1587
+ },
1588
+ notLoggedIn: {
1589
+ textAlign: "center",
1590
+ color: "#6B7280",
1591
+ fontSize: 16
1592
+ }
1593
+ });
1594
+ var ProtectedRoute = ({
1595
+ children,
1596
+ fallback,
1597
+ loadingComponent
1598
+ }) => {
1599
+ const { isLoaded, isSignedIn } = useAuth();
1600
+ if (!isLoaded) {
1601
+ return loadingComponent || /* @__PURE__ */ jsxs(View, { style: styles9.loadingContainer, children: [
1602
+ /* @__PURE__ */ jsx(ActivityIndicator, { size: "large", color: "#4F46E5" }),
1603
+ /* @__PURE__ */ jsx(Text, { style: styles9.loadingText, children: "Loading..." })
1604
+ ] });
1605
+ }
1606
+ if (!isSignedIn) {
1607
+ return fallback || /* @__PURE__ */ jsxs(View, { style: styles9.unauthorizedContainer, children: [
1608
+ /* @__PURE__ */ jsx(Text, { style: styles9.unauthorizedTitle, children: "Access Denied" }),
1609
+ /* @__PURE__ */ jsx(Text, { style: styles9.unauthorizedText, children: "Please sign in to access this content." })
1610
+ ] });
1611
+ }
1612
+ return /* @__PURE__ */ jsx(Fragment, { children });
1613
+ };
1614
+ var styles9 = StyleSheet.create({
1615
+ loadingContainer: {
1616
+ flex: 1,
1617
+ justifyContent: "center",
1618
+ alignItems: "center",
1619
+ backgroundColor: "#F9FAFB"
1620
+ },
1621
+ loadingText: {
1622
+ marginTop: 12,
1623
+ fontSize: 16,
1624
+ color: "#6B7280"
1625
+ },
1626
+ unauthorizedContainer: {
1627
+ flex: 1,
1628
+ justifyContent: "center",
1629
+ alignItems: "center",
1630
+ padding: 20,
1631
+ backgroundColor: "#F9FAFB"
1632
+ },
1633
+ unauthorizedTitle: {
1634
+ fontSize: 20,
1635
+ fontWeight: "700",
1636
+ color: "#111827",
1637
+ marginBottom: 8
1638
+ },
1639
+ unauthorizedText: {
1640
+ fontSize: 14,
1641
+ color: "#6B7280",
1642
+ textAlign: "center"
1643
+ }
1644
+ });
1645
+
1646
+ export { AuthProvider, AuthServiceRN, Button, ForgotPassword, Input, LoginForm, OtpForm, ProtectedRoute, RegisterForm, ResetPassword, UserProfile, useAuth };
1647
+ //# sourceMappingURL=index.react-native.mjs.map
1648
+ //# sourceMappingURL=index.react-native.mjs.map