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
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
TextInput,
|
|
6
|
+
ScrollView,
|
|
7
|
+
ActivityIndicator,
|
|
8
|
+
Alert,
|
|
9
|
+
Pressable,
|
|
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
|
+
import { Container } from "@/components/container";
|
|
20
|
+
{{#unless (eq backend "convex")}}
|
|
21
|
+
{{#if (eq api "orpc")}}
|
|
22
|
+
import { orpc } from "@/utils/orpc";
|
|
23
|
+
{{/if}}
|
|
24
|
+
{{#if (eq api "trpc")}}
|
|
25
|
+
import { trpc } from "@/utils/trpc";
|
|
26
|
+
{{/if}}
|
|
27
|
+
{{/unless}}
|
|
28
|
+
import { Card, Checkbox, useThemeColor, Chip } from "heroui-native";
|
|
29
|
+
|
|
30
|
+
export default function TodosScreen() {
|
|
31
|
+
const [newTodoText, setNewTodoText] = useState("");
|
|
32
|
+
{{#if (eq backend "convex")}}
|
|
33
|
+
const todos = useQuery(api.todos.getAll);
|
|
34
|
+
const createTodoMutation = useMutation(api.todos.create);
|
|
35
|
+
const toggleTodoMutation = useMutation(api.todos.toggle);
|
|
36
|
+
const deleteTodoMutation = useMutation(api.todos.deleteTodo);
|
|
37
|
+
{{else}}
|
|
38
|
+
{{#if (eq api "orpc")}}
|
|
39
|
+
const todos = useQuery(orpc.todo.getAll.queryOptions());
|
|
40
|
+
const createMutation = useMutation(orpc.todo.create.mutationOptions({
|
|
41
|
+
onSuccess: () => {
|
|
42
|
+
todos.refetch();
|
|
43
|
+
setNewTodoText("");
|
|
44
|
+
},
|
|
45
|
+
}));
|
|
46
|
+
const toggleMutation = useMutation(orpc.todo.toggle.mutationOptions({
|
|
47
|
+
onSuccess: () => {
|
|
48
|
+
todos.refetch();
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
const deleteMutation = useMutation(orpc.todo.delete.mutationOptions({
|
|
52
|
+
onSuccess: () => {
|
|
53
|
+
todos.refetch();
|
|
54
|
+
},
|
|
55
|
+
}));
|
|
56
|
+
{{/if}}
|
|
57
|
+
{{#if (eq api "trpc")}}
|
|
58
|
+
const todos = useQuery(trpc.todo.getAll.queryOptions());
|
|
59
|
+
const createMutation = useMutation(trpc.todo.create.mutationOptions({
|
|
60
|
+
onSuccess: () => {
|
|
61
|
+
todos.refetch();
|
|
62
|
+
setNewTodoText("");
|
|
63
|
+
},
|
|
64
|
+
}));
|
|
65
|
+
const toggleMutation = useMutation(trpc.todo.toggle.mutationOptions({
|
|
66
|
+
onSuccess: () => {
|
|
67
|
+
todos.refetch();
|
|
68
|
+
},
|
|
69
|
+
}));
|
|
70
|
+
const deleteMutation = useMutation(trpc.todo.delete.mutationOptions({
|
|
71
|
+
onSuccess: () => {
|
|
72
|
+
todos.refetch();
|
|
73
|
+
},
|
|
74
|
+
}));
|
|
75
|
+
{{/if}}
|
|
76
|
+
{{/if}}
|
|
77
|
+
|
|
78
|
+
const mutedColor = useThemeColor("muted");
|
|
79
|
+
const accentColor = useThemeColor("accent");
|
|
80
|
+
const dangerColor = useThemeColor("danger");
|
|
81
|
+
const foregroundColor = useThemeColor("foreground");
|
|
82
|
+
|
|
83
|
+
{{#if (eq backend "convex")}}
|
|
84
|
+
const handleAddTodo = async () => {
|
|
85
|
+
const text = newTodoText.trim();
|
|
86
|
+
if (!text) return;
|
|
87
|
+
await createTodoMutation({ text });
|
|
88
|
+
setNewTodoText("");
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
|
|
92
|
+
toggleTodoMutation({ id, completed: !currentCompleted });
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const handleDeleteTodo = (id: Id<"todos">) => {
|
|
96
|
+
Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
|
|
97
|
+
{ text: "Cancel", style: "cancel" },
|
|
98
|
+
{
|
|
99
|
+
text: "Delete",
|
|
100
|
+
style: "destructive",
|
|
101
|
+
onPress: () => deleteTodoMutation({ id }),
|
|
102
|
+
},
|
|
103
|
+
]);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const isLoading = !todos;
|
|
107
|
+
const completedCount = todos?.filter((t) => t.completed).length || 0;
|
|
108
|
+
const totalCount = todos?.length || 0;
|
|
109
|
+
{{else}}
|
|
110
|
+
const handleAddTodo = () => {
|
|
111
|
+
if (newTodoText.trim()) {
|
|
112
|
+
createMutation.mutate({ text: newTodoText });
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const handleToggleTodo = (id: number, completed: boolean) => {
|
|
117
|
+
toggleMutation.mutate({ id, completed: !completed });
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const handleDeleteTodo = (id: number) => {
|
|
121
|
+
Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
|
|
122
|
+
{ text: "Cancel", style: "cancel" },
|
|
123
|
+
{
|
|
124
|
+
text: "Delete",
|
|
125
|
+
style: "destructive",
|
|
126
|
+
onPress: () => deleteMutation.mutate({ id }),
|
|
127
|
+
},
|
|
128
|
+
]);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const isLoading = todos?.isLoading;
|
|
132
|
+
const completedCount = todos?.data?.filter((t) => t.completed).length || 0;
|
|
133
|
+
const totalCount = todos?.data?.length || 0;
|
|
134
|
+
{{/if}}
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<Container>
|
|
138
|
+
<ScrollView className="flex-1" contentContainerClassName="p-6">
|
|
139
|
+
<View className="mb-6">
|
|
140
|
+
<View className="flex-row items-center justify-between mb-2">
|
|
141
|
+
<Text className="text-3xl font-bold text-foreground">
|
|
142
|
+
Todo List
|
|
143
|
+
</Text>
|
|
144
|
+
{totalCount > 0 && (
|
|
145
|
+
<Chip variant="secondary" color="accent" size="sm">
|
|
146
|
+
<Chip.Label>
|
|
147
|
+
{completedCount}/{totalCount}
|
|
148
|
+
</Chip.Label>
|
|
149
|
+
</Chip>
|
|
150
|
+
)}
|
|
151
|
+
</View>
|
|
152
|
+
</View>
|
|
153
|
+
|
|
154
|
+
<Card variant="secondary" className="mb-6 p-4">
|
|
155
|
+
<View className="flex-row items-center gap-3">
|
|
156
|
+
<View className="flex-1">
|
|
157
|
+
<TextInput
|
|
158
|
+
value={newTodoText}
|
|
159
|
+
onChangeText={setNewTodoText}
|
|
160
|
+
placeholder="Add a new task..."
|
|
161
|
+
placeholderTextColor={mutedColor}
|
|
162
|
+
{{#unless (eq backend "convex")}}
|
|
163
|
+
editable={!createMutation.isPending}
|
|
164
|
+
{{/unless}}
|
|
165
|
+
onSubmitEditing={handleAddTodo}
|
|
166
|
+
returnKeyType="done"
|
|
167
|
+
className="text-foreground text-base py-3 px-4 border border-divider rounded-lg bg-surface"
|
|
168
|
+
/>
|
|
169
|
+
</View>
|
|
170
|
+
<Pressable
|
|
171
|
+
onPress={handleAddTodo}
|
|
172
|
+
{{#if (eq backend "convex")}}
|
|
173
|
+
disabled={!newTodoText.trim()}
|
|
174
|
+
className={`p-3 rounded-lg active:opacity-70 ${newTodoText.trim() ? "bg-accent" : "bg-surface"}`}
|
|
175
|
+
{{else}}
|
|
176
|
+
disabled={createMutation.isPending || !newTodoText.trim()}
|
|
177
|
+
className={`p-3 rounded-lg active:opacity-70 ${(createMutation.isPending || !newTodoText.trim()) ? "bg-surface" : "bg-accent"}`}
|
|
178
|
+
{{/if}}
|
|
179
|
+
>
|
|
180
|
+
{{#if (eq backend "convex")}}
|
|
181
|
+
<Ionicons
|
|
182
|
+
name="add"
|
|
183
|
+
size={24}
|
|
184
|
+
color={newTodoText.trim() ? foregroundColor : mutedColor}
|
|
185
|
+
/>
|
|
186
|
+
{{else}}
|
|
187
|
+
{createMutation.isPending ? (
|
|
188
|
+
<ActivityIndicator size="small" color={foregroundColor} />
|
|
189
|
+
) : (
|
|
190
|
+
<Ionicons
|
|
191
|
+
name="add"
|
|
192
|
+
size={24}
|
|
193
|
+
color={(createMutation.isPending || !newTodoText.trim()) ? mutedColor : foregroundColor}
|
|
194
|
+
/>
|
|
195
|
+
)}
|
|
196
|
+
{{/if}}
|
|
197
|
+
</Pressable>
|
|
198
|
+
</View>
|
|
199
|
+
</Card>
|
|
200
|
+
|
|
201
|
+
{{#if (eq backend "convex")}}
|
|
202
|
+
{isLoading && (
|
|
203
|
+
<View className="items-center justify-center py-12">
|
|
204
|
+
<ActivityIndicator size="large" color={accentColor} />
|
|
205
|
+
<Text className="text-muted mt-4">Loading todos...</Text>
|
|
206
|
+
</View>
|
|
207
|
+
)}
|
|
208
|
+
|
|
209
|
+
{todos && todos.length === 0 && !isLoading && (
|
|
210
|
+
<Card className="items-center justify-center py-12">
|
|
211
|
+
<Ionicons name="checkbox-outline" size={64} color={mutedColor} style=\{{ marginBottom: 16 }} />
|
|
212
|
+
<Text className="text-foreground text-lg font-semibold mb-2">
|
|
213
|
+
No todos yet
|
|
214
|
+
</Text>
|
|
215
|
+
<Text className="text-muted text-center">
|
|
216
|
+
Add your first task to get started!
|
|
217
|
+
</Text>
|
|
218
|
+
</Card>
|
|
219
|
+
)}
|
|
220
|
+
|
|
221
|
+
{todos && todos.length > 0 && (
|
|
222
|
+
<View className="gap-3">
|
|
223
|
+
{todos.map((todo) => (
|
|
224
|
+
<Card key={todo._id} variant="secondary" className="p-4">
|
|
225
|
+
<View className="flex-row items-center gap-3">
|
|
226
|
+
<Checkbox
|
|
227
|
+
isSelected={todo.completed}
|
|
228
|
+
onSelectedChange={() => handleToggleTodo(todo._id, todo.completed)}
|
|
229
|
+
/>
|
|
230
|
+
<View className="flex-1">
|
|
231
|
+
<Text className={`text-base ${todo.completed ? "text-muted line-through" : "text-foreground"}`}>
|
|
232
|
+
{todo.text}
|
|
233
|
+
</Text>
|
|
234
|
+
</View>
|
|
235
|
+
<Pressable
|
|
236
|
+
onPress={() => handleDeleteTodo(todo._id)}
|
|
237
|
+
className="p-2 rounded-lg active:opacity-70"
|
|
238
|
+
>
|
|
239
|
+
<Ionicons name="trash-outline" size={24} color={dangerColor} />
|
|
240
|
+
</Pressable>
|
|
241
|
+
</View>
|
|
242
|
+
</Card>
|
|
243
|
+
))}
|
|
244
|
+
</View>
|
|
245
|
+
)}
|
|
246
|
+
{{else}}
|
|
247
|
+
{isLoading && (
|
|
248
|
+
<View className="items-center justify-center py-12">
|
|
249
|
+
<ActivityIndicator size="large" color={accentColor} />
|
|
250
|
+
<Text className="text-muted mt-4">Loading todos...</Text>
|
|
251
|
+
</View>
|
|
252
|
+
)}
|
|
253
|
+
|
|
254
|
+
{todos?.data && todos.data.length === 0 && !isLoading && (
|
|
255
|
+
<Card className="items-center justify-center py-12">
|
|
256
|
+
<Ionicons name="checkbox-outline" size={64} color={mutedColor} style=\{{ marginBottom: 16 }} />
|
|
257
|
+
<Text className="text-foreground text-lg font-semibold mb-2">
|
|
258
|
+
No todos yet
|
|
259
|
+
</Text>
|
|
260
|
+
<Text className="text-muted text-center">
|
|
261
|
+
Add your first task to get started!
|
|
262
|
+
</Text>
|
|
263
|
+
</Card>
|
|
264
|
+
)}
|
|
265
|
+
|
|
266
|
+
{todos?.data && todos.data.length > 0 && (
|
|
267
|
+
<View className="gap-3">
|
|
268
|
+
{todos.data.map((todo) => (
|
|
269
|
+
<Card key={todo.id} variant="secondary" className="p-4">
|
|
270
|
+
<View className="flex-row items-center gap-3">
|
|
271
|
+
<Checkbox
|
|
272
|
+
isSelected={todo.completed}
|
|
273
|
+
onSelectedChange={() => handleToggleTodo(todo.id, todo.completed)}
|
|
274
|
+
/>
|
|
275
|
+
<View className="flex-1">
|
|
276
|
+
<Text className={`text-base ${todo.completed ? "text-muted line-through" : "text-foreground"}`}>
|
|
277
|
+
{todo.text}
|
|
278
|
+
</Text>
|
|
279
|
+
</View>
|
|
280
|
+
<Pressable
|
|
281
|
+
onPress={() => handleDeleteTodo(todo.id)}
|
|
282
|
+
className="p-2 rounded-lg active:opacity-70"
|
|
283
|
+
>
|
|
284
|
+
<Ionicons name="trash-outline" size={24} color={dangerColor} />
|
|
285
|
+
</Pressable>
|
|
286
|
+
</View>
|
|
287
|
+
</Card>
|
|
288
|
+
))}
|
|
289
|
+
</View>
|
|
290
|
+
)}
|
|
291
|
+
{{/if}}
|
|
292
|
+
</ScrollView>
|
|
293
|
+
</Container>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[install]
|
|
2
|
-
{{#if (or (includes frontend "nuxt")
|
|
3
|
-
linker = "hoisted"
|
|
2
|
+
{{#if (or (includes frontend "nuxt"))}}
|
|
3
|
+
linker = "hoisted" # having issues with Nuxt when linker is isolated
|
|
4
4
|
{{else}}
|
|
5
5
|
linker = "isolated"
|
|
6
|
-
{{/if}}
|
|
6
|
+
{{/if}}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
.expo/
|
|
3
|
+
dist/
|
|
4
|
+
npm-debug.*
|
|
5
|
+
*.jks
|
|
6
|
+
*.p8
|
|
7
|
+
*.p12
|
|
8
|
+
*.key
|
|
9
|
+
*.mobileprovision
|
|
10
|
+
*.orig.*
|
|
11
|
+
web-build/
|
|
12
|
+
|
|
13
|
+
# macOS
|
|
14
|
+
.DS_Store
|
|
15
|
+
|
|
16
|
+
# Temporary files created by Metro to check the health of the file watcher
|
|
17
|
+
.metro-health-check*
|
|
18
|
+
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
import { TabBarIcon } from "@/components/tabbar-icon";
|
|
2
2
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
3
3
|
import { Tabs } from "expo-router";
|
|
4
|
+
import { NAV_THEME } from "@/lib/constants";
|
|
4
5
|
|
|
5
6
|
export default function TabLayout() {
|
|
6
7
|
const { isDarkColorScheme } = useColorScheme();
|
|
8
|
+
const theme = isDarkColorScheme ? NAV_THEME.dark : NAV_THEME.light;
|
|
7
9
|
|
|
8
10
|
return (
|
|
9
11
|
<Tabs
|
|
10
12
|
screenOptions=\{{
|
|
11
13
|
headerShown: false,
|
|
12
|
-
tabBarActiveTintColor:
|
|
13
|
-
|
|
14
|
-
: "hsl(221.2 83.2% 53.3%)",
|
|
15
|
-
tabBarInactiveTintColor: isDarkColorScheme
|
|
16
|
-
? "hsl(215 20.2% 65.1%)"
|
|
17
|
-
: "hsl(215.4 16.3% 46.9%)",
|
|
14
|
+
tabBarActiveTintColor: theme.primary,
|
|
15
|
+
tabBarInactiveTintColor: theme.text,
|
|
18
16
|
tabBarStyle: {
|
|
19
|
-
backgroundColor:
|
|
20
|
-
|
|
21
|
-
: "hsl(0 0% 100%)",
|
|
22
|
-
borderTopColor: isDarkColorScheme
|
|
23
|
-
? "hsl(217.2 32.6% 17.5%)"
|
|
24
|
-
: "hsl(214.3 31.8% 91.4%)",
|
|
17
|
+
backgroundColor: theme.background,
|
|
18
|
+
borderTopColor: theme.border,
|
|
25
19
|
},
|
|
26
20
|
}}
|
|
27
21
|
>
|
|
@@ -44,3 +38,4 @@ export default function TabLayout() {
|
|
|
44
38
|
</Tabs>
|
|
45
39
|
);
|
|
46
40
|
}
|
|
41
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Container } from "@/components/container";
|
|
2
|
+
import { ScrollView, Text, View, StyleSheet } from "react-native";
|
|
3
|
+
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
4
|
+
import { NAV_THEME } from "@/lib/constants";
|
|
5
|
+
|
|
6
|
+
export default function TabOne() {
|
|
7
|
+
const { colorScheme } = useColorScheme();
|
|
8
|
+
const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Container>
|
|
12
|
+
<ScrollView style={styles.scrollView}>
|
|
13
|
+
<View style={styles.content}>
|
|
14
|
+
<Text style={[styles.title, { color: theme.text }]}>
|
|
15
|
+
Tab One
|
|
16
|
+
</Text>
|
|
17
|
+
<Text style={[styles.subtitle, { color: theme.text, opacity: 0.7 }]}>
|
|
18
|
+
Explore the first section of your app
|
|
19
|
+
</Text>
|
|
20
|
+
</View>
|
|
21
|
+
</ScrollView>
|
|
22
|
+
</Container>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const styles = StyleSheet.create({
|
|
27
|
+
scrollView: {
|
|
28
|
+
flex: 1,
|
|
29
|
+
padding: 16,
|
|
30
|
+
},
|
|
31
|
+
content: {
|
|
32
|
+
paddingVertical: 16,
|
|
33
|
+
},
|
|
34
|
+
title: {
|
|
35
|
+
fontSize: 24,
|
|
36
|
+
fontWeight: "bold",
|
|
37
|
+
marginBottom: 8,
|
|
38
|
+
},
|
|
39
|
+
subtitle: {
|
|
40
|
+
fontSize: 16,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Container } from "@/components/container";
|
|
2
|
+
import { ScrollView, Text, View, StyleSheet } from "react-native";
|
|
3
|
+
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
4
|
+
import { NAV_THEME } from "@/lib/constants";
|
|
5
|
+
|
|
6
|
+
export default function TabTwo() {
|
|
7
|
+
const { colorScheme } = useColorScheme();
|
|
8
|
+
const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Container>
|
|
12
|
+
<ScrollView style={styles.scrollView}>
|
|
13
|
+
<View style={styles.content}>
|
|
14
|
+
<Text style={[styles.title, { color: theme.text }]}>
|
|
15
|
+
Tab Two
|
|
16
|
+
</Text>
|
|
17
|
+
<Text style={[styles.subtitle, { color: theme.text, opacity: 0.7 }]}>
|
|
18
|
+
Discover more features and content
|
|
19
|
+
</Text>
|
|
20
|
+
</View>
|
|
21
|
+
</ScrollView>
|
|
22
|
+
</Container>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const styles = StyleSheet.create({
|
|
27
|
+
scrollView: {
|
|
28
|
+
flex: 1,
|
|
29
|
+
padding: 16,
|
|
30
|
+
},
|
|
31
|
+
content: {
|
|
32
|
+
paddingVertical: 16,
|
|
33
|
+
},
|
|
34
|
+
title: {
|
|
35
|
+
fontSize: 24,
|
|
36
|
+
fontWeight: "bold",
|
|
37
|
+
marginBottom: 8,
|
|
38
|
+
},
|
|
39
|
+
subtitle: {
|
|
40
|
+
fontSize: 16,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
import { Ionicons, MaterialIcons } from "@expo/vector-icons";
|
|
2
2
|
import { Link } from "expo-router";
|
|
3
3
|
import { Drawer } from "expo-router/drawer";
|
|
4
|
+
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
5
|
+
import { NAV_THEME } from "@/lib/constants";
|
|
4
6
|
|
|
5
7
|
import { HeaderButton } from "@/components/header-button";
|
|
6
8
|
|
|
7
9
|
const DrawerLayout = () => {
|
|
10
|
+
const { colorScheme } = useColorScheme();
|
|
11
|
+
const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
|
|
12
|
+
|
|
8
13
|
return (
|
|
9
|
-
<Drawer
|
|
14
|
+
<Drawer
|
|
15
|
+
screenOptions=\{{
|
|
16
|
+
headerStyle: {
|
|
17
|
+
backgroundColor: theme.background,
|
|
18
|
+
},
|
|
19
|
+
headerTitleStyle: {
|
|
20
|
+
color: theme.text,
|
|
21
|
+
},
|
|
22
|
+
headerTintColor: theme.text,
|
|
23
|
+
drawerStyle: {
|
|
24
|
+
backgroundColor: theme.background,
|
|
25
|
+
},
|
|
26
|
+
drawerLabelStyle: {
|
|
27
|
+
color: theme.text,
|
|
28
|
+
},
|
|
29
|
+
drawerInactiveTintColor: theme.text,
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
10
32
|
<Drawer.Screen
|
|
11
33
|
name="index"
|
|
12
34
|
options=\{{
|
|
@@ -65,3 +87,4 @@ const DrawerLayout = () => {
|
|
|
65
87
|
};
|
|
66
88
|
|
|
67
89
|
export default DrawerLayout;
|
|
90
|
+
|