create-better-t-stack 3.2.22 → 3.2.23-canary.b8d62867

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 (86) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +1 -1
  3. package/dist/index.d.ts +4 -2
  4. package/dist/index.js +1 -1
  5. package/dist/{src-WIwtBCHf.js → src-VoUvj8ZF.js} +106 -66
  6. package/package.json +1 -1
  7. package/templates/addons/biome/biome.json.hbs +5 -0
  8. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +5 -5
  9. package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +1 -1
  10. package/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs +127 -0
  11. package/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs +138 -0
  12. package/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs +91 -0
  13. package/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs +102 -0
  14. package/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs +186 -0
  15. package/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs +131 -0
  16. package/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs +150 -0
  17. package/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs +9 -1
  18. package/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs +5 -0
  19. package/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs +5 -0
  20. package/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs +123 -0
  21. package/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs +90 -0
  22. package/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs +116 -0
  23. package/templates/auth/better-auth/server/base/src/index.ts.hbs +5 -5
  24. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +287 -0
  25. package/templates/examples/ai/native/{nativewind → bare}/polyfills.js +1 -0
  26. package/templates/examples/ai/native/{nativewind → uniwind}/app/(drawer)/ai.tsx.hbs +52 -51
  27. package/templates/examples/ai/native/uniwind/polyfills.js +26 -0
  28. package/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs +521 -0
  29. package/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs +295 -0
  30. package/templates/extras/bunfig.toml.hbs +3 -3
  31. package/templates/frontend/native/bare/_gitignore +18 -0
  32. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/(tabs)/_layout.tsx.hbs +7 -12
  33. package/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs +43 -0
  34. package/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs +43 -0
  35. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/_layout.tsx.hbs +24 -1
  36. package/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs +234 -0
  37. package/templates/frontend/native/bare/app/+not-found.tsx.hbs +65 -0
  38. package/templates/frontend/native/bare/app/_layout.tsx.hbs +163 -0
  39. package/templates/frontend/native/bare/app/modal.tsx.hbs +34 -0
  40. package/templates/frontend/native/{nativewind → bare}/app.json.hbs +1 -0
  41. package/templates/frontend/native/bare/components/container.tsx.hbs +25 -0
  42. package/templates/frontend/native/bare/components/header-button.tsx.hbs +47 -0
  43. package/templates/frontend/native/{nativewind → bare}/components/tabbar-icon.tsx.hbs +1 -0
  44. package/templates/frontend/native/{nativewind → bare}/lib/android-navigation-bar.tsx.hbs +1 -0
  45. package/templates/frontend/native/{nativewind → bare}/lib/constants.ts.hbs +1 -0
  46. package/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs +20 -0
  47. package/templates/frontend/native/bare/metro.config.js.hbs +9 -0
  48. package/templates/frontend/native/{nativewind → bare}/package.json.hbs +1 -2
  49. package/templates/frontend/native/bare/tsconfig.json.hbs +11 -0
  50. package/templates/frontend/native/{nativewind → uniwind}/_gitignore +4 -8
  51. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs +46 -0
  52. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs +15 -0
  53. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs +15 -0
  54. package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +83 -0
  55. package/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs +151 -0
  56. package/templates/frontend/native/uniwind/app/+not-found.tsx.hbs +32 -0
  57. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +131 -0
  58. package/templates/frontend/native/uniwind/app/modal.tsx.hbs +53 -0
  59. package/templates/frontend/native/uniwind/app.json.hbs +19 -0
  60. package/templates/frontend/native/uniwind/components/container.tsx.hbs +33 -0
  61. package/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs +35 -0
  62. package/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs +62 -0
  63. package/templates/frontend/native/uniwind/global.css +5 -0
  64. package/templates/frontend/native/uniwind/metro.config.js.hbs +13 -0
  65. package/templates/frontend/native/uniwind/package.json.hbs +54 -0
  66. package/templates/frontend/native/{nativewind → uniwind}/tsconfig.json.hbs +4 -8
  67. package/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs +0 -86
  68. package/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs +0 -97
  69. package/templates/auth/better-auth/native/nativewind/app/(drawer)/index.tsx.hbs +0 -95
  70. package/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs +0 -93
  71. package/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs +0 -104
  72. package/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs +0 -295
  73. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs +0 -19
  74. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs +0 -19
  75. package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +0 -178
  76. package/templates/frontend/native/nativewind/app/+not-found.tsx.hbs +0 -29
  77. package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +0 -175
  78. package/templates/frontend/native/nativewind/app/modal.tsx.hbs +0 -14
  79. package/templates/frontend/native/nativewind/babel.config.js.hbs +0 -14
  80. package/templates/frontend/native/nativewind/components/container.tsx.hbs +0 -8
  81. package/templates/frontend/native/nativewind/components/header-button.tsx.hbs +0 -26
  82. package/templates/frontend/native/nativewind/global.css +0 -50
  83. package/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs +0 -12
  84. package/templates/frontend/native/nativewind/metro.config.js.hbs +0 -12
  85. package/templates/frontend/native/nativewind/tailwind.config.js.hbs +0 -59
  86. /package/templates/auth/clerk/convex/native/base/app/(auth)/{sign-out.tsx.hbs → sign-up.tsx.hbs} +0 -0
@@ -0,0 +1,5 @@
1
+ @import 'tailwindcss';
2
+ @import 'uniwind';
3
+ @import 'heroui-native/styles';
4
+
5
+ @source './node_modules/heroui-native/lib';
@@ -0,0 +1,13 @@
1
+ const { getDefaultConfig } = require("expo/metro-config");
2
+ const { withUniwindConfig } = require("uniwind/metro");
3
+
4
+ /** @type {import('expo/metro-config').MetroConfig} */
5
+ const config = getDefaultConfig(__dirname);
6
+
7
+ const uniwindConfig = withUniwindConfig(config, {
8
+ cssEntryFile: "./global.css",
9
+ dtsFile: "./uniwind-types.d.ts",
10
+ });
11
+
12
+ module.exports = uniwindConfig;
13
+
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "native",
3
+ "version": "1.0.0",
4
+ "main": "expo-router/entry",
5
+ "scripts": {
6
+ "start": "expo start",
7
+ "dev": "expo start --clear",
8
+ "android": "expo run:android",
9
+ "ios": "expo run:ios",
10
+ "prebuild": "expo prebuild",
11
+ "web": "expo start --web"
12
+ },
13
+ "dependencies": {
14
+ "@expo/metro-runtime": "~6.1.2",
15
+ "@expo/vector-icons": "^15.0.3",
16
+ "@gorhom/bottom-sheet": "^5",
17
+ "@react-navigation/drawer": "^7.3.9",
18
+ "@react-navigation/elements": "^2.8.1",
19
+ {{#if (includes examples "ai")}}
20
+ "@stardazed/streams-text-encoding": "^1.0.2",
21
+ "@ungap/structured-clone": "^1.3.0",
22
+ {{/if}}
23
+ "expo": "^54.0.23",
24
+ "expo-constants": "~18.0.10",
25
+ "expo-font": "~14.0.9",
26
+ "expo-haptics": "^15.0.7",
27
+ "expo-linking": "~8.0.8",
28
+ "expo-router": "~6.0.14",
29
+ "expo-secure-store": "~15.0.7",
30
+ "expo-status-bar": "~3.0.8",
31
+ "heroui-native": "^1.0.0-beta.1",
32
+ "react": "19.1.0",
33
+ "react-dom": "19.1.0",
34
+ "react-native": "0.81.5",
35
+ "react-native-gesture-handler": "~2.28.0",
36
+ "react-native-keyboard-controller": "1.18.5",
37
+ "react-native-reanimated": "~4.1.0",
38
+ "react-native-safe-area-context": "5.6.0",
39
+ "react-native-screens": "~4.16.0",
40
+ "react-native-svg": "15.12.1",
41
+ "react-native-web": "^0.21.0",
42
+ "react-native-worklets": "0.5.1",
43
+ "tailwind-merge": "^3.3.1",
44
+ "tailwind-variants": "^3.1.0",
45
+ "tailwindcss": "~4.1.16",
46
+ "uniwind": "^1.0.0"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^24.10.0",
50
+ "@types/react": "~19.1.0",
51
+ "typescript": "~5.9.2"
52
+ },
53
+ "private": true
54
+ }
@@ -2,17 +2,13 @@
2
2
  "extends": "expo/tsconfig.base",
3
3
  "compilerOptions": {
4
4
  "strict": true,
5
+ "baseUrl": ".",
5
6
  "paths": {
6
- "@/*": [
7
- "./*"
8
- ]
7
+ "@/*": ["./*"]
9
8
  }
10
9
  },
11
10
  "include": [
12
11
  "**/*.ts",
13
- "**/*.tsx",
14
- ".expo/types/**/*.ts",
15
- "expo-env.d.ts",
16
- "nativewind-env.d.ts"
12
+ "**/*.tsx"
17
13
  ]
18
- }
14
+ }
@@ -1,86 +0,0 @@
1
- import { authClient } from "@/lib/auth-client";
2
- import { useState } from "react";
3
- import {
4
- ActivityIndicator,
5
- Text,
6
- TextInput,
7
- TouchableOpacity,
8
- View,
9
- } from "react-native";
10
-
11
- export function SignIn() {
12
- const [email, setEmail] = useState("");
13
- const [password, setPassword] = useState("");
14
- const [isLoading, setIsLoading] = useState(false);
15
- const [error, setError] = useState<string | null>(null);
16
-
17
- const handleLogin = async () => {
18
- setIsLoading(true);
19
- setError(null);
20
-
21
- await authClient.signIn.email(
22
- {
23
- email,
24
- password,
25
- },
26
- {
27
- onError: (error) => {
28
- setError(error.error?.message || "Failed to sign in");
29
- setIsLoading(false);
30
- },
31
- onSuccess: () => {
32
- setEmail("");
33
- setPassword("");
34
- },
35
- onFinished: () => {
36
- setIsLoading(false);
37
- },
38
- },
39
- );
40
- };
41
-
42
- return (
43
- <View className="mt-6 p-4 bg-card rounded-lg border border-border">
44
- <Text className="text-lg font-semibold text-foreground mb-4">
45
- Sign In
46
- </Text>
47
-
48
- {error && (
49
- <View className="mb-4 p-3 bg-destructive/10 rounded-md">
50
- <Text className="text-destructive text-sm">{error}</Text>
51
- </View>
52
- )}
53
-
54
- <TextInput
55
- className="mb-3 p-4 rounded-md bg-input text-foreground border border-input"
56
- placeholder="Email"
57
- value={email}
58
- onChangeText={setEmail}
59
- placeholderTextColor="#9CA3AF"
60
- keyboardType="email-address"
61
- autoCapitalize="none"
62
- />
63
-
64
- <TextInput
65
- className="mb-4 p-4 rounded-md bg-input text-foreground border border-input"
66
- placeholder="Password"
67
- value={password}
68
- onChangeText={setPassword}
69
- placeholderTextColor="#9CA3AF"
70
- secureTextEntry
71
- />
72
-
73
- <TouchableOpacity
74
- onPress={handleLogin}
75
- disabled={isLoading}
76
- className="bg-primary p-4 rounded-md flex-row justify-center items-center"
77
- >
78
- {isLoading ? (
79
- <ActivityIndicator size="small" color="#fff" />
80
- ) : (
81
- <Text className="text-primary-foreground font-medium">Sign In</Text>
82
- )}
83
- </TouchableOpacity>
84
- </View>
85
- );
86
- }
@@ -1,97 +0,0 @@
1
- import { authClient } from "@/lib/auth-client";
2
- import { useState } from "react";
3
- import {
4
- ActivityIndicator,
5
- Text,
6
- TextInput,
7
- TouchableOpacity,
8
- View,
9
- } from "react-native";
10
-
11
- export function SignUp() {
12
- const [name, setName] = useState("");
13
- const [email, setEmail] = useState("");
14
- const [password, setPassword] = useState("");
15
- const [isLoading, setIsLoading] = useState(false);
16
- const [error, setError] = useState<string | null>(null);
17
-
18
- const handleSignUp = async () => {
19
- setIsLoading(true);
20
- setError(null);
21
-
22
- await authClient.signUp.email(
23
- {
24
- name,
25
- email,
26
- password,
27
- },
28
- {
29
- onError: (error) => {
30
- setError(error.error?.message || "Failed to sign up");
31
- setIsLoading(false);
32
- },
33
- onSuccess: () => {
34
- setName("");
35
- setEmail("");
36
- setPassword("");
37
- },
38
- onFinished: () => {
39
- setIsLoading(false);
40
- },
41
- },
42
- );
43
- };
44
-
45
- return (
46
- <View className="mt-6 p-4 bg-card rounded-lg border border-border">
47
- <Text className="text-lg font-semibold text-foreground mb-4">
48
- Create Account
49
- </Text>
50
-
51
- {error && (
52
- <View className="mb-4 p-3 bg-destructive/10 rounded-md">
53
- <Text className="text-destructive text-sm">{error}</Text>
54
- </View>
55
- )}
56
-
57
- <TextInput
58
- className="mb-3 p-4 rounded-md bg-input text-foreground border border-input"
59
- placeholder="Name"
60
- value={name}
61
- onChangeText={setName}
62
- placeholderTextColor="#9CA3AF"
63
- />
64
-
65
- <TextInput
66
- className="mb-3 p-4 rounded-md bg-input text-foreground border border-input"
67
- placeholder="Email"
68
- value={email}
69
- onChangeText={setEmail}
70
- placeholderTextColor="#9CA3AF"
71
- keyboardType="email-address"
72
- autoCapitalize="none"
73
- />
74
-
75
- <TextInput
76
- className="mb-4 p-4 rounded-md bg-input text-foreground border border-input"
77
- placeholder="Password"
78
- value={password}
79
- onChangeText={setPassword}
80
- placeholderTextColor="#9CA3AF"
81
- secureTextEntry
82
- />
83
-
84
- <TouchableOpacity
85
- onPress={handleSignUp}
86
- disabled={isLoading}
87
- className="bg-primary p-4 rounded-md flex-row justify-center items-center"
88
- >
89
- {isLoading ? (
90
- <ActivityIndicator size="small" color="#fff" />
91
- ) : (
92
- <Text className="text-primary-foreground font-medium">Sign Up</Text>
93
- )}
94
- </TouchableOpacity>
95
- </View>
96
- );
97
- }
@@ -1,95 +0,0 @@
1
- import { authClient } from "@/lib/auth-client";
2
- import { useQuery } from "@tanstack/react-query";
3
- import { ScrollView, Text, TouchableOpacity, View } from "react-native";
4
-
5
- import { Container } from "@/components/container";
6
- import { SignIn } from "@/components/sign-in";
7
- import { SignUp } from "@/components/sign-up";
8
- {{#if (eq api "orpc")}}
9
- import { queryClient, orpc } from "@/utils/orpc";
10
- {{/if}}
11
- {{#if (eq api "trpc")}}
12
- import { queryClient, trpc } from "@/utils/trpc";
13
- {{/if}}
14
-
15
- export default function Home() {
16
- {{#if (eq api "orpc")}}
17
- const healthCheck = useQuery(orpc.healthCheck.queryOptions());
18
- const privateData = useQuery(orpc.privateData.queryOptions());
19
- {{/if}}
20
- {{#if (eq api "trpc")}}
21
- const healthCheck = useQuery(trpc.healthCheck.queryOptions());
22
- const privateData = useQuery(trpc.privateData.queryOptions());
23
- {{/if}}
24
- const { data: session } = authClient.useSession();
25
-
26
- return (
27
- <Container>
28
- <ScrollView className="flex-1">
29
- <View className="px-4">
30
- <Text className="font-mono text-foreground text-3xl font-bold mb-4">
31
- BETTER T STACK
32
- </Text>
33
- {session?.user ? (
34
- <View className="mb-6 p-4 bg-card rounded-lg border border-border">
35
- <View className="flex-row justify-between items-center mb-2">
36
- <Text className="text-foreground text-base">
37
- Welcome,{" "}
38
- <Text className="font-medium">{session.user.name}</Text>
39
- </Text>
40
- </View>
41
- <Text className="text-muted-foreground text-sm mb-4">
42
- {session.user.email}
43
- </Text>
44
-
45
- <TouchableOpacity
46
- className="bg-destructive py-2 px-4 rounded-md self-start"
47
- onPress={() => {
48
- authClient.signOut();
49
- queryClient.invalidateQueries();
50
- }}
51
- >
52
- <Text className="text-white font-medium">Sign Out</Text>
53
- </TouchableOpacity>
54
- </View>
55
- ) : null}
56
- <View className="mb-6 rounded-lg border border-border p-4">
57
- <Text className="mb-3 font-medium text-foreground">API Status</Text>
58
- <View className="flex-row items-center gap-2">
59
- <View
60
- className={`h-3 w-3 rounded-full ${
61
- healthCheck.data ? "bg-green-500" : "bg-red-500"
62
- }`}
63
- />
64
- <Text className="text-muted-foreground">
65
- {healthCheck.isLoading
66
- ? "Checking..."
67
- : healthCheck.data
68
- ? "Connected to API"
69
- : "API Disconnected"}
70
- </Text>
71
- </View>
72
- </View>
73
- <View className="mb-6 rounded-lg border border-border p-4">
74
- <Text className="mb-3 font-medium text-foreground">
75
- Private Data
76
- </Text>
77
- {privateData && (
78
- <View>
79
- <Text className="text-muted-foreground">
80
- {privateData.data?.message}
81
- </Text>
82
- </View>
83
- )}
84
- </View>
85
- {!session?.user && (
86
- <>
87
- <SignIn />
88
- <SignUp />
89
- </>
90
- )}
91
- </View>
92
- </ScrollView>
93
- </Container>
94
- );
95
- }
@@ -1,93 +0,0 @@
1
- import { authClient } from "@/lib/auth-client";
2
- {{#if (eq api "trpc")}}
3
- import { queryClient } from "@/utils/trpc";
4
- {{/if}}
5
- {{#if (eq api "orpc")}}
6
- import { queryClient } from "@/utils/orpc";
7
- {{/if}}
8
- import { useState } from "react";
9
- import {
10
- ActivityIndicator,
11
- Text,
12
- TextInput,
13
- TouchableOpacity,
14
- View,
15
- } from "react-native";
16
-
17
- export function SignIn() {
18
- const [email, setEmail] = useState("");
19
- const [password, setPassword] = useState("");
20
- const [isLoading, setIsLoading] = useState(false);
21
- const [error, setError] = useState<string | null>(null);
22
-
23
- const handleLogin = async () => {
24
- setIsLoading(true);
25
- setError(null);
26
-
27
- await authClient.signIn.email(
28
- {
29
- email,
30
- password,
31
- },
32
- {
33
- onError: (error) => {
34
- setError(error.error?.message || "Failed to sign in");
35
- setIsLoading(false);
36
- },
37
- onSuccess: () => {
38
- setEmail("");
39
- setPassword("");
40
- queryClient.refetchQueries();
41
- },
42
- onFinished: () => {
43
- setIsLoading(false);
44
- },
45
- },
46
- );
47
- };
48
-
49
- return (
50
- <View className="mt-6 p-4 bg-card rounded-lg border border-border">
51
- <Text className="text-lg font-semibold text-foreground mb-4">
52
- Sign In
53
- </Text>
54
-
55
- {error && (
56
- <View className="mb-4 p-3 bg-destructive/10 rounded-md">
57
- <Text className="text-destructive text-sm">{error}</Text>
58
- </View>
59
- )}
60
-
61
- <TextInput
62
- className="mb-3 p-4 rounded-md bg-input text-foreground border border-input"
63
- placeholder="Email"
64
- value={email}
65
- onChangeText={setEmail}
66
- placeholderTextColor="#9CA3AF"
67
- keyboardType="email-address"
68
- autoCapitalize="none"
69
- />
70
-
71
- <TextInput
72
- className="mb-4 p-4 rounded-md bg-input text-foreground border border-input"
73
- placeholder="Password"
74
- value={password}
75
- onChangeText={setPassword}
76
- placeholderTextColor="#9CA3AF"
77
- secureTextEntry
78
- />
79
-
80
- <TouchableOpacity
81
- onPress={handleLogin}
82
- disabled={isLoading}
83
- className="bg-primary p-4 rounded-md flex-row justify-center items-center"
84
- >
85
- {isLoading ? (
86
- <ActivityIndicator size="small" color="#fff" />
87
- ) : (
88
- <Text className="text-primary-foreground font-medium">Sign In</Text>
89
- )}
90
- </TouchableOpacity>
91
- </View>
92
- );
93
- }
@@ -1,104 +0,0 @@
1
- import { authClient } from "@/lib/auth-client";
2
- {{#if (eq api "trpc")}}
3
- import { queryClient } from "@/utils/trpc";
4
- {{/if}}
5
- {{#if (eq api "orpc")}}
6
- import { queryClient } from "@/utils/orpc";
7
- {{/if}}
8
- import { useState } from "react";
9
- import {
10
- ActivityIndicator,
11
- Text,
12
- TextInput,
13
- TouchableOpacity,
14
- View,
15
- } from "react-native";
16
-
17
- export function SignUp() {
18
- const [name, setName] = useState("");
19
- const [email, setEmail] = useState("");
20
- const [password, setPassword] = useState("");
21
- const [isLoading, setIsLoading] = useState(false);
22
- const [error, setError] = useState<string | null>(null);
23
-
24
- const handleSignUp = async () => {
25
- setIsLoading(true);
26
- setError(null);
27
-
28
- await authClient.signUp.email(
29
- {
30
- name,
31
- email,
32
- password,
33
- },
34
- {
35
- onError: (error) => {
36
- setError(error.error?.message || "Failed to sign up");
37
- setIsLoading(false);
38
- },
39
- onSuccess: () => {
40
- setName("");
41
- setEmail("");
42
- setPassword("");
43
- queryClient.refetchQueries();
44
- },
45
- onFinished: () => {
46
- setIsLoading(false);
47
- },
48
- },
49
- );
50
- };
51
-
52
- return (
53
- <View className="mt-6 p-4 bg-card rounded-lg border border-border">
54
- <Text className="text-lg font-semibold text-foreground mb-4">
55
- Create Account
56
- </Text>
57
-
58
- {error && (
59
- <View className="mb-4 p-3 bg-destructive/10 rounded-md">
60
- <Text className="text-destructive text-sm">{error}</Text>
61
- </View>
62
- )}
63
-
64
- <TextInput
65
- className="mb-3 p-4 rounded-md bg-input text-foreground border border-input"
66
- placeholder="Name"
67
- value={name}
68
- onChangeText={setName}
69
- placeholderTextColor="#9CA3AF"
70
- />
71
-
72
- <TextInput
73
- className="mb-3 p-4 rounded-md bg-input text-foreground border border-input"
74
- placeholder="Email"
75
- value={email}
76
- onChangeText={setEmail}
77
- placeholderTextColor="#9CA3AF"
78
- keyboardType="email-address"
79
- autoCapitalize="none"
80
- />
81
-
82
- <TextInput
83
- className="mb-4 p-4 rounded-md bg-input text-foreground border border-input"
84
- placeholder="Password"
85
- value={password}
86
- onChangeText={setPassword}
87
- placeholderTextColor="#9CA3AF"
88
- secureTextEntry
89
- />
90
-
91
- <TouchableOpacity
92
- onPress={handleSignUp}
93
- disabled={isLoading}
94
- className="bg-primary p-4 rounded-md flex-row justify-center items-center"
95
- >
96
- {isLoading ? (
97
- <ActivityIndicator size="small" color="#fff" />
98
- ) : (
99
- <Text className="text-primary-foreground font-medium">Sign Up</Text>
100
- )}
101
- </TouchableOpacity>
102
- </View>
103
- );
104
- }