create-better-t-stack 3.1.8-canary.65dbf382 → 3.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-EpWSiOd8.js → src-DeOVz-ZI.js} +13 -51
- package/package.json +1 -1
- package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +33 -45
- package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +1 -1
- package/templates/auth/better-auth/native/{base → native-base}/lib/auth-client.ts.hbs +2 -3
- package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +100 -151
- package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +0 -21
- package/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs +91 -201
- package/templates/frontend/native/unistyles/app/_layout.tsx.hbs +0 -28
- package/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs +0 -19
- package/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs +0 -86
- package/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs +0 -97
- package/templates/auth/better-auth/convex/native/unistyles/components/sign-in.tsx.hbs +0 -127
- package/templates/auth/better-auth/convex/native/unistyles/components/sign-up.tsx.hbs +0 -145
- /package/templates/frontend/native/{base → native-base}/assets/images/android-icon-background.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/android-icon-foreground.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/android-icon-monochrome.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/favicon.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/icon.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/partial-react-logo.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/react-logo.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/react-logo@2x.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/react-logo@3x.png +0 -0
- /package/templates/frontend/native/{base → native-base}/assets/images/splash-icon.png +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ScrollView, Text, View
|
|
1
|
+
import { ScrollView, Text, View } from "react-native";
|
|
2
2
|
import { StyleSheet } from "react-native-unistyles";
|
|
3
3
|
import { Container } from "@/components/container";
|
|
4
4
|
|
|
@@ -11,47 +11,33 @@ import { useQuery } from "@tanstack/react-query";
|
|
|
11
11
|
import { trpc } from "@/utils/trpc";
|
|
12
12
|
{{/if}}
|
|
13
13
|
{{#if (eq backend "convex")}}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
import { authClient } from "@/lib/auth-client";
|
|
25
|
-
import { SignIn } from "@/components/sign-in";
|
|
26
|
-
import { SignUp } from "@/components/sign-up";
|
|
27
|
-
{{else}}
|
|
28
|
-
import { useQuery } from "convex/react";
|
|
29
|
-
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
|
|
30
|
-
{{/if}}
|
|
31
|
-
{{/if}}
|
|
14
|
+
{{#if (eq auth "clerk")}}
|
|
15
|
+
import { Link } from "expo-router";
|
|
16
|
+
import { Authenticated, AuthLoading, Unauthenticated, useQuery } from "convex/react";
|
|
17
|
+
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
|
|
18
|
+
import { useUser } from "@clerk/clerk-expo";
|
|
19
|
+
import { SignOutButton } from "@/components/sign-out-button";
|
|
20
|
+
{{else}}
|
|
21
|
+
import { useQuery } from "convex/react";
|
|
22
|
+
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
|
|
23
|
+
{{/if}}
|
|
32
24
|
{{/if}}
|
|
33
25
|
|
|
34
26
|
export default function Home() {
|
|
35
27
|
{{#if (eq api "orpc")}}
|
|
36
|
-
|
|
28
|
+
const healthCheck = useQuery(orpc.healthCheck.queryOptions());
|
|
37
29
|
{{/if}}
|
|
38
30
|
{{#if (eq api "trpc")}}
|
|
39
|
-
|
|
31
|
+
const healthCheck = useQuery(trpc.healthCheck.queryOptions());
|
|
40
32
|
{{/if}}
|
|
41
33
|
{{#if (eq backend "convex")}}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const { isAuthenticated } = useConvexAuth();
|
|
50
|
-
const user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : "skip");
|
|
51
|
-
{{else}}
|
|
52
|
-
const healthCheck = useQuery(api.healthCheck.get);
|
|
53
|
-
{{/if}}
|
|
54
|
-
{{/if}}
|
|
34
|
+
{{#if (eq auth "clerk")}}
|
|
35
|
+
const { user } = useUser();
|
|
36
|
+
const healthCheck = useQuery(api.healthCheck.get);
|
|
37
|
+
const privateData = useQuery(api.privateData.get);
|
|
38
|
+
{{else}}
|
|
39
|
+
const healthCheck = useQuery(api.healthCheck.get);
|
|
40
|
+
{{/if}}
|
|
55
41
|
{{/if}}
|
|
56
42
|
|
|
57
43
|
return (
|
|
@@ -68,125 +54,86 @@ export default function Home() {
|
|
|
68
54
|
<Text style={styles.statusBadgeText}>LIVE</Text>
|
|
69
55
|
</View>
|
|
70
56
|
</View>
|
|
57
|
+
|
|
71
58
|
{{#if (eq backend "convex")}}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
</View>
|
|
93
|
-
{{/unless}}
|
|
59
|
+
<View style={styles.statusRow}>
|
|
60
|
+
<View
|
|
61
|
+
style={[
|
|
62
|
+
styles.statusDot,
|
|
63
|
+
healthCheck === "OK"
|
|
64
|
+
? styles.statusDotSuccess
|
|
65
|
+
: styles.statusDotWarning,
|
|
66
|
+
]}
|
|
67
|
+
/>
|
|
68
|
+
<View style={styles.statusContent}>
|
|
69
|
+
<Text style={styles.statusLabel}>Convex</Text>
|
|
70
|
+
<Text style={styles.statusDescription}>
|
|
71
|
+
{healthCheck === undefined
|
|
72
|
+
? "Checking connection..."
|
|
73
|
+
: healthCheck === "OK"
|
|
74
|
+
? "All systems operational"
|
|
75
|
+
: "Service unavailable"}
|
|
76
|
+
</Text>
|
|
77
|
+
</View>
|
|
78
|
+
</View>
|
|
94
79
|
{{else}}
|
|
95
80
|
{{#unless (eq api "none")}}
|
|
96
|
-
|
|
97
|
-
<View
|
|
98
|
-
style={[
|
|
99
|
-
styles.statusDot,
|
|
100
|
-
healthCheck.data
|
|
101
|
-
? styles.statusDotSuccess
|
|
102
|
-
: styles.statusDotWarning,
|
|
103
|
-
]}
|
|
104
|
-
/>
|
|
105
|
-
<View style={styles.statusContent}>
|
|
106
|
-
<Text style={styles.statusLabel}>
|
|
107
|
-
{{#if (eq api "orpc")}}ORPC{{/if}}
|
|
108
|
-
{{#if (eq api "trpc")}}TRPC{{/if}}
|
|
109
|
-
</Text>
|
|
110
|
-
<Text style={styles.statusDescription}>
|
|
111
|
-
{(healthCheck.isLoading)
|
|
112
|
-
? "Checking connection..."
|
|
113
|
-
: healthCheck.data
|
|
114
|
-
? "All systems operational"
|
|
115
|
-
: "Service unavailable"}
|
|
116
|
-
</Text>
|
|
117
|
-
</View>
|
|
118
|
-
</View>
|
|
119
|
-
{{/unless}}
|
|
120
|
-
{{/if}}
|
|
121
|
-
</View>
|
|
122
|
-
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
|
|
123
|
-
<Authenticated>
|
|
124
|
-
<Text>
|
|
125
|
-
Hello {user?.emailAddresses[0].emailAddress}
|
|
126
|
-
</Text>
|
|
127
|
-
<Text>
|
|
128
|
-
Private Data: {privateData?.message}
|
|
129
|
-
</Text>
|
|
130
|
-
<SignOutButton />
|
|
131
|
-
</Authenticated>
|
|
132
|
-
<Unauthenticated>
|
|
133
|
-
<Link href="/(auth)/sign-in">
|
|
134
|
-
<Text>Sign in</Text>
|
|
135
|
-
</Link>
|
|
136
|
-
<Link href="/(auth)/sign-up">
|
|
137
|
-
<Text>Sign up</Text>
|
|
138
|
-
</Link>
|
|
139
|
-
</Unauthenticated>
|
|
140
|
-
<AuthLoading>
|
|
141
|
-
<Text>Loading...</Text>
|
|
142
|
-
</AuthLoading>
|
|
143
|
-
{{/if}}
|
|
144
|
-
{{#if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
145
|
-
{user ? (
|
|
146
|
-
<View style={styles.userCard}>
|
|
147
|
-
<View style={styles.userHeader}>
|
|
148
|
-
<Text style={styles.userWelcome}>
|
|
149
|
-
Welcome,{" "}
|
|
150
|
-
<Text style={styles.userName}>{user.name}</Text>
|
|
151
|
-
</Text>
|
|
152
|
-
</View>
|
|
153
|
-
<Text style={styles.userEmail}>{user.email}</Text>
|
|
154
|
-
<TouchableOpacity
|
|
155
|
-
style={styles.signOutButton}
|
|
156
|
-
onPress={() => {
|
|
157
|
-
authClient.signOut();
|
|
158
|
-
}}
|
|
159
|
-
>
|
|
160
|
-
<Text style={styles.signOutText}>Sign Out</Text>
|
|
161
|
-
</TouchableOpacity>
|
|
162
|
-
</View>
|
|
163
|
-
) : null}
|
|
164
|
-
<View style={styles.apiStatusCard}>
|
|
165
|
-
<Text style={styles.apiStatusTitle}>API Status</Text>
|
|
166
|
-
<View style={styles.apiStatusRow}>
|
|
81
|
+
<View style={styles.statusRow}>
|
|
167
82
|
<View
|
|
168
83
|
style={[
|
|
169
84
|
styles.statusDot,
|
|
170
|
-
healthCheck
|
|
85
|
+
healthCheck.data
|
|
171
86
|
? styles.statusDotSuccess
|
|
172
87
|
: styles.statusDotWarning,
|
|
173
88
|
]}
|
|
174
89
|
/>
|
|
175
|
-
<
|
|
176
|
-
{
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
90
|
+
<View style={styles.statusContent}>
|
|
91
|
+
<Text style={styles.statusLabel}>
|
|
92
|
+
{{#if (eq api "orpc")}}
|
|
93
|
+
ORPC
|
|
94
|
+
{{/if}}
|
|
95
|
+
{{#if (eq api "trpc")}}
|
|
96
|
+
TRPC
|
|
97
|
+
{{/if}}
|
|
98
|
+
</Text>
|
|
99
|
+
<Text style={styles.statusDescription}>
|
|
100
|
+
{{#if (eq api "orpc")}}
|
|
101
|
+
{healthCheck.isLoading
|
|
102
|
+
? "Checking connection..."
|
|
103
|
+
: healthCheck.data
|
|
104
|
+
? "All systems operational"
|
|
105
|
+
: "Service unavailable"}
|
|
106
|
+
{{/if}}
|
|
107
|
+
{{#if (eq api "trpc")}}
|
|
108
|
+
{healthCheck.isLoading
|
|
109
|
+
? "Checking connection..."
|
|
110
|
+
: healthCheck.data
|
|
111
|
+
? "All systems operational"
|
|
112
|
+
: "Service unavailable"}
|
|
113
|
+
{{/if}}
|
|
114
|
+
</Text>
|
|
115
|
+
</View>
|
|
182
116
|
</View>
|
|
183
|
-
|
|
184
|
-
{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
117
|
+
{{/unless}}
|
|
118
|
+
{{/if}}
|
|
119
|
+
</View>
|
|
120
|
+
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
|
|
121
|
+
<Authenticated>
|
|
122
|
+
<Text>Hello {user?.emailAddresses[0].emailAddress}</Text>
|
|
123
|
+
<Text>Private Data: {privateData?.message}</Text>
|
|
124
|
+
<SignOutButton />
|
|
125
|
+
</Authenticated>
|
|
126
|
+
<Unauthenticated>
|
|
127
|
+
<Link href="/(auth)/sign-in">
|
|
128
|
+
<Text>Sign in</Text>
|
|
129
|
+
</Link>
|
|
130
|
+
<Link href="/(auth)/sign-up">
|
|
131
|
+
<Text>Sign up</Text>
|
|
132
|
+
</Link>
|
|
133
|
+
</Unauthenticated>
|
|
134
|
+
<AuthLoading>
|
|
135
|
+
<Text>Loading...</Text>
|
|
136
|
+
</AuthLoading>
|
|
190
137
|
{{/if}}
|
|
191
138
|
</ScrollView>
|
|
192
139
|
</Container>
|
|
@@ -273,62 +220,5 @@ const styles = StyleSheet.create((theme) => ({
|
|
|
273
220
|
statusDescription: {
|
|
274
221
|
fontSize: theme.fontSize.xs,
|
|
275
222
|
color: theme.colors.mutedForeground,
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
backgroundColor: theme.colors.card,
|
|
279
|
-
borderWidth: 1,
|
|
280
|
-
borderColor: theme.colors.border,
|
|
281
|
-
borderRadius: theme.borderRadius.lg,
|
|
282
|
-
padding: theme.spacing.md,
|
|
283
|
-
marginBottom: theme.spacing.md,
|
|
284
|
-
},
|
|
285
|
-
userHeader: {
|
|
286
|
-
flexDirection: "row",
|
|
287
|
-
justifyContent: "space-between",
|
|
288
|
-
alignItems: "center",
|
|
289
|
-
marginBottom: theme.spacing.xs,
|
|
290
|
-
},
|
|
291
|
-
userWelcome: {
|
|
292
|
-
fontSize: theme.fontSize.base,
|
|
293
|
-
color: theme.colors.foreground,
|
|
294
|
-
},
|
|
295
|
-
userName: {
|
|
296
|
-
fontWeight: "500",
|
|
297
|
-
},
|
|
298
|
-
userEmail: {
|
|
299
|
-
fontSize: theme.fontSize.sm,
|
|
300
|
-
color: theme.colors.mutedForeground,
|
|
301
|
-
marginBottom: theme.spacing.md,
|
|
302
|
-
},
|
|
303
|
-
signOutButton: {
|
|
304
|
-
backgroundColor: theme.colors.destructive,
|
|
305
|
-
paddingVertical: theme.spacing.sm,
|
|
306
|
-
paddingHorizontal: theme.spacing.md,
|
|
307
|
-
borderRadius: theme.borderRadius.md,
|
|
308
|
-
alignSelf: "flex-start",
|
|
309
|
-
},
|
|
310
|
-
signOutText: {
|
|
311
|
-
color: theme.colors.destructiveForeground,
|
|
312
|
-
fontWeight: "500",
|
|
313
|
-
},
|
|
314
|
-
apiStatusCard: {
|
|
315
|
-
marginBottom: theme.spacing.md,
|
|
316
|
-
borderRadius: theme.borderRadius.lg,
|
|
317
|
-
borderWidth: 1,
|
|
318
|
-
borderColor: theme.colors.border,
|
|
319
|
-
padding: theme.spacing.md,
|
|
320
|
-
},
|
|
321
|
-
apiStatusTitle: {
|
|
322
|
-
marginBottom: theme.spacing.sm,
|
|
323
|
-
fontWeight: "500",
|
|
324
|
-
color: theme.colors.foreground,
|
|
325
|
-
},
|
|
326
|
-
apiStatusRow: {
|
|
327
|
-
flexDirection: "row",
|
|
328
|
-
alignItems: "center",
|
|
329
|
-
gap: theme.spacing.xs,
|
|
330
|
-
},
|
|
331
|
-
apiStatusText: {
|
|
332
|
-
color: theme.colors.mutedForeground,
|
|
333
|
-
},
|
|
334
|
-
}));
|
|
223
|
+
}
|
|
224
|
+
}));
|
|
@@ -8,13 +8,7 @@ import { queryClient } from "@/utils/trpc";
|
|
|
8
8
|
import { queryClient } from "@/utils/orpc";
|
|
9
9
|
{{/if}}
|
|
10
10
|
{{#if (eq backend "convex")}}
|
|
11
|
-
{{#if (eq auth "better-auth")}}
|
|
12
|
-
import { ConvexReactClient } from "convex/react";
|
|
13
|
-
import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
|
|
14
|
-
import { authClient } from "@/lib/auth-client";
|
|
15
|
-
{{else}}
|
|
16
11
|
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
|
17
|
-
{{/if}}
|
|
18
12
|
{{#if (eq auth "clerk")}}
|
|
19
13
|
import { ClerkProvider, useAuth } from "@clerk/clerk-expo";
|
|
20
14
|
import { ConvexProviderWithClerk } from "convex/react-clerk";
|
|
@@ -73,28 +67,6 @@ export default function RootLayout() {
|
|
|
73
67
|
</GestureHandlerRootView>
|
|
74
68
|
</ConvexProviderWithClerk>
|
|
75
69
|
</ClerkProvider>
|
|
76
|
-
{{else if (eq auth "better-auth")}}
|
|
77
|
-
<ConvexBetterAuthProvider client={convex} authClient={authClient}>
|
|
78
|
-
<GestureHandlerRootView style=\{{ flex: 1 }}>
|
|
79
|
-
<Stack
|
|
80
|
-
screenOptions=\{{
|
|
81
|
-
headerStyle: {
|
|
82
|
-
backgroundColor: theme.colors.background,
|
|
83
|
-
},
|
|
84
|
-
headerTitleStyle: {
|
|
85
|
-
color: theme.colors.foreground,
|
|
86
|
-
},
|
|
87
|
-
headerTintColor: theme.colors.foreground,
|
|
88
|
-
}}}
|
|
89
|
-
>
|
|
90
|
-
<Stack.Screen name="(drawer)" options=\{{ headerShown: false }} />
|
|
91
|
-
<Stack.Screen
|
|
92
|
-
name="modal"
|
|
93
|
-
options=\{{ title: "Modal", presentation: "modal" }}
|
|
94
|
-
/>
|
|
95
|
-
</Stack>
|
|
96
|
-
</GestureHandlerRootView>
|
|
97
|
-
</ConvexBetterAuthProvider>
|
|
98
70
|
{{else}}
|
|
99
71
|
<ConvexProvider client={convex}>
|
|
100
72
|
<GestureHandlerRootView style=\{{ flex: 1 }}>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { createAuthClient } from "better-auth/react";
|
|
2
|
-
import { anonymousClient } from "better-auth/client/plugins";
|
|
3
|
-
import { convexClient } from "@convex-dev/better-auth/client/plugins";
|
|
4
|
-
import { expoClient } from "@better-auth/expo/client";
|
|
5
|
-
import Constants from "expo-constants";
|
|
6
|
-
import * as SecureStore from "expo-secure-store";
|
|
7
|
-
|
|
8
|
-
export const authClient = createAuthClient({
|
|
9
|
-
baseURL: process.env.EXPO_PUBLIC_CONVEX_SITE_URL,
|
|
10
|
-
plugins: [
|
|
11
|
-
anonymousClient(),
|
|
12
|
-
expoClient({
|
|
13
|
-
scheme: Constants.expoConfig?.scheme as string,
|
|
14
|
-
storagePrefix: Constants.expoConfig?.scheme as string,
|
|
15
|
-
storage: SecureStore,
|
|
16
|
-
}),
|
|
17
|
-
convexClient(),
|
|
18
|
-
],
|
|
19
|
-
});
|
|
@@ -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
|
-
}
|