create-croissant 0.1.47 → 0.1.49
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/package.json +1 -1
- package/template/apps/mobile/README.md +3 -3
- package/template/apps/mobile/app/(tabs)/_layout.tsx +17 -25
- package/template/apps/mobile/app/(tabs)/explore.tsx +104 -337
- package/template/apps/mobile/app/(tabs)/index.tsx +85 -99
- package/template/apps/mobile/app/_layout.tsx +13 -32
- package/template/apps/mobile/app/modal.tsx +29 -0
- package/template/apps/mobile/app.json +6 -14
- package/template/apps/mobile/components/external-link.tsx +5 -5
- package/template/apps/mobile/components/haptic-tab.tsx +4 -4
- package/template/apps/mobile/components/hello-wave.tsx +4 -5
- package/template/apps/mobile/components/parallax-scroll-view.tsx +13 -15
- package/template/apps/mobile/components/themed-text.tsx +14 -14
- package/template/apps/mobile/components/themed-view.tsx +3 -3
- package/template/apps/mobile/components/ui/collapsible.tsx +13 -14
- package/template/apps/mobile/components/ui/icon-symbol.ios.tsx +4 -4
- package/template/apps/mobile/components/ui/icon-symbol.tsx +9 -9
- package/template/apps/mobile/constants/theme.ts +19 -19
- package/template/apps/mobile/hooks/use-color-scheme.ts +1 -1
- package/template/apps/mobile/hooks/use-color-scheme.web.ts +3 -3
- package/template/apps/mobile/hooks/use-theme-color.ts +4 -4
- package/template/apps/mobile/package.json +26 -38
- package/template/apps/mobile/scripts/reset-project.js +2 -2
- package/template/apps/mobile/tsconfig.json +9 -2
- package/template/apps/platform/src/routes/api/auth/$.ts +1 -1
- package/template/apps/platform/src/routes/api/rpc.$.ts +2 -2
- package/template/package.json +12 -14
- package/template/pnpm-workspace.yaml +8 -0
- package/template/tsconfig.json +1 -2
- package/template/apps/mobile/app/(tabs)/account.tsx +0 -147
- package/template/apps/mobile/app/index.tsx +0 -129
- package/template/apps/mobile/app/login.tsx +0 -135
- package/template/apps/mobile/app/signup.tsx +0 -144
- package/template/apps/mobile/components/ui/button.tsx +0 -86
- package/template/apps/mobile/components/ui/input.tsx +0 -56
- package/template/apps/mobile/lib/auth-client.ts +0 -14
- package/template/apps/mobile/lib/orpc.ts +0 -28
|
@@ -3,26 +3,26 @@
|
|
|
3
3
|
* There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { Platform } from
|
|
6
|
+
import { Platform } from 'react-native';
|
|
7
7
|
|
|
8
|
-
const tintColorLight =
|
|
9
|
-
const tintColorDark =
|
|
8
|
+
const tintColorLight = '#0a7ea4';
|
|
9
|
+
const tintColorDark = '#fff';
|
|
10
10
|
|
|
11
11
|
export const Colors = {
|
|
12
12
|
light: {
|
|
13
|
-
text:
|
|
14
|
-
background:
|
|
13
|
+
text: '#11181C',
|
|
14
|
+
background: '#fff',
|
|
15
15
|
tint: tintColorLight,
|
|
16
|
-
icon:
|
|
17
|
-
tabIconDefault:
|
|
16
|
+
icon: '#687076',
|
|
17
|
+
tabIconDefault: '#687076',
|
|
18
18
|
tabIconSelected: tintColorLight,
|
|
19
19
|
},
|
|
20
20
|
dark: {
|
|
21
|
-
text:
|
|
22
|
-
background:
|
|
21
|
+
text: '#ECEDEE',
|
|
22
|
+
background: '#151718',
|
|
23
23
|
tint: tintColorDark,
|
|
24
|
-
icon:
|
|
25
|
-
tabIconDefault:
|
|
24
|
+
icon: '#9BA1A6',
|
|
25
|
+
tabIconDefault: '#9BA1A6',
|
|
26
26
|
tabIconSelected: tintColorDark,
|
|
27
27
|
},
|
|
28
28
|
};
|
|
@@ -30,19 +30,19 @@ export const Colors = {
|
|
|
30
30
|
export const Fonts = Platform.select({
|
|
31
31
|
ios: {
|
|
32
32
|
/** iOS `UIFontDescriptorSystemDesignDefault` */
|
|
33
|
-
sans:
|
|
33
|
+
sans: 'system-ui',
|
|
34
34
|
/** iOS `UIFontDescriptorSystemDesignSerif` */
|
|
35
|
-
serif:
|
|
35
|
+
serif: 'ui-serif',
|
|
36
36
|
/** iOS `UIFontDescriptorSystemDesignRounded` */
|
|
37
|
-
rounded:
|
|
37
|
+
rounded: 'ui-rounded',
|
|
38
38
|
/** iOS `UIFontDescriptorSystemDesignMonospaced` */
|
|
39
|
-
mono:
|
|
39
|
+
mono: 'ui-monospace',
|
|
40
40
|
},
|
|
41
41
|
default: {
|
|
42
|
-
sans:
|
|
43
|
-
serif:
|
|
44
|
-
rounded:
|
|
45
|
-
mono:
|
|
42
|
+
sans: 'normal',
|
|
43
|
+
serif: 'serif',
|
|
44
|
+
rounded: 'normal',
|
|
45
|
+
mono: 'monospace',
|
|
46
46
|
},
|
|
47
47
|
web: {
|
|
48
48
|
sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { useColorScheme } from
|
|
1
|
+
export { useColorScheme } from 'react-native';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useEffect, useState } from
|
|
2
|
-
import { useColorScheme as useRNColorScheme } from
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useColorScheme as useRNColorScheme } from 'react-native';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* To support static rendering, this value needs to be re-calculated on the client side for web
|
|
@@ -17,5 +17,5 @@ export function useColorScheme() {
|
|
|
17
17
|
return colorScheme;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
return
|
|
20
|
+
return 'light';
|
|
21
21
|
}
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* https://docs.expo.dev/guides/color-schemes/
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { Colors } from
|
|
7
|
-
import { useColorScheme } from
|
|
6
|
+
import { Colors } from '@/constants/theme';
|
|
7
|
+
import { useColorScheme } from '@/hooks/use-color-scheme';
|
|
8
8
|
|
|
9
9
|
export function useThemeColor(
|
|
10
10
|
props: { light?: string; dark?: string },
|
|
11
|
-
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
|
|
11
|
+
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
|
|
12
12
|
) {
|
|
13
|
-
const theme = useColorScheme() ??
|
|
13
|
+
const theme = useColorScheme() ?? 'light';
|
|
14
14
|
const colorFromProps = props[theme];
|
|
15
15
|
|
|
16
16
|
if (colorFromProps) {
|
|
@@ -1,57 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobile",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"private": true,
|
|
5
3
|
"main": "expo-router/entry",
|
|
4
|
+
"version": "1.0.0",
|
|
6
5
|
"scripts": {
|
|
7
6
|
"dev": "expo start",
|
|
8
7
|
"start": "expo start",
|
|
9
8
|
"reset-project": "node ./scripts/reset-project.js",
|
|
10
9
|
"android": "expo start --android",
|
|
11
10
|
"ios": "expo start --ios",
|
|
12
|
-
"web": "expo start --web"
|
|
13
|
-
"build": "expo export --output-dir .output"
|
|
11
|
+
"web": "expo start --web"
|
|
14
12
|
},
|
|
15
13
|
"dependencies": {
|
|
16
|
-
"@better-auth/expo": "^1.6.9",
|
|
17
14
|
"@expo/vector-icons": "^15.0.3",
|
|
18
|
-
"@orpc/client": "^1.14.0",
|
|
19
|
-
"@orpc/server": "^1.14.0",
|
|
20
|
-
"@orpc/tanstack-query": "^1.14.0",
|
|
21
15
|
"@react-navigation/bottom-tabs": "^7.4.0",
|
|
22
16
|
"@react-navigation/elements": "^2.6.3",
|
|
23
17
|
"@react-navigation/native": "^7.1.8",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"expo": "
|
|
30
|
-
"expo-
|
|
31
|
-
"expo-
|
|
32
|
-
"expo-
|
|
33
|
-
"expo-
|
|
34
|
-
"expo-
|
|
35
|
-
"expo-
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"expo-web-browser": "~55.0.14",
|
|
43
|
-
"react": "19.2.5",
|
|
44
|
-
"react-dom": "19.2.5",
|
|
45
|
-
"react-native": "0.83.6",
|
|
46
|
-
"react-native-gesture-handler": "~2.30.0",
|
|
47
|
-
"react-native-reanimated": "4.2.1",
|
|
18
|
+
"expo": "~54.0.33",
|
|
19
|
+
"expo-constants": "~18.0.13",
|
|
20
|
+
"expo-font": "~14.0.11",
|
|
21
|
+
"expo-haptics": "~15.0.8",
|
|
22
|
+
"expo-image": "~3.0.11",
|
|
23
|
+
"expo-linking": "~8.0.11",
|
|
24
|
+
"expo-router": "~6.0.23",
|
|
25
|
+
"expo-splash-screen": "~31.0.13",
|
|
26
|
+
"expo-status-bar": "~3.0.9",
|
|
27
|
+
"expo-symbols": "~1.0.8",
|
|
28
|
+
"expo-system-ui": "~6.0.9",
|
|
29
|
+
"expo-web-browser": "~15.0.10",
|
|
30
|
+
"react": "19.1.0",
|
|
31
|
+
"react-dom": "19.1.0",
|
|
32
|
+
"react-native": "0.81.5",
|
|
33
|
+
"react-native-gesture-handler": "~2.28.0",
|
|
34
|
+
"react-native-worklets": "0.5.1",
|
|
35
|
+
"react-native-reanimated": "~4.1.1",
|
|
48
36
|
"react-native-safe-area-context": "~5.6.0",
|
|
49
|
-
"react-native-screens": "~4.
|
|
50
|
-
"react-native-web": "~0.21.0"
|
|
51
|
-
"react-native-worklets": "0.7.4"
|
|
37
|
+
"react-native-screens": "~4.16.0",
|
|
38
|
+
"react-native-web": "~0.21.0"
|
|
52
39
|
},
|
|
53
40
|
"devDependencies": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
}
|
|
41
|
+
"@workspace/config-typescript": "workspace:*",
|
|
42
|
+
"@types/react": "~19.1.0"
|
|
43
|
+
},
|
|
44
|
+
"private": true
|
|
57
45
|
}
|
|
@@ -91,7 +91,7 @@ const moveDirectories = async (userInput) => {
|
|
|
91
91
|
userInput === "y"
|
|
92
92
|
? `\n3. Delete the /${exampleDir} directory when you're done referencing it.`
|
|
93
93
|
: ""
|
|
94
|
-
}
|
|
94
|
+
}`
|
|
95
95
|
);
|
|
96
96
|
} catch (error) {
|
|
97
97
|
console.error(`❌ Error during script execution: ${error.message}`);
|
|
@@ -108,5 +108,5 @@ rl.question(
|
|
|
108
108
|
console.log("❌ Invalid input. Please enter 'Y' or 'N'.");
|
|
109
109
|
rl.close();
|
|
110
110
|
}
|
|
111
|
-
}
|
|
111
|
+
}
|
|
112
112
|
);
|
|
@@ -6,8 +6,15 @@
|
|
|
6
6
|
"compilerOptions": {
|
|
7
7
|
"strict": true,
|
|
8
8
|
"paths": {
|
|
9
|
-
"@/*": [
|
|
9
|
+
"@/*": [
|
|
10
|
+
"./*"
|
|
11
|
+
]
|
|
10
12
|
}
|
|
11
13
|
},
|
|
12
|
-
"include": [
|
|
14
|
+
"include": [
|
|
15
|
+
"**/*.ts",
|
|
16
|
+
"**/*.tsx",
|
|
17
|
+
".expo/types/**/*.ts",
|
|
18
|
+
"expo-env.d.ts"
|
|
19
|
+
]
|
|
13
20
|
}
|
|
@@ -2,7 +2,7 @@ import { auth } from "@workspace/auth/lib/auth";
|
|
|
2
2
|
import { createFileRoute } from "@tanstack/react-router";
|
|
3
3
|
|
|
4
4
|
const CORS_HEADERS = {
|
|
5
|
-
"Access-Control-Allow-Origin": "
|
|
5
|
+
"Access-Control-Allow-Origin": "*",
|
|
6
6
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
7
7
|
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
8
8
|
"Access-Control-Allow-Credentials": "true",
|
|
@@ -28,7 +28,7 @@ export const Route = createFileRoute("/api/rpc/$")({
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
if (response) {
|
|
31
|
-
response.headers.set("Access-Control-Allow-Origin", "
|
|
31
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
32
32
|
response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
33
33
|
response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
34
34
|
response.headers.set("Access-Control-Allow-Credentials", "true");
|
|
@@ -40,7 +40,7 @@ export const Route = createFileRoute("/api/rpc/$")({
|
|
|
40
40
|
return new Response(null, {
|
|
41
41
|
status: 204,
|
|
42
42
|
headers: {
|
|
43
|
-
"Access-Control-Allow-Origin": "
|
|
43
|
+
"Access-Control-Allow-Origin": "*",
|
|
44
44
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
45
45
|
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
46
46
|
"Access-Control-Allow-Credentials": "true",
|
package/template/package.json
CHANGED
|
@@ -13,9 +13,6 @@
|
|
|
13
13
|
"quality": "turbo quality",
|
|
14
14
|
"quality:fix": "turbo quality:fix",
|
|
15
15
|
"typecheck": "turbo typecheck",
|
|
16
|
-
"dev:mobile": "turbo run dev --filter=mobile",
|
|
17
|
-
"dev:ios": "turbo run dev --filter=mobile -- --ios",
|
|
18
|
-
"dev:android": "turbo run dev --filter=mobile -- --android",
|
|
19
16
|
"ci": "pnpm run lint && pnpm run typecheck && pnpm run build",
|
|
20
17
|
"db:up": "docker compose up -d",
|
|
21
18
|
"db:down": "docker compose down",
|
|
@@ -25,14 +22,13 @@
|
|
|
25
22
|
},
|
|
26
23
|
"dependencies": {
|
|
27
24
|
"react": "19.2.5",
|
|
28
|
-
"react-dom": "19.2.5"
|
|
29
|
-
"react-native": "0.83.6"
|
|
25
|
+
"react-dom": "19.2.5"
|
|
30
26
|
},
|
|
31
27
|
"devDependencies": {
|
|
32
28
|
"@better-auth/core": "^1.6.9",
|
|
33
29
|
"@types/react": "^19.2.7",
|
|
34
30
|
"@types/react-dom": "^19.2.3",
|
|
35
|
-
"husky": "
|
|
31
|
+
"husky": "latest",
|
|
36
32
|
"oxfmt": "latest",
|
|
37
33
|
"oxlint": "latest",
|
|
38
34
|
"portless": "^0.11.0",
|
|
@@ -42,16 +38,18 @@
|
|
|
42
38
|
"zod": "4.3.6"
|
|
43
39
|
},
|
|
44
40
|
"pnpm": {
|
|
45
|
-
"
|
|
46
|
-
"@
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
41
|
+
"onlyBuiltDependencies": [
|
|
42
|
+
"@prisma/client",
|
|
43
|
+
"better-sqlite3",
|
|
44
|
+
"electron-winstaller",
|
|
45
|
+
"electron",
|
|
46
|
+
"esbuild",
|
|
47
|
+
"msw",
|
|
48
|
+
"unrs-resolver"
|
|
49
|
+
]
|
|
52
50
|
},
|
|
53
51
|
"engines": {
|
|
54
52
|
"node": ">=20"
|
|
55
53
|
},
|
|
56
|
-
"packageManager": "pnpm@
|
|
54
|
+
"packageManager": "pnpm@11.1.0"
|
|
57
55
|
}
|
package/template/tsconfig.json
CHANGED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from "react";
|
|
2
|
-
import { View, Text, StyleSheet, ScrollView, Alert, ActivityIndicator } 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 AccountScreen() {
|
|
9
|
-
const router = useRouter();
|
|
10
|
-
const { data: session, isPending } = authClient.useSession();
|
|
11
|
-
const [updating, setUpdating] = useState(false);
|
|
12
|
-
|
|
13
|
-
// Form states
|
|
14
|
-
const [name, setName] = useState("");
|
|
15
|
-
const [email, setEmail] = useState("");
|
|
16
|
-
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
if (!isPending && !session) {
|
|
19
|
-
router.replace("/login");
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (session) {
|
|
24
|
-
setName(session.user.name);
|
|
25
|
-
setEmail(session.user.email);
|
|
26
|
-
}
|
|
27
|
-
}, [session, isPending, router]);
|
|
28
|
-
|
|
29
|
-
const handleUpdateProfile = async () => {
|
|
30
|
-
if (!name) {
|
|
31
|
-
Alert.alert("Error", "Name is required");
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
setUpdating(true);
|
|
36
|
-
try {
|
|
37
|
-
const { error } = await authClient.updateUser({
|
|
38
|
-
name,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
if (error) {
|
|
42
|
-
Alert.alert("Error", error.message || "Failed to update profile");
|
|
43
|
-
} else {
|
|
44
|
-
Alert.alert("Success", "Profile updated successfully");
|
|
45
|
-
}
|
|
46
|
-
} catch (err) {
|
|
47
|
-
Alert.alert("Error", "An unexpected error occurred");
|
|
48
|
-
} finally {
|
|
49
|
-
setUpdating(false);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
if (isPending) {
|
|
54
|
-
return (
|
|
55
|
-
<View style={styles.center}>
|
|
56
|
-
<ActivityIndicator size="large" color="#000" />
|
|
57
|
-
</View>
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return (
|
|
62
|
-
<ScrollView style={styles.container} contentContainerStyle={styles.content}>
|
|
63
|
-
<Text style={styles.title}>Account Settings</Text>
|
|
64
|
-
|
|
65
|
-
<View style={styles.section}>
|
|
66
|
-
<Text style={styles.sectionTitle}>Profile Information</Text>
|
|
67
|
-
<View style={styles.form}>
|
|
68
|
-
<Input
|
|
69
|
-
label="Name"
|
|
70
|
-
value={name}
|
|
71
|
-
onChangeText={setName}
|
|
72
|
-
placeholder="Your name"
|
|
73
|
-
/>
|
|
74
|
-
<Input
|
|
75
|
-
label="Email"
|
|
76
|
-
value={email}
|
|
77
|
-
editable={false}
|
|
78
|
-
style={styles.disabledInput}
|
|
79
|
-
/>
|
|
80
|
-
<Button
|
|
81
|
-
onPress={handleUpdateProfile}
|
|
82
|
-
loading={updating}
|
|
83
|
-
style={styles.button}
|
|
84
|
-
>
|
|
85
|
-
Update Profile
|
|
86
|
-
</Button>
|
|
87
|
-
</View>
|
|
88
|
-
</View>
|
|
89
|
-
|
|
90
|
-
<View style={styles.section}>
|
|
91
|
-
<Text style={styles.sectionTitle}>Security</Text>
|
|
92
|
-
<Text style={styles.infoText}>
|
|
93
|
-
Password management and other security settings are currently available on the web platform.
|
|
94
|
-
</Text>
|
|
95
|
-
</View>
|
|
96
|
-
</ScrollView>
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const styles = StyleSheet.create({
|
|
101
|
-
container: {
|
|
102
|
-
flex: 1,
|
|
103
|
-
backgroundColor: "#fff",
|
|
104
|
-
},
|
|
105
|
-
content: {
|
|
106
|
-
padding: 24,
|
|
107
|
-
},
|
|
108
|
-
center: {
|
|
109
|
-
flex: 1,
|
|
110
|
-
justifyContent: "center",
|
|
111
|
-
alignItems: "center",
|
|
112
|
-
},
|
|
113
|
-
title: {
|
|
114
|
-
fontSize: 28,
|
|
115
|
-
fontWeight: "bold",
|
|
116
|
-
marginBottom: 24,
|
|
117
|
-
},
|
|
118
|
-
section: {
|
|
119
|
-
marginBottom: 32,
|
|
120
|
-
},
|
|
121
|
-
sectionTitle: {
|
|
122
|
-
fontSize: 18,
|
|
123
|
-
fontWeight: "600",
|
|
124
|
-
marginBottom: 16,
|
|
125
|
-
color: "#333",
|
|
126
|
-
},
|
|
127
|
-
form: {
|
|
128
|
-
gap: 16,
|
|
129
|
-
},
|
|
130
|
-
disabledInput: {
|
|
131
|
-
backgroundColor: "#f5f5f5",
|
|
132
|
-
color: "#888",
|
|
133
|
-
},
|
|
134
|
-
button: {
|
|
135
|
-
marginTop: 8,
|
|
136
|
-
},
|
|
137
|
-
infoText: {
|
|
138
|
-
fontSize: 14,
|
|
139
|
-
color: "#666",
|
|
140
|
-
lineHeight: 20,
|
|
141
|
-
backgroundColor: "#f9f9f9",
|
|
142
|
-
padding: 16,
|
|
143
|
-
borderRadius: 8,
|
|
144
|
-
borderWidth: 1,
|
|
145
|
-
borderColor: "#eee",
|
|
146
|
-
},
|
|
147
|
-
});
|
|
@@ -1,129 +0,0 @@
|
|
|
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
|
-
});
|