create-better-t-stack 3.2.21 → 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.
- package/README.md +2 -2
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/{src-WIwtBCHf.js → src-ehteLbIu.js} +105 -65
- package/package.json +1 -1
- package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +5 -5
- package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +1 -1
- package/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs +127 -0
- package/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs +138 -0
- package/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs +91 -0
- package/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs +102 -0
- package/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs +186 -0
- package/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs +131 -0
- package/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs +150 -0
- package/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs +9 -1
- package/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs +5 -0
- package/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs +5 -0
- package/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs +123 -0
- package/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs +90 -0
- package/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs +116 -0
- package/templates/auth/better-auth/server/base/src/index.ts.hbs +5 -5
- package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +287 -0
- package/templates/examples/ai/native/{nativewind → bare}/polyfills.js +1 -0
- package/templates/examples/ai/native/{nativewind → uniwind}/app/(drawer)/ai.tsx.hbs +52 -51
- package/templates/examples/ai/native/uniwind/polyfills.js +26 -0
- package/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs +430 -0
- package/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs +295 -0
- package/templates/extras/bunfig.toml.hbs +3 -3
- package/templates/frontend/native/bare/_gitignore +18 -0
- package/templates/frontend/native/{nativewind → bare}/app/(drawer)/(tabs)/_layout.tsx.hbs +7 -12
- package/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs +43 -0
- package/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs +43 -0
- package/templates/frontend/native/{nativewind → bare}/app/(drawer)/_layout.tsx.hbs +24 -1
- package/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs +234 -0
- package/templates/frontend/native/bare/app/+not-found.tsx.hbs +65 -0
- package/templates/frontend/native/bare/app/_layout.tsx.hbs +163 -0
- package/templates/frontend/native/bare/app/modal.tsx.hbs +34 -0
- package/templates/frontend/native/{nativewind → bare}/app.json.hbs +1 -0
- package/templates/frontend/native/bare/components/container.tsx.hbs +25 -0
- package/templates/frontend/native/bare/components/header-button.tsx.hbs +47 -0
- package/templates/frontend/native/{nativewind → bare}/components/tabbar-icon.tsx.hbs +1 -0
- package/templates/frontend/native/{nativewind → bare}/lib/android-navigation-bar.tsx.hbs +1 -0
- package/templates/frontend/native/{nativewind → bare}/lib/constants.ts.hbs +1 -0
- package/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs +20 -0
- package/templates/frontend/native/bare/metro.config.js.hbs +9 -0
- package/templates/frontend/native/{nativewind → bare}/package.json.hbs +1 -2
- package/templates/frontend/native/bare/tsconfig.json.hbs +11 -0
- package/templates/frontend/native/{nativewind → uniwind}/_gitignore +4 -8
- package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs +46 -0
- package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs +15 -0
- package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs +15 -0
- package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +83 -0
- package/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs +151 -0
- package/templates/frontend/native/uniwind/app/+not-found.tsx.hbs +32 -0
- package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +131 -0
- package/templates/frontend/native/uniwind/app/modal.tsx.hbs +53 -0
- package/templates/frontend/native/uniwind/app.json.hbs +19 -0
- package/templates/frontend/native/uniwind/components/container.tsx.hbs +33 -0
- package/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs +35 -0
- package/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs +62 -0
- package/templates/frontend/native/uniwind/global.css +5 -0
- package/templates/frontend/native/uniwind/metro.config.js.hbs +13 -0
- package/templates/frontend/native/uniwind/package.json.hbs +54 -0
- package/templates/frontend/native/{nativewind → uniwind}/tsconfig.json.hbs +4 -8
- package/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs +2 -8
- package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +3 -6
- 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/native/nativewind/app/(drawer)/index.tsx.hbs +0 -95
- package/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs +0 -93
- package/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs +0 -104
- package/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs +0 -295
- package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs +0 -19
- package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs +0 -19
- package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +0 -178
- package/templates/frontend/native/nativewind/app/+not-found.tsx.hbs +0 -29
- package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +0 -175
- package/templates/frontend/native/nativewind/app/modal.tsx.hbs +0 -14
- package/templates/frontend/native/nativewind/babel.config.js.hbs +0 -14
- package/templates/frontend/native/nativewind/components/container.tsx.hbs +0 -8
- package/templates/frontend/native/nativewind/components/header-button.tsx.hbs +0 -26
- package/templates/frontend/native/nativewind/global.css +0 -50
- package/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs +0 -12
- package/templates/frontend/native/nativewind/metro.config.js.hbs +0 -12
- package/templates/frontend/native/nativewind/tailwind.config.js.hbs +0 -59
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
Text,
|
|
5
|
-
TextInput,
|
|
6
|
-
TouchableOpacity,
|
|
7
|
-
ScrollView,
|
|
8
|
-
ActivityIndicator,
|
|
9
|
-
Alert,
|
|
10
|
-
} from "react-native";
|
|
11
|
-
import { Ionicons } from "@expo/vector-icons";
|
|
12
|
-
{{#if (eq backend "convex")}}
|
|
13
|
-
import { useMutation, useQuery } from "convex/react";
|
|
14
|
-
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
15
|
-
import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
16
|
-
{{else}}
|
|
17
|
-
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
18
|
-
{{/if}}
|
|
19
|
-
|
|
20
|
-
import { Container } from "@/components/container";
|
|
21
|
-
{{#unless (eq backend "convex")}}
|
|
22
|
-
{{#if (eq api "orpc")}}
|
|
23
|
-
import { orpc } from "@/utils/orpc";
|
|
24
|
-
{{/if}}
|
|
25
|
-
{{#if (eq api "trpc")}}
|
|
26
|
-
import { trpc } from "@/utils/trpc";
|
|
27
|
-
{{/if}}
|
|
28
|
-
{{/unless}}
|
|
29
|
-
|
|
30
|
-
export default function TodosScreen() {
|
|
31
|
-
const [newTodoText, setNewTodoText] = useState("");
|
|
32
|
-
|
|
33
|
-
{{#if (eq backend "convex")}}
|
|
34
|
-
const todos = useQuery(api.todos.getAll);
|
|
35
|
-
const createTodoMutation = useMutation(api.todos.create);
|
|
36
|
-
const toggleTodoMutation = useMutation(api.todos.toggle);
|
|
37
|
-
const deleteTodoMutation = useMutation(api.todos.deleteTodo);
|
|
38
|
-
|
|
39
|
-
const handleAddTodo = async () => {
|
|
40
|
-
const text = newTodoText.trim();
|
|
41
|
-
if (!text) return;
|
|
42
|
-
await createTodoMutation({ text });
|
|
43
|
-
setNewTodoText("");
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
|
|
47
|
-
toggleTodoMutation({ id, completed: !currentCompleted });
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const handleDeleteTodo = (id: Id<"todos">) => {
|
|
51
|
-
Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
|
|
52
|
-
{ text: "Cancel", style: "cancel" },
|
|
53
|
-
{
|
|
54
|
-
text: "Delete",
|
|
55
|
-
style: "destructive",
|
|
56
|
-
onPress: () => deleteTodoMutation({ id }),
|
|
57
|
-
},
|
|
58
|
-
]);
|
|
59
|
-
};
|
|
60
|
-
{{else}}
|
|
61
|
-
{{#if (eq api "orpc")}}
|
|
62
|
-
const todos = useQuery(orpc.todo.getAll.queryOptions());
|
|
63
|
-
const createMutation = useMutation(
|
|
64
|
-
orpc.todo.create.mutationOptions({
|
|
65
|
-
onSuccess: () => {
|
|
66
|
-
todos.refetch();
|
|
67
|
-
setNewTodoText("");
|
|
68
|
-
},
|
|
69
|
-
}),
|
|
70
|
-
);
|
|
71
|
-
const toggleMutation = useMutation(
|
|
72
|
-
orpc.todo.toggle.mutationOptions({
|
|
73
|
-
onSuccess: () => { todos.refetch() },
|
|
74
|
-
}),
|
|
75
|
-
);
|
|
76
|
-
const deleteMutation = useMutation(
|
|
77
|
-
orpc.todo.delete.mutationOptions({
|
|
78
|
-
onSuccess: () => { todos.refetch() },
|
|
79
|
-
}),
|
|
80
|
-
);
|
|
81
|
-
{{/if}}
|
|
82
|
-
{{#if (eq api "trpc")}}
|
|
83
|
-
const todos = useQuery(trpc.todo.getAll.queryOptions());
|
|
84
|
-
const createMutation = useMutation(
|
|
85
|
-
trpc.todo.create.mutationOptions({
|
|
86
|
-
onSuccess: () => {
|
|
87
|
-
todos.refetch();
|
|
88
|
-
setNewTodoText("");
|
|
89
|
-
},
|
|
90
|
-
}),
|
|
91
|
-
);
|
|
92
|
-
const toggleMutation = useMutation(
|
|
93
|
-
trpc.todo.toggle.mutationOptions({
|
|
94
|
-
onSuccess: () => { todos.refetch() },
|
|
95
|
-
}),
|
|
96
|
-
);
|
|
97
|
-
const deleteMutation = useMutation(
|
|
98
|
-
trpc.todo.delete.mutationOptions({
|
|
99
|
-
onSuccess: () => { todos.refetch() },
|
|
100
|
-
}),
|
|
101
|
-
);
|
|
102
|
-
{{/if}}
|
|
103
|
-
|
|
104
|
-
const handleAddTodo = () => {
|
|
105
|
-
if (newTodoText.trim()) {
|
|
106
|
-
createMutation.mutate({ text: newTodoText });
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const handleToggleTodo = (id: number, completed: boolean) => {
|
|
111
|
-
toggleMutation.mutate({ id, completed: !completed });
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const handleDeleteTodo = (id: number) => {
|
|
115
|
-
Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
|
|
116
|
-
{ text: "Cancel", style: "cancel" },
|
|
117
|
-
{
|
|
118
|
-
text: "Delete",
|
|
119
|
-
style: "destructive",
|
|
120
|
-
onPress: () => deleteMutation.mutate({ id }),
|
|
121
|
-
},
|
|
122
|
-
]);
|
|
123
|
-
};
|
|
124
|
-
{{/if}}
|
|
125
|
-
|
|
126
|
-
return (
|
|
127
|
-
<Container>
|
|
128
|
-
<ScrollView className="flex-1">
|
|
129
|
-
<View className="px-4 py-6">
|
|
130
|
-
<View className="mb-6 rounded-lg border border-border p-4 bg-card">
|
|
131
|
-
<Text className="text-foreground text-2xl font-bold mb-2">
|
|
132
|
-
Todo List
|
|
133
|
-
</Text>
|
|
134
|
-
<Text className="text-muted-foreground mb-4">
|
|
135
|
-
Manage your tasks efficiently
|
|
136
|
-
</Text>
|
|
137
|
-
|
|
138
|
-
<View className="mb-6">
|
|
139
|
-
<View className="flex-row items-center space-x-2 mb-2">
|
|
140
|
-
<TextInput
|
|
141
|
-
value={newTodoText}
|
|
142
|
-
onChangeText={setNewTodoText}
|
|
143
|
-
placeholder="Add a new task..."
|
|
144
|
-
placeholderTextColor="#6b7280"
|
|
145
|
-
{{#if (eq backend "convex")}}
|
|
146
|
-
{{else}}
|
|
147
|
-
editable={!createMutation.isPending}
|
|
148
|
-
{{/if}}
|
|
149
|
-
className="flex-1 border border-border rounded-md px-3 py-2 text-foreground bg-background"
|
|
150
|
-
onSubmitEditing={handleAddTodo}
|
|
151
|
-
returnKeyType="done"
|
|
152
|
-
/>
|
|
153
|
-
<TouchableOpacity
|
|
154
|
-
onPress={handleAddTodo}
|
|
155
|
-
{{#if (eq backend "convex")}}
|
|
156
|
-
disabled={!newTodoText.trim()}
|
|
157
|
-
{{else}}
|
|
158
|
-
disabled={createMutation.isPending || !newTodoText.trim()}
|
|
159
|
-
{{/if}}
|
|
160
|
-
className={`px-4 py-2 rounded-md ${
|
|
161
|
-
{{#if (eq backend "convex")}}
|
|
162
|
-
!newTodoText.trim()
|
|
163
|
-
{{else}}
|
|
164
|
-
createMutation.isPending || !newTodoText.trim()
|
|
165
|
-
{{/if}}
|
|
166
|
-
? "bg-muted"
|
|
167
|
-
: "bg-primary"
|
|
168
|
-
}`}
|
|
169
|
-
>
|
|
170
|
-
{{#if (eq backend "convex")}}
|
|
171
|
-
<Text className="text-white font-medium">Add</Text>
|
|
172
|
-
{{else}}
|
|
173
|
-
{createMutation.isPending ? (
|
|
174
|
-
<ActivityIndicator size="small" color="white" />
|
|
175
|
-
) : (
|
|
176
|
-
<Text className="text-white font-medium">Add</Text>
|
|
177
|
-
)}
|
|
178
|
-
{{/if}}
|
|
179
|
-
</TouchableOpacity>
|
|
180
|
-
</View>
|
|
181
|
-
</View>
|
|
182
|
-
|
|
183
|
-
{{#if (eq backend "convex")}}
|
|
184
|
-
{todos === undefined ? (
|
|
185
|
-
<View className="flex justify-center py-8">
|
|
186
|
-
<ActivityIndicator size="large" color="#3b82f6" />
|
|
187
|
-
</View>
|
|
188
|
-
) : todos.length === 0 ? (
|
|
189
|
-
<Text className="py-8 text-center text-muted-foreground">
|
|
190
|
-
No todos yet. Add one above!
|
|
191
|
-
</Text>
|
|
192
|
-
) : (
|
|
193
|
-
<View className="space-y-2">
|
|
194
|
-
{todos.map((todo) => (
|
|
195
|
-
<View
|
|
196
|
-
key={todo._id}
|
|
197
|
-
className="flex-row items-center justify-between rounded-md border border-border p-3 bg-background"
|
|
198
|
-
>
|
|
199
|
-
<View className="flex-row items-center flex-1">
|
|
200
|
-
<TouchableOpacity
|
|
201
|
-
onPress={() =>
|
|
202
|
-
handleToggleTodo(todo._id, todo.completed)
|
|
203
|
-
}
|
|
204
|
-
className="mr-3"
|
|
205
|
-
>
|
|
206
|
-
<Ionicons
|
|
207
|
-
name={todo.completed ? "checkbox" : "square-outline"}
|
|
208
|
-
size={24}
|
|
209
|
-
color={todo.completed ? "#22c55e" : "#6b7280"}
|
|
210
|
-
/>
|
|
211
|
-
</TouchableOpacity>
|
|
212
|
-
<Text
|
|
213
|
-
className={`flex-1 ${
|
|
214
|
-
todo.completed
|
|
215
|
-
? "line-through text-muted-foreground"
|
|
216
|
-
: "text-foreground"
|
|
217
|
-
}`}
|
|
218
|
-
>
|
|
219
|
-
{todo.text}
|
|
220
|
-
</Text>
|
|
221
|
-
</View>
|
|
222
|
-
<TouchableOpacity
|
|
223
|
-
onPress={() => handleDeleteTodo(todo._id)}
|
|
224
|
-
className="ml-2 p-1"
|
|
225
|
-
>
|
|
226
|
-
<Ionicons
|
|
227
|
-
name="trash-outline"
|
|
228
|
-
size={20}
|
|
229
|
-
color="#ef4444"
|
|
230
|
-
/>
|
|
231
|
-
</TouchableOpacity>
|
|
232
|
-
</View>
|
|
233
|
-
))}
|
|
234
|
-
</View>
|
|
235
|
-
)}
|
|
236
|
-
{{else}}
|
|
237
|
-
{todos.isLoading ? (
|
|
238
|
-
<View className="flex justify-center py-8">
|
|
239
|
-
<ActivityIndicator size="large" color="#3b82f6" />
|
|
240
|
-
</View>
|
|
241
|
-
) : todos.data?.length === 0 ? (
|
|
242
|
-
<Text className="py-8 text-center text-muted-foreground">
|
|
243
|
-
No todos yet. Add one above!
|
|
244
|
-
</Text>
|
|
245
|
-
) : (
|
|
246
|
-
<View className="space-y-2">
|
|
247
|
-
{todos.data?.map((todo) => (
|
|
248
|
-
<View
|
|
249
|
-
key={todo.id}
|
|
250
|
-
className="flex-row items-center justify-between rounded-md border border-border p-3 bg-background"
|
|
251
|
-
>
|
|
252
|
-
<View className="flex-row items-center flex-1">
|
|
253
|
-
<TouchableOpacity
|
|
254
|
-
onPress={() =>
|
|
255
|
-
handleToggleTodo(todo.id, todo.completed)
|
|
256
|
-
}
|
|
257
|
-
className="mr-3"
|
|
258
|
-
>
|
|
259
|
-
<Ionicons
|
|
260
|
-
name={todo.completed ? "checkbox" : "square-outline"}
|
|
261
|
-
size={24}
|
|
262
|
-
color={todo.completed ? "#22c55e" : "#6b7280"}
|
|
263
|
-
/>
|
|
264
|
-
</TouchableOpacity>
|
|
265
|
-
<Text
|
|
266
|
-
className={`flex-1 ${
|
|
267
|
-
todo.completed
|
|
268
|
-
? "line-through text-muted-foreground"
|
|
269
|
-
: "text-foreground"
|
|
270
|
-
}`}
|
|
271
|
-
>
|
|
272
|
-
{todo.text}
|
|
273
|
-
</Text>
|
|
274
|
-
</View>
|
|
275
|
-
<TouchableOpacity
|
|
276
|
-
onPress={() => handleDeleteTodo(todo.id)}
|
|
277
|
-
className="ml-2 p-1"
|
|
278
|
-
>
|
|
279
|
-
<Ionicons
|
|
280
|
-
name="trash-outline"
|
|
281
|
-
size={20}
|
|
282
|
-
color="#ef4444"
|
|
283
|
-
/>
|
|
284
|
-
</TouchableOpacity>
|
|
285
|
-
</View>
|
|
286
|
-
))}
|
|
287
|
-
</View>
|
|
288
|
-
)}
|
|
289
|
-
{{/if}}
|
|
290
|
-
</View>
|
|
291
|
-
</View>
|
|
292
|
-
</ScrollView>
|
|
293
|
-
</Container>
|
|
294
|
-
);
|
|
295
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Container } from "@/components/container";
|
|
2
|
-
import { ScrollView, Text, View } from "react-native";
|
|
3
|
-
|
|
4
|
-
export default function TabOne() {
|
|
5
|
-
return (
|
|
6
|
-
<Container>
|
|
7
|
-
<ScrollView className="flex-1 p-6">
|
|
8
|
-
<View className="py-8">
|
|
9
|
-
<Text className="text-3xl font-bold text-foreground mb-2">
|
|
10
|
-
Tab One
|
|
11
|
-
</Text>
|
|
12
|
-
<Text className="text-lg text-muted-foreground">
|
|
13
|
-
Explore the first section of your app
|
|
14
|
-
</Text>
|
|
15
|
-
</View>
|
|
16
|
-
</ScrollView>
|
|
17
|
-
</Container>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Container } from "@/components/container";
|
|
2
|
-
import { ScrollView, Text, View } from "react-native";
|
|
3
|
-
|
|
4
|
-
export default function TabTwo() {
|
|
5
|
-
return (
|
|
6
|
-
<Container>
|
|
7
|
-
<ScrollView className="flex-1 p-6">
|
|
8
|
-
<View className="py-8">
|
|
9
|
-
<Text className="text-3xl font-bold text-foreground mb-2">
|
|
10
|
-
Tab Two
|
|
11
|
-
</Text>
|
|
12
|
-
<Text className="text-lg text-muted-foreground">
|
|
13
|
-
Discover more features and content
|
|
14
|
-
</Text>
|
|
15
|
-
</View>
|
|
16
|
-
</ScrollView>
|
|
17
|
-
</Container>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { View, Text, ScrollView, TouchableOpacity } from "react-native";
|
|
2
|
-
import { Container } from "@/components/container";
|
|
3
|
-
{{#if (eq api "orpc")}}
|
|
4
|
-
import { useQuery } from "@tanstack/react-query";
|
|
5
|
-
import { orpc } from "@/utils/orpc";
|
|
6
|
-
{{/if}}
|
|
7
|
-
{{#if (eq api "trpc")}}
|
|
8
|
-
import { useQuery } from "@tanstack/react-query";
|
|
9
|
-
import { trpc } from "@/utils/trpc";
|
|
10
|
-
{{/if}}
|
|
11
|
-
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
|
|
12
|
-
import { Link } from "expo-router";
|
|
13
|
-
import { Authenticated, AuthLoading, Unauthenticated, useQuery } from "convex/react";
|
|
14
|
-
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
|
|
15
|
-
import { useUser } from "@clerk/clerk-expo";
|
|
16
|
-
import { SignOutButton } from "@/components/sign-out-button";
|
|
17
|
-
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
18
|
-
import { useConvexAuth, useQuery } from "convex/react";
|
|
19
|
-
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
|
|
20
|
-
import { authClient } from "@/lib/auth-client";
|
|
21
|
-
import { SignIn } from "@/components/sign-in";
|
|
22
|
-
import { SignUp } from "@/components/sign-up";
|
|
23
|
-
{{else if (eq backend "convex")}}
|
|
24
|
-
import { useQuery } from "convex/react";
|
|
25
|
-
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
|
|
26
|
-
{{/if}}
|
|
27
|
-
|
|
28
|
-
export default function Home() {
|
|
29
|
-
{{#if (eq api "orpc")}}
|
|
30
|
-
const healthCheck = useQuery(orpc.healthCheck.queryOptions());
|
|
31
|
-
{{/if}}
|
|
32
|
-
{{#if (eq api "trpc")}}
|
|
33
|
-
const healthCheck = useQuery(trpc.healthCheck.queryOptions());
|
|
34
|
-
{{/if}}
|
|
35
|
-
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
|
|
36
|
-
const { user } = useUser();
|
|
37
|
-
const healthCheck = useQuery(api.healthCheck.get);
|
|
38
|
-
const privateData = useQuery(api.privateData.get);
|
|
39
|
-
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
40
|
-
const healthCheck = useQuery(api.healthCheck.get);
|
|
41
|
-
const { isAuthenticated } = useConvexAuth();
|
|
42
|
-
const user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : "skip");
|
|
43
|
-
{{else if (eq backend "convex")}}
|
|
44
|
-
const healthCheck = useQuery(api.healthCheck.get);
|
|
45
|
-
{{/if}}
|
|
46
|
-
|
|
47
|
-
return (
|
|
48
|
-
<Container>
|
|
49
|
-
<ScrollView className="flex-1">
|
|
50
|
-
<View className="px-4">
|
|
51
|
-
<Text className="font-mono text-foreground text-3xl font-bold mb-4">
|
|
52
|
-
BETTER T STACK
|
|
53
|
-
</Text>
|
|
54
|
-
|
|
55
|
-
{{#unless (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
56
|
-
<View className="bg-card border border-border rounded-xl p-6 mb-6 shadow-sm">
|
|
57
|
-
{{#if (eq backend "convex")}}
|
|
58
|
-
<View className="flex-row items-center gap-3">
|
|
59
|
-
<View
|
|
60
|
-
className={`h-3 w-3 rounded-full ${
|
|
61
|
-
healthCheck ? "bg-green-500" : "bg-orange-500"
|
|
62
|
-
}`}
|
|
63
|
-
/>
|
|
64
|
-
<View className="flex-1">
|
|
65
|
-
<Text className="text-sm font-medium text-card-foreground">
|
|
66
|
-
Convex
|
|
67
|
-
</Text>
|
|
68
|
-
<Text className="text-muted-foreground">
|
|
69
|
-
{
|
|
70
|
-
healthCheck === undefined
|
|
71
|
-
? "Checking..."
|
|
72
|
-
: healthCheck === "OK"
|
|
73
|
-
? "Connected to API"
|
|
74
|
-
: "API Disconnected"
|
|
75
|
-
}
|
|
76
|
-
</Text>
|
|
77
|
-
</View>
|
|
78
|
-
</View>
|
|
79
|
-
{{else}}
|
|
80
|
-
{{#unless (eq api "none")}}
|
|
81
|
-
<View className="flex-row items-center gap-3">
|
|
82
|
-
<View
|
|
83
|
-
className={`h-3 w-3 rounded-full ${
|
|
84
|
-
healthCheck.data ? "bg-green-500" : "bg-orange-500"
|
|
85
|
-
}`}
|
|
86
|
-
/>
|
|
87
|
-
<View className="flex-1">
|
|
88
|
-
<Text className="text-sm font-medium text-card-foreground">
|
|
89
|
-
{{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}}
|
|
90
|
-
</Text>
|
|
91
|
-
<Text className="text-xs text-muted-foreground">
|
|
92
|
-
{healthCheck.isLoading
|
|
93
|
-
? "Checking connection..."
|
|
94
|
-
: healthCheck.data
|
|
95
|
-
? "All systems operational"
|
|
96
|
-
: "Service unavailable"}
|
|
97
|
-
</Text>
|
|
98
|
-
</View>
|
|
99
|
-
</View>
|
|
100
|
-
{{/unless}}
|
|
101
|
-
{{/if}}
|
|
102
|
-
</View>
|
|
103
|
-
{{/unless}}
|
|
104
|
-
|
|
105
|
-
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
|
|
106
|
-
<Authenticated>
|
|
107
|
-
<Text>Hello {user?.emailAddresses[0].emailAddress}</Text>
|
|
108
|
-
<Text>Private Data: {privateData?.message}</Text>
|
|
109
|
-
<SignOutButton />
|
|
110
|
-
</Authenticated>
|
|
111
|
-
<Unauthenticated>
|
|
112
|
-
<Link href="/(auth)/sign-in">
|
|
113
|
-
<Text>Sign in</Text>
|
|
114
|
-
</Link>
|
|
115
|
-
<Link href="/(auth)/sign-up">
|
|
116
|
-
<Text>Sign up</Text>
|
|
117
|
-
</Link>
|
|
118
|
-
</Unauthenticated>
|
|
119
|
-
<AuthLoading>
|
|
120
|
-
<Text>Loading...</Text>
|
|
121
|
-
</AuthLoading>
|
|
122
|
-
{{/if}}
|
|
123
|
-
|
|
124
|
-
{{#if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
125
|
-
{user ? (
|
|
126
|
-
<View className="mb-6 p-4 bg-card rounded-lg border border-border">
|
|
127
|
-
<View className="flex-row justify-between items-center mb-2">
|
|
128
|
-
<Text className="text-foreground text-base">
|
|
129
|
-
Welcome,{" "}
|
|
130
|
-
<Text className="font-medium">{user.name}</Text>
|
|
131
|
-
</Text>
|
|
132
|
-
</View>
|
|
133
|
-
<Text className="text-muted-foreground text-sm mb-4">
|
|
134
|
-
{user.email}
|
|
135
|
-
</Text>
|
|
136
|
-
<TouchableOpacity
|
|
137
|
-
className="bg-destructive py-2 px-4 rounded-md self-start"
|
|
138
|
-
onPress={() => {
|
|
139
|
-
authClient.signOut();
|
|
140
|
-
}}
|
|
141
|
-
>
|
|
142
|
-
<Text className="text-white font-medium">Sign Out</Text>
|
|
143
|
-
</TouchableOpacity>
|
|
144
|
-
</View>
|
|
145
|
-
) : null}
|
|
146
|
-
<View className="mb-6 rounded-lg border border-border p-4">
|
|
147
|
-
<Text className="mb-3 font-medium text-foreground">
|
|
148
|
-
API Status
|
|
149
|
-
</Text>
|
|
150
|
-
<View className="flex-row items-center gap-2">
|
|
151
|
-
<View
|
|
152
|
-
className={`h-3 w-3 rounded-full ${
|
|
153
|
-
healthCheck ? "bg-green-500" : "bg-red-500"
|
|
154
|
-
}`}
|
|
155
|
-
/>
|
|
156
|
-
<Text className="text-muted-foreground">
|
|
157
|
-
{
|
|
158
|
-
healthCheck === undefined
|
|
159
|
-
? "Checking..."
|
|
160
|
-
: healthCheck === "OK"
|
|
161
|
-
? "Connected to API"
|
|
162
|
-
: "API Disconnected"
|
|
163
|
-
}
|
|
164
|
-
</Text>
|
|
165
|
-
</View>
|
|
166
|
-
</View>
|
|
167
|
-
{!user && (
|
|
168
|
-
<>
|
|
169
|
-
<SignIn />
|
|
170
|
-
<SignUp />
|
|
171
|
-
</>
|
|
172
|
-
)}
|
|
173
|
-
{{/if}}
|
|
174
|
-
</View>
|
|
175
|
-
</ScrollView>
|
|
176
|
-
</Container>
|
|
177
|
-
);
|
|
178
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Container } from "@/components/container";
|
|
2
|
-
import { Link, Stack } from "expo-router";
|
|
3
|
-
import { Text, View } from "react-native";
|
|
4
|
-
|
|
5
|
-
export default function NotFoundScreen() {
|
|
6
|
-
return (
|
|
7
|
-
<>
|
|
8
|
-
<Stack.Screen options=\{{ title: "Oops!" }} />
|
|
9
|
-
<Container>
|
|
10
|
-
<View className="flex-1 justify-center items-center p-6">
|
|
11
|
-
<View className="items-center">
|
|
12
|
-
<Text className="text-6xl mb-4">🤔</Text>
|
|
13
|
-
<Text className="text-2xl font-bold text-foreground mb-2 text-center">
|
|
14
|
-
Page Not Found
|
|
15
|
-
</Text>
|
|
16
|
-
<Text className="text-muted-foreground text-center mb-8 max-w-sm">
|
|
17
|
-
Sorry, the page you're looking for doesn't exist.
|
|
18
|
-
</Text>
|
|
19
|
-
<Link href="/" asChild>
|
|
20
|
-
<Text className="text-primary font-medium bg-primary/10 px-6 py-3 rounded-lg">
|
|
21
|
-
Go to Home
|
|
22
|
-
</Text>
|
|
23
|
-
</Link>
|
|
24
|
-
</View>
|
|
25
|
-
</View>
|
|
26
|
-
</Container>
|
|
27
|
-
</>
|
|
28
|
-
);
|
|
29
|
-
}
|