create-croissant 0.1.44 → 0.1.46

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 (170) hide show
  1. package/dist/add.js +8 -8
  2. package/dist/index.js +8 -8
  3. package/package.json +10 -10
  4. package/template/.env.example +2 -2
  5. package/template/.github/dependabot.yml +15 -0
  6. package/template/.github/workflows/ci.yml +143 -0
  7. package/template/.github/workflows/dependabot-automerge.yml +23 -0
  8. package/template/.husky/pre-push +0 -0
  9. package/template/README.md +23 -23
  10. package/template/apps/desktop/.eslintcache +1 -0
  11. package/template/apps/desktop/README.md +5 -5
  12. package/template/apps/desktop/package.json +5 -5
  13. package/template/apps/mobile/README.md +3 -3
  14. package/template/apps/mobile/app/(tabs)/_layout.tsx +21 -14
  15. package/template/apps/mobile/app/(tabs)/account.tsx +147 -0
  16. package/template/apps/mobile/app/(tabs)/explore.tsx +335 -104
  17. package/template/apps/mobile/app/(tabs)/index.tsx +94 -96
  18. package/template/apps/mobile/app/_layout.tsx +26 -7
  19. package/template/apps/mobile/app/index.tsx +129 -0
  20. package/template/apps/mobile/app/login.tsx +135 -0
  21. package/template/apps/mobile/app/signup.tsx +144 -0
  22. package/template/apps/mobile/app.json +9 -4
  23. package/template/apps/mobile/components/ui/button.tsx +86 -0
  24. package/template/apps/mobile/components/ui/input.tsx +56 -0
  25. package/template/apps/mobile/lib/auth-client.ts +1 -1
  26. package/template/apps/mobile/lib/orpc.ts +28 -0
  27. package/template/apps/mobile/package.json +14 -1
  28. package/template/apps/mobile/scripts/reset-project.js +0 -0
  29. package/template/apps/mobile/tsconfig.json +4 -1
  30. package/template/apps/platform/.env.example +1 -1
  31. package/template/apps/platform/package.json +10 -6
  32. package/template/apps/platform/portless.json +3 -0
  33. package/template/apps/platform/src/components/login-form.tsx +5 -4
  34. package/template/apps/platform/src/components/signup-form.tsx +12 -16
  35. package/template/apps/platform/src/router.tsx +0 -1
  36. package/template/apps/platform/src/routes/__root.tsx +6 -2
  37. package/template/apps/platform/src/routes/_auth/account.tsx +13 -17
  38. package/template/apps/platform/src/routes/_auth/examples/client-orpc-auth.tsx +2 -6
  39. package/template/apps/platform/src/routes/_public/examples/client-orpc.tsx +16 -29
  40. package/template/apps/platform/src/routes/_public/examples/ssr-orpc.tsx +10 -14
  41. package/template/apps/platform/src/routes/api/auth/$.ts +23 -2
  42. package/template/apps/platform/src/routes/api/rpc.$.ts +18 -0
  43. package/template/package.json +23 -18
  44. package/template/packages/auth/package.json +2 -2
  45. package/template/packages/db/package.json +1 -1
  46. package/template/packages/orpc/package.json +11 -4
  47. package/template/packages/orpc/src/lib/planets.ts +18 -18
  48. package/template/packages/orpc/src/lib/router.ts +3 -3
  49. package/template/packages/orpc/src/react/context.tsx +23 -0
  50. package/template/packages/orpc/src/react/general.ts +29 -0
  51. package/template/packages/orpc/src/react/index.ts +3 -0
  52. package/template/packages/orpc/src/react/planets.ts +90 -0
  53. package/template/packages/ui/package.json +3 -2
  54. package/template/pnpm-workspace.yaml +3 -0
  55. package/template/tsconfig.json +2 -1
  56. package/template/apps/mobile/app/modal.tsx +0 -29
  57. package/template/packages/orpc/node_modules/@types/node/LICENSE +0 -21
  58. package/template/packages/orpc/node_modules/@types/node/README.md +0 -15
  59. package/template/packages/orpc/node_modules/@types/node/assert/strict.d.ts +0 -111
  60. package/template/packages/orpc/node_modules/@types/node/assert.d.ts +0 -1078
  61. package/template/packages/orpc/node_modules/@types/node/async_hooks.d.ts +0 -603
  62. package/template/packages/orpc/node_modules/@types/node/buffer.buffer.d.ts +0 -472
  63. package/template/packages/orpc/node_modules/@types/node/buffer.d.ts +0 -1934
  64. package/template/packages/orpc/node_modules/@types/node/child_process.d.ts +0 -1476
  65. package/template/packages/orpc/node_modules/@types/node/cluster.d.ts +0 -578
  66. package/template/packages/orpc/node_modules/@types/node/compatibility/disposable.d.ts +0 -14
  67. package/template/packages/orpc/node_modules/@types/node/compatibility/index.d.ts +0 -9
  68. package/template/packages/orpc/node_modules/@types/node/compatibility/indexable.d.ts +0 -20
  69. package/template/packages/orpc/node_modules/@types/node/compatibility/iterators.d.ts +0 -20
  70. package/template/packages/orpc/node_modules/@types/node/console.d.ts +0 -452
  71. package/template/packages/orpc/node_modules/@types/node/constants.d.ts +0 -21
  72. package/template/packages/orpc/node_modules/@types/node/crypto.d.ts +0 -4545
  73. package/template/packages/orpc/node_modules/@types/node/dgram.d.ts +0 -600
  74. package/template/packages/orpc/node_modules/@types/node/diagnostics_channel.d.ts +0 -578
  75. package/template/packages/orpc/node_modules/@types/node/dns/promises.d.ts +0 -503
  76. package/template/packages/orpc/node_modules/@types/node/dns.d.ts +0 -923
  77. package/template/packages/orpc/node_modules/@types/node/domain.d.ts +0 -170
  78. package/template/packages/orpc/node_modules/@types/node/events.d.ts +0 -976
  79. package/template/packages/orpc/node_modules/@types/node/fs/promises.d.ts +0 -1295
  80. package/template/packages/orpc/node_modules/@types/node/fs.d.ts +0 -4461
  81. package/template/packages/orpc/node_modules/@types/node/globals.d.ts +0 -172
  82. package/template/packages/orpc/node_modules/@types/node/globals.typedarray.d.ts +0 -38
  83. package/template/packages/orpc/node_modules/@types/node/http.d.ts +0 -2089
  84. package/template/packages/orpc/node_modules/@types/node/http2.d.ts +0 -2644
  85. package/template/packages/orpc/node_modules/@types/node/https.d.ts +0 -579
  86. package/template/packages/orpc/node_modules/@types/node/index.d.ts +0 -97
  87. package/template/packages/orpc/node_modules/@types/node/inspector.d.ts +0 -253
  88. package/template/packages/orpc/node_modules/@types/node/inspector.generated.d.ts +0 -4052
  89. package/template/packages/orpc/node_modules/@types/node/module.d.ts +0 -891
  90. package/template/packages/orpc/node_modules/@types/node/net.d.ts +0 -1076
  91. package/template/packages/orpc/node_modules/@types/node/os.d.ts +0 -506
  92. package/template/packages/orpc/node_modules/@types/node/package.json +0 -145
  93. package/template/packages/orpc/node_modules/@types/node/path.d.ts +0 -200
  94. package/template/packages/orpc/node_modules/@types/node/perf_hooks.d.ts +0 -968
  95. package/template/packages/orpc/node_modules/@types/node/process.d.ts +0 -2084
  96. package/template/packages/orpc/node_modules/@types/node/punycode.d.ts +0 -117
  97. package/template/packages/orpc/node_modules/@types/node/querystring.d.ts +0 -152
  98. package/template/packages/orpc/node_modules/@types/node/readline/promises.d.ts +0 -161
  99. package/template/packages/orpc/node_modules/@types/node/readline.d.ts +0 -594
  100. package/template/packages/orpc/node_modules/@types/node/repl.d.ts +0 -428
  101. package/template/packages/orpc/node_modules/@types/node/sea.d.ts +0 -153
  102. package/template/packages/orpc/node_modules/@types/node/sqlite.d.ts +0 -721
  103. package/template/packages/orpc/node_modules/@types/node/stream/consumers.d.ts +0 -38
  104. package/template/packages/orpc/node_modules/@types/node/stream/promises.d.ts +0 -90
  105. package/template/packages/orpc/node_modules/@types/node/stream/web.d.ts +0 -622
  106. package/template/packages/orpc/node_modules/@types/node/stream.d.ts +0 -1687
  107. package/template/packages/orpc/node_modules/@types/node/string_decoder.d.ts +0 -67
  108. package/template/packages/orpc/node_modules/@types/node/test.d.ts +0 -2163
  109. package/template/packages/orpc/node_modules/@types/node/timers/promises.d.ts +0 -108
  110. package/template/packages/orpc/node_modules/@types/node/timers.d.ts +0 -287
  111. package/template/packages/orpc/node_modules/@types/node/tls.d.ts +0 -1319
  112. package/template/packages/orpc/node_modules/@types/node/trace_events.d.ts +0 -197
  113. package/template/packages/orpc/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +0 -468
  114. package/template/packages/orpc/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +0 -34
  115. package/template/packages/orpc/node_modules/@types/node/ts5.6/index.d.ts +0 -97
  116. package/template/packages/orpc/node_modules/@types/node/tty.d.ts +0 -208
  117. package/template/packages/orpc/node_modules/@types/node/url.d.ts +0 -984
  118. package/template/packages/orpc/node_modules/@types/node/util.d.ts +0 -2606
  119. package/template/packages/orpc/node_modules/@types/node/v8.d.ts +0 -920
  120. package/template/packages/orpc/node_modules/@types/node/vm.d.ts +0 -1000
  121. package/template/packages/orpc/node_modules/@types/node/wasi.d.ts +0 -181
  122. package/template/packages/orpc/node_modules/@types/node/web-globals/abortcontroller.d.ts +0 -34
  123. package/template/packages/orpc/node_modules/@types/node/web-globals/domexception.d.ts +0 -68
  124. package/template/packages/orpc/node_modules/@types/node/web-globals/events.d.ts +0 -97
  125. package/template/packages/orpc/node_modules/@types/node/web-globals/fetch.d.ts +0 -55
  126. package/template/packages/orpc/node_modules/@types/node/web-globals/navigator.d.ts +0 -22
  127. package/template/packages/orpc/node_modules/@types/node/web-globals/storage.d.ts +0 -24
  128. package/template/packages/orpc/node_modules/@types/node/worker_threads.d.ts +0 -784
  129. package/template/packages/orpc/node_modules/@types/node/zlib.d.ts +0 -747
  130. package/template/packages/orpc/node_modules/undici-types/LICENSE +0 -21
  131. package/template/packages/orpc/node_modules/undici-types/README.md +0 -6
  132. package/template/packages/orpc/node_modules/undici-types/agent.d.ts +0 -31
  133. package/template/packages/orpc/node_modules/undici-types/api.d.ts +0 -43
  134. package/template/packages/orpc/node_modules/undici-types/balanced-pool.d.ts +0 -29
  135. package/template/packages/orpc/node_modules/undici-types/cache.d.ts +0 -36
  136. package/template/packages/orpc/node_modules/undici-types/client.d.ts +0 -108
  137. package/template/packages/orpc/node_modules/undici-types/connector.d.ts +0 -34
  138. package/template/packages/orpc/node_modules/undici-types/content-type.d.ts +0 -21
  139. package/template/packages/orpc/node_modules/undici-types/cookies.d.ts +0 -28
  140. package/template/packages/orpc/node_modules/undici-types/diagnostics-channel.d.ts +0 -66
  141. package/template/packages/orpc/node_modules/undici-types/dispatcher.d.ts +0 -256
  142. package/template/packages/orpc/node_modules/undici-types/env-http-proxy-agent.d.ts +0 -21
  143. package/template/packages/orpc/node_modules/undici-types/errors.d.ts +0 -149
  144. package/template/packages/orpc/node_modules/undici-types/eventsource.d.ts +0 -61
  145. package/template/packages/orpc/node_modules/undici-types/fetch.d.ts +0 -209
  146. package/template/packages/orpc/node_modules/undici-types/file.d.ts +0 -39
  147. package/template/packages/orpc/node_modules/undici-types/filereader.d.ts +0 -54
  148. package/template/packages/orpc/node_modules/undici-types/formdata.d.ts +0 -108
  149. package/template/packages/orpc/node_modules/undici-types/global-dispatcher.d.ts +0 -9
  150. package/template/packages/orpc/node_modules/undici-types/global-origin.d.ts +0 -7
  151. package/template/packages/orpc/node_modules/undici-types/handlers.d.ts +0 -15
  152. package/template/packages/orpc/node_modules/undici-types/header.d.ts +0 -4
  153. package/template/packages/orpc/node_modules/undici-types/index.d.ts +0 -71
  154. package/template/packages/orpc/node_modules/undici-types/interceptors.d.ts +0 -17
  155. package/template/packages/orpc/node_modules/undici-types/mock-agent.d.ts +0 -50
  156. package/template/packages/orpc/node_modules/undici-types/mock-client.d.ts +0 -25
  157. package/template/packages/orpc/node_modules/undici-types/mock-errors.d.ts +0 -12
  158. package/template/packages/orpc/node_modules/undici-types/mock-interceptor.d.ts +0 -93
  159. package/template/packages/orpc/node_modules/undici-types/mock-pool.d.ts +0 -25
  160. package/template/packages/orpc/node_modules/undici-types/package.json +0 -55
  161. package/template/packages/orpc/node_modules/undici-types/patch.d.ts +0 -33
  162. package/template/packages/orpc/node_modules/undici-types/pool-stats.d.ts +0 -19
  163. package/template/packages/orpc/node_modules/undici-types/pool.d.ts +0 -39
  164. package/template/packages/orpc/node_modules/undici-types/proxy-agent.d.ts +0 -28
  165. package/template/packages/orpc/node_modules/undici-types/readable.d.ts +0 -65
  166. package/template/packages/orpc/node_modules/undici-types/retry-agent.d.ts +0 -8
  167. package/template/packages/orpc/node_modules/undici-types/retry-handler.d.ts +0 -116
  168. package/template/packages/orpc/node_modules/undici-types/util.d.ts +0 -18
  169. package/template/packages/orpc/node_modules/undici-types/webidl.d.ts +0 -228
  170. package/template/packages/orpc/node_modules/undici-types/websocket.d.ts +0 -150
@@ -1,114 +1,112 @@
1
- import { Image } from "expo-image";
2
- import { Platform, StyleSheet } from "react-native";
3
-
4
- import { HelloWave } from "@/components/hello-wave";
5
- import ParallaxScrollView from "@/components/parallax-scroll-view";
6
- import { ThemedText } from "@/components/themed-text";
7
- import { ThemedView } from "@/components/themed-view";
8
- import { Link } from "expo-router";
1
+ import { useEffect } from "react";
2
+ import { View, Text, StyleSheet, ScrollView, Platform } from "react-native";
3
+ import { useRouter } from "expo-router";
9
4
  import { authClient } from "@/lib/auth-client";
5
+ import { useSecretData } from "@workspace/orpc/react";
6
+ import { Button } from "@/components/ui/button";
7
+
8
+ export default function DashboardScreen() {
9
+ const router = useRouter();
10
+ const { data: session, isPending: isAuthPending } = authClient.useSession();
11
+
12
+ const { data: secretData, isLoading: isLoadingSecret, error: secretError } = useSecretData({
13
+ enabled: !!session,
14
+ });
15
+
16
+ useEffect(() => {
17
+ if (!isAuthPending && !session) {
18
+ router.replace("/login");
19
+ }
20
+ }, [session, isAuthPending, router]);
21
+
22
+ const handleSignOut = async () => {
23
+ await authClient.signOut();
24
+ router.replace("/");
25
+ };
10
26
 
11
- export default function HomeScreen() {
12
- const { data: session, isPending } = authClient.useSession();
27
+ if (isAuthPending) {
28
+ return (
29
+ <View style={styles.center}>
30
+ <Text>Loading dashboard...</Text>
31
+ </View>
32
+ );
33
+ }
13
34
 
14
35
  return (
15
- <ParallaxScrollView
16
- headerBackgroundColor={{ light: "#A1CEDC", dark: "#1D3D47" }}
17
- headerImage={
18
- <Image
19
- source={require("@/assets/images/partial-react-logo.png")}
20
- style={styles.reactLogo}
21
- />
22
- }
23
- >
24
- <ThemedView style={styles.titleContainer}>
25
- <ThemedText type="title">Welcome!</ThemedText>
26
- <HelloWave />
27
- </ThemedView>
36
+ <ScrollView style={styles.container} contentContainerStyle={styles.content}>
37
+ <Text style={styles.title}>Dashboard</Text>
38
+ <Text style={styles.welcome}>Welcome, {session?.user?.name}!</Text>
39
+ <Text style={styles.description}>
40
+ This is a protected page. Only authenticated users can see this.
41
+ </Text>
28
42
 
29
- <ThemedView style={styles.stepContainer}>
30
- <ThemedText type="subtitle">Auth Status</ThemedText>
31
- {isPending ? (
32
- <ThemedText>Checking session...</ThemedText>
33
- ) : session ? (
34
- <ThemedText>Logged in as: {session.user.email}</ThemedText>
43
+ <View style={styles.secureBox}>
44
+ <Text style={styles.secureTitle}>Secure oRPC Data:</Text>
45
+ {isLoadingSecret ? (
46
+ <Text style={styles.secureContent}>Loading secret data...</Text>
47
+ ) : secretError ? (
48
+ <Text style={[styles.secureContent, styles.errorText]}>
49
+ Error: {secretError.message || "Unknown error"}
50
+ </Text>
35
51
  ) : (
36
- <ThemedText>Not logged in</ThemedText>
52
+ <Text style={styles.secureContent}>{secretData?.secret}</Text>
37
53
  )}
38
- </ThemedView>
54
+ </View>
39
55
 
40
- <ThemedView style={styles.stepContainer}>
41
- <ThemedText type="subtitle">Step 1: Try it</ThemedText>
42
- <ThemedText>
43
- Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
44
- Press{" "}
45
- <ThemedText type="defaultSemiBold">
46
- {Platform.select({
47
- ios: "cmd + d",
48
- android: "cmd + m",
49
- web: "F12",
50
- })}
51
- </ThemedText>{" "}
52
- to open developer tools.
53
- </ThemedText>
54
- </ThemedView>
55
- <ThemedView style={styles.stepContainer}>
56
- <Link href="/modal">
57
- <Link.Trigger>
58
- <ThemedText type="subtitle">Step 2: Explore</ThemedText>
59
- </Link.Trigger>
60
- <Link.Preview />
61
- <Link.Menu>
62
- <Link.MenuAction title="Action" icon="cube" onPress={() => alert("Action pressed")} />
63
- <Link.MenuAction
64
- title="Share"
65
- icon="square.and.arrow.up"
66
- onPress={() => alert("Share pressed")}
67
- />
68
- <Link.Menu title="More" icon="ellipsis">
69
- <Link.MenuAction
70
- title="Delete"
71
- icon="trash"
72
- destructive
73
- onPress={() => alert("Delete pressed")}
74
- />
75
- </Link.Menu>
76
- </Link.Menu>
77
- </Link>
78
-
79
- <ThemedText>
80
- {`Tap the Explore tab to learn more about what's included in this starter app.`}
81
- </ThemedText>
82
- </ThemedView>
83
- <ThemedView style={styles.stepContainer}>
84
- <ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
85
- <ThemedText>
86
- {`When you're ready, run `}
87
- <ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{" "}
88
- <ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{" "}
89
- <ThemedText type="defaultSemiBold">app</ThemedText> to{" "}
90
- <ThemedText type="defaultSemiBold">app-example</ThemedText>.
91
- </ThemedText>
92
- </ThemedView>
93
- </ParallaxScrollView>
56
+ <Button variant="destructive" onPress={handleSignOut} style={styles.signOutBtn}>
57
+ Sign Out
58
+ </Button>
59
+ </ScrollView>
94
60
  );
95
61
  }
96
62
 
97
63
  const styles = StyleSheet.create({
98
- titleContainer: {
99
- flexDirection: "row",
64
+ container: {
65
+ flex: 1,
66
+ backgroundColor: "#fff",
67
+ },
68
+ content: {
69
+ padding: 24,
70
+ },
71
+ center: {
72
+ flex: 1,
73
+ justifyContent: "center",
100
74
  alignItems: "center",
101
- gap: 8,
102
75
  },
103
- stepContainer: {
104
- gap: 8,
76
+ title: {
77
+ fontSize: 28,
78
+ fontWeight: "bold",
105
79
  marginBottom: 8,
106
80
  },
107
- reactLogo: {
108
- height: 178,
109
- width: 290,
110
- bottom: 0,
111
- left: 0,
112
- position: "absolute",
81
+ welcome: {
82
+ fontSize: 18,
83
+ marginBottom: 8,
84
+ },
85
+ description: {
86
+ fontSize: 14,
87
+ color: "#666",
88
+ marginBottom: 24,
89
+ },
90
+ secureBox: {
91
+ padding: 16,
92
+ backgroundColor: "#f9f9f9",
93
+ borderRadius: 8,
94
+ borderWidth: 1,
95
+ borderColor: "#eee",
96
+ marginBottom: 24,
97
+ },
98
+ secureTitle: {
99
+ fontWeight: "600",
100
+ marginBottom: 8,
101
+ },
102
+ secureContent: {
103
+ fontFamily: Platform.OS === "ios" ? "Courier" : "monospace",
104
+ fontSize: 12,
105
+ },
106
+ errorText: {
107
+ color: "#ef4444",
108
+ },
109
+ signOutBtn: {
110
+ marginTop: 12,
113
111
  },
114
112
  });
@@ -2,9 +2,22 @@ import { DarkTheme, DefaultTheme, ThemeProvider } from "@react-navigation/native
2
2
  import { Stack } from "expo-router";
3
3
  import { StatusBar } from "expo-status-bar";
4
4
  import "react-native-reanimated";
5
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
6
+ import { ORPCProvider } from "@workspace/orpc/react";
7
+ import { orpc } from "@/lib/orpc";
5
8
 
6
9
  import { useColorScheme } from "@/hooks/use-color-scheme";
7
10
 
11
+ const queryClient = new QueryClient({
12
+ defaultOptions: {
13
+ mutations: {
14
+ onError: (error) => {
15
+ console.error("Global Mutation Error:", error);
16
+ },
17
+ },
18
+ },
19
+ });
20
+
8
21
  export const unstable_settings = {
9
22
  anchor: "(tabs)",
10
23
  };
@@ -13,12 +26,18 @@ export default function RootLayout() {
13
26
  const colorScheme = useColorScheme();
14
27
 
15
28
  return (
16
- <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
17
- <Stack>
18
- <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
19
- <Stack.Screen name="modal" options={{ presentation: "modal", title: "Modal" }} />
20
- </Stack>
21
- <StatusBar style="auto" />
22
- </ThemeProvider>
29
+ <QueryClientProvider client={queryClient}>
30
+ <ORPCProvider client={orpc}>
31
+ <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
32
+ <Stack>
33
+ <Stack.Screen name="index" options={{ headerShown: false }} />
34
+ <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
35
+ <Stack.Screen name="login" options={{ title: "Login" }} />
36
+ <Stack.Screen name="signup" options={{ title: "Sign Up" }} />
37
+ </Stack>
38
+ <StatusBar style="auto" />
39
+ </ThemeProvider>
40
+ </ORPCProvider>
41
+ </QueryClientProvider>
23
42
  );
24
43
  }
@@ -0,0 +1,129 @@
1
+ import { View, Text, StyleSheet, ScrollView } from "react-native";
2
+ import { useRouter } from "expo-router";
3
+ import { Button } from "@/components/ui/button";
4
+ import { usePlanets, useHello } from "@workspace/orpc/react";
5
+
6
+ export default function LandingScreen() {
7
+ const router = useRouter();
8
+ const { data: helloData, isLoading: isHelloLoading } = useHello("Croissant Stack Mobile");
9
+ const { data: planets = [], isLoading: isPlanetsLoading } = usePlanets();
10
+
11
+ return (
12
+ <ScrollView style={styles.container} contentContainerStyle={styles.content}>
13
+ <View style={styles.header}>
14
+ <Text style={styles.title}>Project ready!</Text>
15
+ <Text style={styles.subtitle}>
16
+ oRPC integration: <Text style={styles.bold}>
17
+ {isHelloLoading ? "Loading..." : helloData?.message}
18
+ </Text>
19
+ </Text>
20
+ </View>
21
+
22
+ <View style={styles.section}>
23
+ <Text style={styles.sectionTitle}>Planets from Database:</Text>
24
+ {isPlanetsLoading ? (
25
+ <Text style={styles.loading}>Loading planets...</Text>
26
+ ) : planets.length === 0 ? (
27
+ <Text style={styles.empty}>
28
+ No planets found in the database. Run `db:push` and seed data if needed.
29
+ </Text>
30
+ ) : (
31
+ planets.map((planet: any) => (
32
+ <View key={planet.id} style={styles.planetCard}>
33
+ <Text style={styles.planetName}>{planet.name}</Text>
34
+ <Text style={styles.planetDesc}>{planet.description}</Text>
35
+ </View>
36
+ ))
37
+ )}
38
+ </View>
39
+
40
+ <View style={styles.footer}>
41
+ <Button onPress={() => router.push("/login")} style={styles.button}>
42
+ Go to Login
43
+ </Button>
44
+ <Button
45
+ onPress={() => router.push("/(tabs)")}
46
+ variant="outline"
47
+ style={styles.button}
48
+ >
49
+ Go to Dashboard
50
+ </Button>
51
+ <Text style={styles.footerText}>
52
+ You may now add components and start building.
53
+ </Text>
54
+ </View>
55
+ </ScrollView>
56
+ );
57
+ }
58
+
59
+ const styles = StyleSheet.create({
60
+ container: {
61
+ flex: 1,
62
+ backgroundColor: "#fff",
63
+ },
64
+ content: {
65
+ padding: 24,
66
+ paddingTop: 60,
67
+ },
68
+ header: {
69
+ marginBottom: 32,
70
+ },
71
+ title: {
72
+ fontSize: 28,
73
+ fontWeight: "bold",
74
+ marginBottom: 8,
75
+ },
76
+ subtitle: {
77
+ fontSize: 16,
78
+ color: "#666",
79
+ },
80
+ bold: {
81
+ fontWeight: "bold",
82
+ color: "#000",
83
+ },
84
+ section: {
85
+ marginBottom: 32,
86
+ },
87
+ sectionTitle: {
88
+ fontSize: 20,
89
+ fontWeight: "600",
90
+ marginBottom: 16,
91
+ },
92
+ planetCard: {
93
+ padding: 16,
94
+ borderRadius: 8,
95
+ borderWidth: 1,
96
+ borderColor: "#eee",
97
+ marginBottom: 12,
98
+ backgroundColor: "#fafafa",
99
+ },
100
+ planetName: {
101
+ fontSize: 16,
102
+ fontWeight: "bold",
103
+ marginBottom: 4,
104
+ },
105
+ planetDesc: {
106
+ fontSize: 14,
107
+ color: "#666",
108
+ },
109
+ loading: {
110
+ fontStyle: "italic",
111
+ color: "#999",
112
+ },
113
+ empty: {
114
+ fontStyle: "italic",
115
+ color: "#999",
116
+ },
117
+ footer: {
118
+ gap: 12,
119
+ },
120
+ button: {
121
+ width: "100%",
122
+ },
123
+ footerText: {
124
+ marginTop: 16,
125
+ textAlign: "center",
126
+ color: "#999",
127
+ fontSize: 14,
128
+ },
129
+ });
@@ -0,0 +1,135 @@
1
+ import { useState } from "react";
2
+ import { View, StyleSheet, KeyboardAvoidingView, Platform, ScrollView, Text } from "react-native";
3
+ import { useRouter } from "expo-router";
4
+ import { authClient } from "@/lib/auth-client";
5
+ import { Button } from "@/components/ui/button";
6
+ import { Input } from "@/components/ui/input";
7
+
8
+ export default function LoginScreen() {
9
+ const router = useRouter();
10
+ const [email, setEmail] = useState("");
11
+ const [password, setPassword] = useState("");
12
+ const [loading, setLoading] = useState(false);
13
+ const [error, setError] = useState<string | null>(null);
14
+
15
+ const handleLogin = async () => {
16
+ if (!email || !password) {
17
+ setError("Please fill in all fields");
18
+ return;
19
+ }
20
+
21
+ setLoading(true);
22
+ setError(null);
23
+ try {
24
+ const { error } = await authClient.signIn.email({
25
+ email,
26
+ password,
27
+ });
28
+
29
+ if (error) {
30
+ setError(error.message || "Invalid credentials");
31
+ } else {
32
+ router.replace("/(tabs)");
33
+ }
34
+ } catch (err) {
35
+ setError(err instanceof Error ? err.message : "An error occurred during login");
36
+ } finally {
37
+ setLoading(false);
38
+ }
39
+ };
40
+
41
+ return (
42
+ <KeyboardAvoidingView
43
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
44
+ style={styles.container}
45
+ >
46
+ <ScrollView contentContainerStyle={styles.scrollContent}>
47
+ <View style={styles.header}>
48
+ <Text style={styles.title}>Welcome Back</Text>
49
+ <Text style={styles.subtitle}>Sign in to your account</Text>
50
+ </View>
51
+
52
+ <View style={styles.form}>
53
+ <Input
54
+ label="Email"
55
+ placeholder="email@example.com"
56
+ value={email}
57
+ onChangeText={setEmail}
58
+ autoCapitalize="none"
59
+ keyboardType="email-address"
60
+ />
61
+
62
+ <Input
63
+ label="Password"
64
+ placeholder="••••••••"
65
+ value={password}
66
+ onChangeText={setPassword}
67
+ secureTextEntry
68
+ />
69
+
70
+ {error && <Text style={styles.errorText}>{error}</Text>}
71
+
72
+ <Button
73
+ onPress={handleLogin}
74
+ loading={loading}
75
+ >
76
+ Sign In
77
+ </Button>
78
+
79
+ <View style={styles.footer}>
80
+ <Text style={styles.footerText}>Don't have an account? </Text>
81
+ <Text
82
+ style={styles.link}
83
+ onPress={() => router.push("/signup")}
84
+ >
85
+ Sign Up
86
+ </Text>
87
+ </View>
88
+ </View>
89
+ </ScrollView>
90
+ </KeyboardAvoidingView>
91
+ );
92
+ }
93
+
94
+ const styles = StyleSheet.create({
95
+ container: {
96
+ flex: 1,
97
+ backgroundColor: "#fff",
98
+ },
99
+ scrollContent: {
100
+ flexGrow: 1,
101
+ padding: 24,
102
+ justifyContent: "center",
103
+ },
104
+ header: {
105
+ marginBottom: 40,
106
+ },
107
+ title: {
108
+ fontSize: 32,
109
+ fontWeight: "bold",
110
+ marginBottom: 8,
111
+ },
112
+ subtitle: {
113
+ fontSize: 16,
114
+ color: "#666",
115
+ },
116
+ form: {
117
+ gap: 20,
118
+ },
119
+ errorText: {
120
+ color: "#ef4444",
121
+ fontSize: 14,
122
+ },
123
+ footer: {
124
+ flexDirection: "row",
125
+ justifyContent: "center",
126
+ marginTop: 20,
127
+ },
128
+ footerText: {
129
+ color: "#666",
130
+ },
131
+ link: {
132
+ color: "#000",
133
+ fontWeight: "bold",
134
+ },
135
+ });
@@ -0,0 +1,144 @@
1
+ import { useState } from "react";
2
+ import { View, StyleSheet, KeyboardAvoidingView, Platform, ScrollView, Text } from "react-native";
3
+ import { useRouter } from "expo-router";
4
+ import { authClient } from "@/lib/auth-client";
5
+ import { Button } from "@/components/ui/button";
6
+ import { Input } from "@/components/ui/input";
7
+
8
+ export default function SignupScreen() {
9
+ const router = useRouter();
10
+ const [name, setName] = useState("");
11
+ const [email, setEmail] = useState("");
12
+ const [password, setPassword] = useState("");
13
+ const [loading, setLoading] = useState(false);
14
+ const [error, setError] = useState<string | null>(null);
15
+
16
+ const handleSignup = async () => {
17
+ if (!name || !email || !password) {
18
+ setError("Please fill in all fields");
19
+ return;
20
+ }
21
+
22
+ setLoading(true);
23
+ setError(null);
24
+ try {
25
+ const { error } = await authClient.signUp.email({
26
+ email,
27
+ password,
28
+ name,
29
+ });
30
+
31
+ if (error) {
32
+ setError(error.message || "An error occurred during signup");
33
+ } else {
34
+ router.replace("/(tabs)");
35
+ }
36
+ } catch (err) {
37
+ setError(err instanceof Error ? err.message : "An error occurred during signup");
38
+ } finally {
39
+ setLoading(false);
40
+ }
41
+ };
42
+
43
+ return (
44
+ <KeyboardAvoidingView
45
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
46
+ style={styles.container}
47
+ >
48
+ <ScrollView contentContainerStyle={styles.scrollContent}>
49
+ <View style={styles.header}>
50
+ <Text style={styles.title}>Create Account</Text>
51
+ <Text style={styles.subtitle}>Join the Croissant Stack</Text>
52
+ </View>
53
+
54
+ <View style={styles.form}>
55
+ <Input
56
+ label="Name"
57
+ placeholder="John Doe"
58
+ value={name}
59
+ onChangeText={setName}
60
+ />
61
+
62
+ <Input
63
+ label="Email"
64
+ placeholder="email@example.com"
65
+ value={email}
66
+ onChangeText={setEmail}
67
+ autoCapitalize="none"
68
+ keyboardType="email-address"
69
+ />
70
+
71
+ <Input
72
+ label="Password"
73
+ placeholder="••••••••"
74
+ value={password}
75
+ onChangeText={setPassword}
76
+ secureTextEntry
77
+ />
78
+
79
+ {error && <Text style={styles.errorText}>{error}</Text>}
80
+
81
+ <Button
82
+ onPress={handleSignup}
83
+ loading={loading}
84
+ >
85
+ Sign Up
86
+ </Button>
87
+
88
+ <View style={styles.footer}>
89
+ <Text style={styles.footerText}>Already have an account? </Text>
90
+ <Text
91
+ style={styles.link}
92
+ onPress={() => router.push("/login")}
93
+ >
94
+ Sign In
95
+ </Text>
96
+ </View>
97
+ </View>
98
+ </ScrollView>
99
+ </KeyboardAvoidingView>
100
+ );
101
+ }
102
+
103
+ const styles = StyleSheet.create({
104
+ container: {
105
+ flex: 1,
106
+ backgroundColor: "#fff",
107
+ },
108
+ scrollContent: {
109
+ flexGrow: 1,
110
+ padding: 24,
111
+ justifyContent: "center",
112
+ },
113
+ header: {
114
+ marginBottom: 40,
115
+ },
116
+ title: {
117
+ fontSize: 32,
118
+ fontWeight: "bold",
119
+ marginBottom: 8,
120
+ },
121
+ subtitle: {
122
+ fontSize: 16,
123
+ color: "#666",
124
+ },
125
+ form: {
126
+ gap: 20,
127
+ },
128
+ errorText: {
129
+ color: "#ef4444",
130
+ fontSize: 14,
131
+ },
132
+ footer: {
133
+ flexDirection: "row",
134
+ justifyContent: "center",
135
+ marginTop: 20,
136
+ },
137
+ footerText: {
138
+ color: "#666",
139
+ },
140
+ link: {
141
+ color: "#000",
142
+ fontWeight: "bold",
143
+ },
144
+ });
@@ -9,7 +9,12 @@
9
9
  "userInterfaceStyle": "automatic",
10
10
  "newArchEnabled": true,
11
11
  "ios": {
12
- "supportsTablet": true
12
+ "supportsTablet": true,
13
+ "infoPlist": {
14
+ "NSAppTransportSecurity": {
15
+ "NSAllowsLocalNetworking": true
16
+ }
17
+ }
13
18
  },
14
19
  "android": {
15
20
  "adaptiveIcon": {
@@ -23,7 +28,8 @@
23
28
  },
24
29
  "web": {
25
30
  "output": "single",
26
- "favicon": "./assets/images/favicon.png"
31
+ "favicon": "./assets/images/favicon.png",
32
+ "bundler": "metro"
27
33
  },
28
34
  "plugins": [
29
35
  "expo-router",
@@ -44,8 +50,7 @@
44
50
  "expo-web-browser"
45
51
  ],
46
52
  "experiments": {
47
- "typedRoutes": true,
48
- "reactCompiler": true
53
+ "typedRoutes": true
49
54
  }
50
55
  }
51
56
  }