create-better-t-stack 3.2.23 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) 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-Cx7HDf0b.js → src-oHcpd_LW.js} +98 -57
  6. package/package.json +1 -1
  7. package/templates/addons/biome/biome.json.hbs +5 -0
  8. package/templates/api/orpc/server/tsconfig.json.hbs +1 -1
  9. package/templates/api/trpc/server/tsconfig.json.hbs +1 -1
  10. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +5 -5
  11. package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +1 -1
  12. package/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs +127 -0
  13. package/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs +138 -0
  14. package/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs +91 -0
  15. package/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs +102 -0
  16. package/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs +186 -0
  17. package/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs +131 -0
  18. package/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs +150 -0
  19. package/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs +9 -1
  20. package/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs +5 -0
  21. package/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs +5 -0
  22. package/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs +123 -0
  23. package/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs +90 -0
  24. package/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs +116 -0
  25. package/templates/auth/better-auth/server/base/src/index.ts.hbs +5 -5
  26. package/templates/auth/better-auth/server/base/tsconfig.json.hbs +1 -1
  27. package/templates/backend/server/base/tsconfig.json.hbs +1 -1
  28. package/templates/db/base/tsconfig.json.hbs +1 -1
  29. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +287 -0
  30. package/templates/examples/ai/native/{nativewind → bare}/polyfills.js +1 -0
  31. package/templates/examples/ai/native/{nativewind → uniwind}/app/(drawer)/ai.tsx.hbs +52 -51
  32. package/templates/examples/ai/native/uniwind/polyfills.js +26 -0
  33. package/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs +521 -0
  34. package/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs +295 -0
  35. package/templates/extras/bunfig.toml.hbs +3 -3
  36. package/templates/frontend/native/bare/_gitignore +18 -0
  37. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/(tabs)/_layout.tsx.hbs +7 -12
  38. package/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs +43 -0
  39. package/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs +43 -0
  40. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/_layout.tsx.hbs +24 -1
  41. package/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs +234 -0
  42. package/templates/frontend/native/bare/app/+not-found.tsx.hbs +65 -0
  43. package/templates/frontend/native/bare/app/_layout.tsx.hbs +163 -0
  44. package/templates/frontend/native/bare/app/modal.tsx.hbs +34 -0
  45. package/templates/frontend/native/{nativewind → bare}/app.json.hbs +1 -0
  46. package/templates/frontend/native/bare/components/container.tsx.hbs +25 -0
  47. package/templates/frontend/native/bare/components/header-button.tsx.hbs +47 -0
  48. package/templates/frontend/native/{nativewind → bare}/components/tabbar-icon.tsx.hbs +1 -0
  49. package/templates/frontend/native/{nativewind → bare}/lib/android-navigation-bar.tsx.hbs +1 -0
  50. package/templates/frontend/native/{nativewind → bare}/lib/constants.ts.hbs +1 -0
  51. package/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs +20 -0
  52. package/templates/frontend/native/bare/metro.config.js.hbs +9 -0
  53. package/templates/frontend/native/{nativewind → bare}/package.json.hbs +1 -2
  54. package/templates/frontend/native/bare/tsconfig.json.hbs +11 -0
  55. package/templates/frontend/native/{nativewind → uniwind}/_gitignore +4 -8
  56. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs +46 -0
  57. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs +15 -0
  58. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs +15 -0
  59. package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +83 -0
  60. package/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs +151 -0
  61. package/templates/frontend/native/uniwind/app/+not-found.tsx.hbs +32 -0
  62. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +131 -0
  63. package/templates/frontend/native/uniwind/app/modal.tsx.hbs +53 -0
  64. package/templates/frontend/native/uniwind/app.json.hbs +19 -0
  65. package/templates/frontend/native/uniwind/components/container.tsx.hbs +33 -0
  66. package/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs +35 -0
  67. package/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs +62 -0
  68. package/templates/frontend/native/uniwind/global.css +5 -0
  69. package/templates/frontend/native/uniwind/metro.config.js.hbs +13 -0
  70. package/templates/frontend/native/uniwind/package.json.hbs +54 -0
  71. package/templates/frontend/native/{nativewind → uniwind}/tsconfig.json.hbs +4 -8
  72. package/templates/packages/config/package.json.hbs +5 -0
  73. package/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs +0 -86
  74. package/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs +0 -97
  75. package/templates/auth/better-auth/native/nativewind/app/(drawer)/index.tsx.hbs +0 -95
  76. package/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs +0 -93
  77. package/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs +0 -104
  78. package/templates/base/tsconfig.json.hbs +0 -3
  79. package/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs +0 -295
  80. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs +0 -19
  81. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs +0 -19
  82. package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +0 -178
  83. package/templates/frontend/native/nativewind/app/+not-found.tsx.hbs +0 -29
  84. package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +0 -175
  85. package/templates/frontend/native/nativewind/app/modal.tsx.hbs +0 -14
  86. package/templates/frontend/native/nativewind/babel.config.js.hbs +0 -14
  87. package/templates/frontend/native/nativewind/components/container.tsx.hbs +0 -8
  88. package/templates/frontend/native/nativewind/components/header-button.tsx.hbs +0 -26
  89. package/templates/frontend/native/nativewind/global.css +0 -50
  90. package/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs +0 -12
  91. package/templates/frontend/native/nativewind/metro.config.js.hbs +0 -12
  92. package/templates/frontend/native/nativewind/tailwind.config.js.hbs +0 -59
  93. /package/templates/auth/clerk/convex/native/base/app/(auth)/{sign-out.tsx.hbs → sign-up.tsx.hbs} +0 -0
  94. /package/templates/{base → packages/config}/tsconfig.base.json.hbs +0 -0
@@ -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
+ });