create-better-t-stack 3.2.22 → 3.2.23-canary.2b547ed5

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 (84) 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-ehteLbIu.js} +105 -65
  6. package/package.json +1 -1
  7. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +5 -5
  8. package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +1 -1
  9. package/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs +127 -0
  10. package/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs +138 -0
  11. package/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs +91 -0
  12. package/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs +102 -0
  13. package/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs +186 -0
  14. package/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs +131 -0
  15. package/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs +150 -0
  16. package/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs +9 -1
  17. package/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs +5 -0
  18. package/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs +5 -0
  19. package/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs +123 -0
  20. package/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs +90 -0
  21. package/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs +116 -0
  22. package/templates/auth/better-auth/server/base/src/index.ts.hbs +5 -5
  23. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +287 -0
  24. package/templates/examples/ai/native/{nativewind → bare}/polyfills.js +1 -0
  25. package/templates/examples/ai/native/{nativewind → uniwind}/app/(drawer)/ai.tsx.hbs +52 -51
  26. package/templates/examples/ai/native/uniwind/polyfills.js +26 -0
  27. package/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs +430 -0
  28. package/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs +295 -0
  29. package/templates/extras/bunfig.toml.hbs +3 -3
  30. package/templates/frontend/native/bare/_gitignore +18 -0
  31. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/(tabs)/_layout.tsx.hbs +7 -12
  32. package/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs +43 -0
  33. package/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs +43 -0
  34. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/_layout.tsx.hbs +24 -1
  35. package/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs +234 -0
  36. package/templates/frontend/native/bare/app/+not-found.tsx.hbs +65 -0
  37. package/templates/frontend/native/bare/app/_layout.tsx.hbs +163 -0
  38. package/templates/frontend/native/bare/app/modal.tsx.hbs +34 -0
  39. package/templates/frontend/native/{nativewind → bare}/app.json.hbs +1 -0
  40. package/templates/frontend/native/bare/components/container.tsx.hbs +25 -0
  41. package/templates/frontend/native/bare/components/header-button.tsx.hbs +47 -0
  42. package/templates/frontend/native/{nativewind → bare}/components/tabbar-icon.tsx.hbs +1 -0
  43. package/templates/frontend/native/{nativewind → bare}/lib/android-navigation-bar.tsx.hbs +1 -0
  44. package/templates/frontend/native/{nativewind → bare}/lib/constants.ts.hbs +1 -0
  45. package/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs +20 -0
  46. package/templates/frontend/native/bare/metro.config.js.hbs +9 -0
  47. package/templates/frontend/native/{nativewind → bare}/package.json.hbs +1 -2
  48. package/templates/frontend/native/bare/tsconfig.json.hbs +11 -0
  49. package/templates/frontend/native/{nativewind → uniwind}/_gitignore +4 -8
  50. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs +46 -0
  51. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs +15 -0
  52. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs +15 -0
  53. package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +83 -0
  54. package/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs +151 -0
  55. package/templates/frontend/native/uniwind/app/+not-found.tsx.hbs +32 -0
  56. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +131 -0
  57. package/templates/frontend/native/uniwind/app/modal.tsx.hbs +53 -0
  58. package/templates/frontend/native/uniwind/app.json.hbs +19 -0
  59. package/templates/frontend/native/uniwind/components/container.tsx.hbs +33 -0
  60. package/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs +35 -0
  61. package/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs +62 -0
  62. package/templates/frontend/native/uniwind/global.css +5 -0
  63. package/templates/frontend/native/uniwind/metro.config.js.hbs +13 -0
  64. package/templates/frontend/native/uniwind/package.json.hbs +54 -0
  65. package/templates/frontend/native/{nativewind → uniwind}/tsconfig.json.hbs +4 -8
  66. package/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs +0 -86
  67. package/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs +0 -97
  68. package/templates/auth/better-auth/native/nativewind/app/(drawer)/index.tsx.hbs +0 -95
  69. package/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs +0 -93
  70. package/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs +0 -104
  71. package/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs +0 -295
  72. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs +0 -19
  73. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs +0 -19
  74. package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +0 -178
  75. package/templates/frontend/native/nativewind/app/+not-found.tsx.hbs +0 -29
  76. package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +0 -175
  77. package/templates/frontend/native/nativewind/app/modal.tsx.hbs +0 -14
  78. package/templates/frontend/native/nativewind/babel.config.js.hbs +0 -14
  79. package/templates/frontend/native/nativewind/components/container.tsx.hbs +0 -8
  80. package/templates/frontend/native/nativewind/components/header-button.tsx.hbs +0 -26
  81. package/templates/frontend/native/nativewind/global.css +0 -50
  82. package/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs +0 -12
  83. package/templates/frontend/native/nativewind/metro.config.js.hbs +0 -12
  84. package/templates/frontend/native/nativewind/tailwind.config.js.hbs +0 -59
@@ -0,0 +1,127 @@
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
+ StyleSheet,
10
+ } from "react-native";
11
+ import { useColorScheme } from "@/lib/use-color-scheme";
12
+ import { NAV_THEME } from "@/lib/constants";
13
+
14
+ function SignIn() {
15
+ const { colorScheme } = useColorScheme();
16
+ const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
17
+ const [email, setEmail] = useState("");
18
+ const [password, setPassword] = useState("");
19
+ const [isLoading, setIsLoading] = useState(false);
20
+ const [error, setError] = useState<string | null>(null);
21
+
22
+ async function handleLogin() {
23
+ setIsLoading(true);
24
+ setError(null);
25
+
26
+ await authClient.signIn.email(
27
+ {
28
+ email,
29
+ password,
30
+ },
31
+ {
32
+ onError(error) {
33
+ setError(error.error?.message || "Failed to sign in");
34
+ setIsLoading(false);
35
+ },
36
+ onSuccess() {
37
+ setEmail("");
38
+ setPassword("");
39
+ },
40
+ onFinished() {
41
+ setIsLoading(false);
42
+ },
43
+ }
44
+ );
45
+ }
46
+
47
+ return (
48
+ <View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>
49
+ <Text style={[styles.title, { color: theme.text }]}>Sign In</Text>
50
+
51
+ {error ? (
52
+ <View style={[styles.errorContainer, { backgroundColor: theme.notification + "20" }]}>
53
+ <Text style={[styles.errorText, { color: theme.notification }]}>{error}</Text>
54
+ </View>
55
+ ) : null}
56
+
57
+ <TextInput
58
+ style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
59
+ placeholder="Email"
60
+ placeholderTextColor={theme.text}
61
+ value={email}
62
+ onChangeText={setEmail}
63
+ keyboardType="email-address"
64
+ autoCapitalize="none"
65
+ />
66
+
67
+ <TextInput
68
+ style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
69
+ placeholder="Password"
70
+ placeholderTextColor={theme.text}
71
+ value={password}
72
+ onChangeText={setPassword}
73
+ secureTextEntry
74
+ />
75
+
76
+ <TouchableOpacity
77
+ onPress={handleLogin}
78
+ disabled={isLoading}
79
+ style={[styles.button, { backgroundColor: theme.primary, opacity: isLoading ? 0.5 : 1 }]}
80
+ >
81
+ {isLoading ? (
82
+ <ActivityIndicator size="small" color="#ffffff" />
83
+ ) : (
84
+ <Text style={styles.buttonText}>Sign In</Text>
85
+ )}
86
+ </TouchableOpacity>
87
+ </View>
88
+ );
89
+ }
90
+
91
+ const styles = StyleSheet.create({
92
+ card: {
93
+ marginTop: 16,
94
+ padding: 16,
95
+ borderWidth: 1,
96
+ },
97
+ title: {
98
+ fontSize: 18,
99
+ fontWeight: "bold",
100
+ marginBottom: 12,
101
+ },
102
+ errorContainer: {
103
+ marginBottom: 12,
104
+ padding: 8,
105
+ },
106
+ errorText: {
107
+ fontSize: 14,
108
+ },
109
+ input: {
110
+ borderWidth: 1,
111
+ padding: 12,
112
+ fontSize: 16,
113
+ marginBottom: 12,
114
+ },
115
+ button: {
116
+ padding: 12,
117
+ alignItems: "center",
118
+ justifyContent: "center",
119
+ },
120
+ buttonText: {
121
+ color: "#ffffff",
122
+ fontSize: 16,
123
+ },
124
+ });
125
+
126
+ export { SignIn };
127
+
@@ -0,0 +1,138 @@
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
+ StyleSheet,
10
+ } from "react-native";
11
+ import { useColorScheme } from "@/lib/use-color-scheme";
12
+ import { NAV_THEME } from "@/lib/constants";
13
+
14
+ function SignUp() {
15
+ const { colorScheme } = useColorScheme();
16
+ const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
17
+ const [name, setName] = useState("");
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
+ async function handleSignUp() {
24
+ setIsLoading(true);
25
+ setError(null);
26
+
27
+ await authClient.signUp.email(
28
+ {
29
+ name,
30
+ email,
31
+ password,
32
+ },
33
+ {
34
+ onError(error) {
35
+ setError(error.error?.message || "Failed to sign up");
36
+ setIsLoading(false);
37
+ },
38
+ onSuccess() {
39
+ setName("");
40
+ setEmail("");
41
+ setPassword("");
42
+ },
43
+ onFinished() {
44
+ setIsLoading(false);
45
+ },
46
+ }
47
+ );
48
+ }
49
+
50
+ return (
51
+ <View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>
52
+ <Text style={[styles.title, { color: theme.text }]}>Create Account</Text>
53
+
54
+ {error ? (
55
+ <View style={[styles.errorContainer, { backgroundColor: theme.notification + "20" }]}>
56
+ <Text style={[styles.errorText, { color: theme.notification }]}>{error}</Text>
57
+ </View>
58
+ ) : null}
59
+
60
+ <TextInput
61
+ style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
62
+ placeholder="Name"
63
+ placeholderTextColor={theme.text}
64
+ value={name}
65
+ onChangeText={setName}
66
+ />
67
+
68
+ <TextInput
69
+ style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
70
+ placeholder="Email"
71
+ placeholderTextColor={theme.text}
72
+ value={email}
73
+ onChangeText={setEmail}
74
+ keyboardType="email-address"
75
+ autoCapitalize="none"
76
+ />
77
+
78
+ <TextInput
79
+ style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
80
+ placeholder="Password"
81
+ placeholderTextColor={theme.text}
82
+ value={password}
83
+ onChangeText={setPassword}
84
+ secureTextEntry
85
+ />
86
+
87
+ <TouchableOpacity
88
+ onPress={handleSignUp}
89
+ disabled={isLoading}
90
+ style={[styles.button, { backgroundColor: theme.primary, opacity: isLoading ? 0.5 : 1 }]}
91
+ >
92
+ {isLoading ? (
93
+ <ActivityIndicator size="small" color="#ffffff" />
94
+ ) : (
95
+ <Text style={styles.buttonText}>Sign Up</Text>
96
+ )}
97
+ </TouchableOpacity>
98
+ </View>
99
+ );
100
+ }
101
+
102
+ const styles = StyleSheet.create({
103
+ card: {
104
+ marginTop: 16,
105
+ padding: 16,
106
+ borderWidth: 1,
107
+ },
108
+ title: {
109
+ fontSize: 18,
110
+ fontWeight: "bold",
111
+ marginBottom: 12,
112
+ },
113
+ errorContainer: {
114
+ marginBottom: 12,
115
+ padding: 8,
116
+ },
117
+ errorText: {
118
+ fontSize: 14,
119
+ },
120
+ input: {
121
+ borderWidth: 1,
122
+ padding: 12,
123
+ fontSize: 16,
124
+ marginBottom: 12,
125
+ },
126
+ button: {
127
+ padding: 12,
128
+ alignItems: "center",
129
+ justifyContent: "center",
130
+ },
131
+ buttonText: {
132
+ color: "#ffffff",
133
+ fontSize: 16,
134
+ },
135
+ });
136
+
137
+ export { SignUp };
138
+
@@ -0,0 +1,91 @@
1
+ import { authClient } from "@/lib/auth-client";
2
+ import { useState } from "react";
3
+ import {
4
+ ActivityIndicator,
5
+ Text,
6
+ TextInput,
7
+ Pressable,
8
+ View,
9
+ } from "react-native";
10
+ import { Card, useThemeColor } from "heroui-native";
11
+
12
+ export function SignIn() {
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 mutedColor = useThemeColor("muted");
19
+ const accentColor = useThemeColor("accent");
20
+ const foregroundColor = useThemeColor("foreground");
21
+ const dangerColor = useThemeColor("danger");
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
+ },
41
+ onFinished: () => {
42
+ setIsLoading(false);
43
+ },
44
+ },
45
+ );
46
+ };
47
+
48
+ return (
49
+ <Card variant="secondary" className="mt-6 p-4">
50
+ <Card.Title className="mb-4">Sign In</Card.Title>
51
+
52
+ {error && (
53
+ <View className="mb-4 p-3 bg-danger/10 rounded-lg">
54
+ <Text className="text-danger text-sm">{error}</Text>
55
+ </View>
56
+ )}
57
+
58
+ <TextInput
59
+ className="mb-3 py-3 px-4 rounded-lg bg-surface text-foreground border border-divider"
60
+ placeholder="Email"
61
+ value={email}
62
+ onChangeText={setEmail}
63
+ placeholderTextColor={mutedColor}
64
+ keyboardType="email-address"
65
+ autoCapitalize="none"
66
+ />
67
+
68
+ <TextInput
69
+ className="mb-4 py-3 px-4 rounded-lg bg-surface text-foreground border border-divider"
70
+ placeholder="Password"
71
+ value={password}
72
+ onChangeText={setPassword}
73
+ placeholderTextColor={mutedColor}
74
+ secureTextEntry
75
+ />
76
+
77
+ <Pressable
78
+ onPress={handleLogin}
79
+ disabled={isLoading}
80
+ className="bg-accent p-4 rounded-lg flex-row justify-center items-center active:opacity-70"
81
+ >
82
+ {isLoading ? (
83
+ <ActivityIndicator size="small" color={foregroundColor} />
84
+ ) : (
85
+ <Text className="text-foreground font-medium">Sign In</Text>
86
+ )}
87
+ </Pressable>
88
+ </Card>
89
+ );
90
+ }
91
+
@@ -0,0 +1,102 @@
1
+ import { authClient } from "@/lib/auth-client";
2
+ import { useState } from "react";
3
+ import {
4
+ ActivityIndicator,
5
+ Text,
6
+ TextInput,
7
+ Pressable,
8
+ View,
9
+ } from "react-native";
10
+ import { Card, useThemeColor } from "heroui-native";
11
+
12
+ export function SignUp() {
13
+ const [name, setName] = useState("");
14
+ const [email, setEmail] = useState("");
15
+ const [password, setPassword] = useState("");
16
+ const [isLoading, setIsLoading] = useState(false);
17
+ const [error, setError] = useState<string | null>(null);
18
+
19
+ const mutedColor = useThemeColor("muted");
20
+ const accentColor = useThemeColor("accent");
21
+ const foregroundColor = useThemeColor("foreground");
22
+ const dangerColor = useThemeColor("danger");
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
+ },
44
+ onFinished: () => {
45
+ setIsLoading(false);
46
+ },
47
+ },
48
+ );
49
+ };
50
+
51
+ return (
52
+ <Card variant="secondary" className="mt-6 p-4">
53
+ <Card.Title className="mb-4">Create Account</Card.Title>
54
+
55
+ {error && (
56
+ <View className="mb-4 p-3 bg-danger/10 rounded-lg">
57
+ <Text className="text-danger text-sm">{error}</Text>
58
+ </View>
59
+ )}
60
+
61
+ <TextInput
62
+ className="mb-3 py-3 px-4 rounded-lg bg-surface text-foreground border border-divider"
63
+ placeholder="Name"
64
+ value={name}
65
+ onChangeText={setName}
66
+ placeholderTextColor={mutedColor}
67
+ />
68
+
69
+ <TextInput
70
+ className="mb-3 py-3 px-4 rounded-lg bg-surface text-foreground border border-divider"
71
+ placeholder="Email"
72
+ value={email}
73
+ onChangeText={setEmail}
74
+ placeholderTextColor={mutedColor}
75
+ keyboardType="email-address"
76
+ autoCapitalize="none"
77
+ />
78
+
79
+ <TextInput
80
+ className="mb-4 py-3 px-4 rounded-lg bg-surface text-foreground border border-divider"
81
+ placeholder="Password"
82
+ value={password}
83
+ onChangeText={setPassword}
84
+ placeholderTextColor={mutedColor}
85
+ secureTextEntry
86
+ />
87
+
88
+ <Pressable
89
+ onPress={handleSignUp}
90
+ disabled={isLoading}
91
+ className="bg-accent p-4 rounded-lg flex-row justify-center items-center active:opacity-70"
92
+ >
93
+ {isLoading ? (
94
+ <ActivityIndicator size="small" color={foregroundColor} />
95
+ ) : (
96
+ <Text className="text-foreground font-medium">Sign Up</Text>
97
+ )}
98
+ </Pressable>
99
+ </Card>
100
+ );
101
+ }
102
+
@@ -0,0 +1,186 @@
1
+ import { View, Text, ScrollView, TouchableOpacity, StyleSheet } from "react-native";
2
+ import { Container } from "@/components/container";
3
+ import { useColorScheme } from "@/lib/use-color-scheme";
4
+ import { NAV_THEME } from "@/lib/constants";
5
+ import { authClient } from "@/lib/auth-client";
6
+ import { SignIn } from "@/components/sign-in";
7
+ import { SignUp } from "@/components/sign-up";
8
+ {{#if (eq api "orpc")}}
9
+ import { useQuery } from "@tanstack/react-query";
10
+ import { queryClient, orpc } from "@/utils/orpc";
11
+ {{/if}}
12
+ {{#if (eq api "trpc")}}
13
+ import { useQuery } from "@tanstack/react-query";
14
+ import { queryClient, trpc } from "@/utils/trpc";
15
+ {{/if}}
16
+
17
+ export default function Home() {
18
+ const { colorScheme } = useColorScheme();
19
+ const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
20
+ {{#if (eq api "orpc")}}
21
+ const healthCheck = useQuery(orpc.healthCheck.queryOptions());
22
+ const privateData = useQuery(orpc.privateData.queryOptions());
23
+ const isConnected = healthCheck?.data === "OK";
24
+ const isLoading = healthCheck?.isLoading;
25
+ {{/if}}
26
+ {{#if (eq api "trpc")}}
27
+ const healthCheck = useQuery(trpc.healthCheck.queryOptions());
28
+ const privateData = useQuery(trpc.privateData.queryOptions());
29
+ const isConnected = healthCheck?.data === "OK";
30
+ const isLoading = healthCheck?.isLoading;
31
+ {{/if}}
32
+ const { data: session } = authClient.useSession();
33
+
34
+ return (
35
+ <Container>
36
+ <ScrollView style={styles.scrollView}>
37
+ <View style={styles.content}>
38
+ <Text style={[styles.title, { color: theme.text }]}>
39
+ BETTER T STACK
40
+ </Text>
41
+
42
+ {session?.user ? (
43
+ <View style={[styles.userCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
44
+ <View style={styles.userHeader}>
45
+ <Text style={[styles.userText, { color: theme.text }]}>
46
+ Welcome, <Text style={styles.userName}>{session.user.name}</Text>
47
+ </Text>
48
+ </View>
49
+ <Text style={[styles.userEmail, { color: theme.text, opacity: 0.7 }]}>
50
+ {session.user.email}
51
+ </Text>
52
+ <TouchableOpacity style={[styles.signOutButton, { backgroundColor: theme.notification }]} onPress={()=> {
53
+ authClient.signOut();
54
+ {{#if (eq api "orpc")}}
55
+ queryClient.invalidateQueries();
56
+ {{/if}}
57
+ {{#if (eq api "trpc")}}
58
+ queryClient.invalidateQueries();
59
+ {{/if}}
60
+ }}
61
+ >
62
+ <Text style={styles.signOutText}>Sign Out</Text>
63
+ </TouchableOpacity>
64
+ </View>
65
+ ) : null}
66
+
67
+ {{#unless (eq api "none")}}
68
+ <View style={[styles.statusCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
69
+ <Text style={[styles.cardTitle, { color: theme.text }]}>
70
+ System Status
71
+ </Text>
72
+ <View style={styles.statusRow}>
73
+ <View style={[styles.statusIndicator, { backgroundColor: isConnected ? "#10b981" : "#ef4444" }]} />
74
+ <View style={styles.statusContent}>
75
+ <Text style={[styles.statusTitle, { color: theme.text }]}>
76
+ {{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}} Backend
77
+ </Text>
78
+ <Text style={[styles.statusText, { color: theme.text, opacity: 0.7 }]}>
79
+ {isLoading
80
+ ? "Checking connection..."
81
+ : isConnected
82
+ ? "Connected to API"
83
+ : "API Disconnected"}
84
+ </Text>
85
+ </View>
86
+ </View>
87
+ </View>
88
+
89
+ <View style={[styles.privateDataCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
90
+ <Text style={[styles.cardTitle, { color: theme.text }]}>
91
+ Private Data
92
+ </Text>
93
+ {privateData && (
94
+ <Text style={[styles.privateDataText, { color: theme.text, opacity: 0.7 }]}>
95
+ {privateData.data?.message}
96
+ </Text>
97
+ )}
98
+ </View>
99
+ {{/unless}}
100
+
101
+ {!session?.user && (
102
+ <>
103
+ <SignIn />
104
+ <SignUp />
105
+ </>
106
+ )}
107
+ </View>
108
+ </ScrollView>
109
+ </Container>
110
+ );
111
+ }
112
+
113
+ const styles = StyleSheet.create({
114
+ scrollView: {
115
+ flex: 1,
116
+ },
117
+ content: {
118
+ padding: 16,
119
+ },
120
+ title: {
121
+ fontSize: 24,
122
+ fontWeight: "bold",
123
+ marginBottom: 16,
124
+ },
125
+ userCard: {
126
+ marginBottom: 16,
127
+ padding: 16,
128
+ borderWidth: 1,
129
+ },
130
+ userHeader: {
131
+ marginBottom: 8,
132
+ },
133
+ userText: {
134
+ fontSize: 16,
135
+ },
136
+ userName: {
137
+ fontWeight: "bold",
138
+ },
139
+ userEmail: {
140
+ fontSize: 14,
141
+ marginBottom: 12,
142
+ },
143
+ signOutButton: {
144
+ padding: 12,
145
+ },
146
+ signOutText: {
147
+ color: "#ffffff",
148
+ },
149
+ statusCard: {
150
+ marginBottom: 16,
151
+ padding: 16,
152
+ borderWidth: 1,
153
+ },
154
+ cardTitle: {
155
+ fontSize: 16,
156
+ fontWeight: "bold",
157
+ marginBottom: 12,
158
+ },
159
+ statusRow: {
160
+ flexDirection: "row",
161
+ alignItems: "center",
162
+ gap: 8,
163
+ },
164
+ statusIndicator: {
165
+ height: 8,
166
+ width: 8,
167
+ },
168
+ statusContent: {
169
+ flex: 1,
170
+ },
171
+ statusTitle: {
172
+ fontSize: 14,
173
+ fontWeight: "bold",
174
+ },
175
+ statusText: {
176
+ fontSize: 12,
177
+ },
178
+ privateDataCard: {
179
+ marginBottom: 16,
180
+ padding: 16,
181
+ borderWidth: 1,
182
+ },
183
+ privateDataText: {
184
+ fontSize: 14,
185
+ },
186
+ });