@idealyst/cli 1.0.90 → 1.0.91
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 +2 -2
- package/template/.devcontainer/Dockerfile +26 -0
- package/template/.devcontainer/devcontainer.json +113 -0
- package/template/.devcontainer/docker-compose.yml +59 -0
- package/template/.devcontainer/figma-mcp.sh +32 -0
- package/template/.devcontainer/setup.sh +45 -0
- package/template/.dockerignore +151 -0
- package/template/.env.example +36 -0
- package/template/.env.production +56 -0
- package/template/DOCKER.md +0 -0
- package/template/Dockerfile +111 -0
- package/template/README.md +233 -0
- package/template/docker/nginx/prod.conf +238 -0
- package/template/docker/nginx.conf +131 -0
- package/template/docker/postgres/init.sql +41 -0
- package/template/docker/prometheus/prometheus.yml +52 -0
- package/template/docker-compose.prod.yml +146 -0
- package/template/docker-compose.yml +143 -0
- package/template/jest.config.js +20 -0
- package/template/package.json +45 -0
- package/template/packages/api/.env.example +6 -0
- package/template/packages/api/README.md +274 -0
- package/template/packages/api/__tests__/api.test.ts +26 -0
- package/template/packages/api/jest.config.js +23 -0
- package/template/packages/api/jest.setup.js +9 -0
- package/template/packages/api/package.json +56 -0
- package/template/packages/api/src/context.ts +19 -0
- package/template/packages/api/src/controllers/TestController.ts +0 -0
- package/template/packages/api/src/index.ts +9 -0
- package/template/packages/api/src/lib/crud.ts +150 -0
- package/template/packages/api/src/lib/database.ts +23 -0
- package/template/packages/api/src/router/index.ts +163 -0
- package/template/packages/api/src/routers/test.ts +59 -0
- package/template/packages/api/src/routers/user.example.ts +83 -0
- package/template/packages/api/src/server.ts +50 -0
- package/template/packages/api/src/trpc.ts +28 -0
- package/template/packages/api/tsconfig.json +43 -0
- package/template/packages/database/README.md +162 -0
- package/template/packages/database/package.json +49 -0
- package/template/packages/database/prisma/seed.ts +64 -0
- package/template/packages/database/schema.prisma +107 -0
- package/template/packages/database/src/index.ts +15 -0
- package/template/packages/database/src/validators.ts +10 -0
- package/template/packages/database/tsconfig.json +18 -0
- package/template/packages/mobile/README.md +86 -0
- package/template/packages/mobile/__tests__/App.test.tsx +156 -0
- package/template/packages/mobile/__tests__/components.test.tsx +300 -0
- package/template/packages/mobile/app.json +5 -0
- package/template/packages/mobile/babel.config.js +11 -0
- package/template/packages/mobile/index.js +6 -0
- package/template/packages/mobile/jest.config.js +21 -0
- package/template/packages/mobile/jest.setup.js +12 -0
- package/template/packages/mobile/metro.config.js +27 -0
- package/template/packages/mobile/package.json +52 -0
- package/template/packages/mobile/src/App-with-trpc-and-shared.tsx +8 -0
- package/template/packages/mobile/src/App-with-trpc.tsx +30 -0
- package/template/packages/mobile/src/App.tsx +8 -0
- package/template/packages/mobile/src/utils/trpc.ts +7 -0
- package/template/packages/mobile/tsconfig.json +28 -0
- package/template/packages/shared/README.md +135 -0
- package/template/packages/shared/__tests__/shared.test.ts +51 -0
- package/template/packages/shared/jest.config.js +22 -0
- package/template/packages/shared/package.json +62 -0
- package/template/packages/shared/src/components/App.tsx +46 -0
- package/template/packages/shared/src/components/HelloWorld.tsx +304 -0
- package/template/packages/shared/src/components/index.ts +1 -0
- package/template/packages/shared/src/index.ts +14 -0
- package/template/packages/shared/src/navigation/AppRouter.tsx +565 -0
- package/template/packages/shared/src/trpc/client.ts +44 -0
- package/template/packages/shared/tsconfig.json +22 -0
- package/template/packages/web/README.md +131 -0
- package/template/packages/web/__tests__/App.test.tsx +342 -0
- package/template/packages/web/__tests__/components.test.tsx +564 -0
- package/template/packages/web/index.html +13 -0
- package/template/packages/web/jest.config.js +27 -0
- package/template/packages/web/jest.setup.js +24 -0
- package/template/packages/web/package.json +69 -0
- package/template/packages/web/src/App-with-trpc-and-shared.tsx +14 -0
- package/template/packages/web/src/App-with-trpc.tsx +32 -0
- package/template/packages/web/src/App.tsx +14 -0
- package/template/packages/web/src/components/TestDemo.tsx +164 -0
- package/template/packages/web/src/main.tsx +25 -0
- package/template/packages/web/src/utils/trpc.ts +7 -0
- package/template/packages/web/tsconfig.json +26 -0
- package/template/packages/web/vite.config.ts +98 -0
- package/template/setup.sh +30 -0
- package/template/tsconfig.json +31 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { HelloWorld } from '../src/index';
|
|
2
|
+
|
|
3
|
+
describe('Shared Library', () => {
|
|
4
|
+
it('should export HelloWorld component', () => {
|
|
5
|
+
expect(HelloWorld).toBeDefined();
|
|
6
|
+
expect(typeof HelloWorld).toBe('function');
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('HelloWorld Component', () => {
|
|
11
|
+
it('should be a React component', () => {
|
|
12
|
+
expect(HelloWorld).toBeDefined();
|
|
13
|
+
expect(typeof HelloWorld).toBe('function');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should accept props', () => {
|
|
17
|
+
// Test that the component function exists and can be called
|
|
18
|
+
// Note: Full component testing would require a React testing environment
|
|
19
|
+
expect(() => HelloWorld({ name: 'Test' })).not.toThrow();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('Sample Shared Tests', () => {
|
|
24
|
+
it('should pass a basic test', () => {
|
|
25
|
+
expect(1 + 1).toBe(2);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should handle string operations', () => {
|
|
29
|
+
const testString = 'Hello World';
|
|
30
|
+
expect(testString).toContain('World');
|
|
31
|
+
expect(testString.length).toBe(11);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should work with objects', () => {
|
|
35
|
+
const testObj = { name: 'test', value: 42 };
|
|
36
|
+
expect(testObj).toHaveProperty('name');
|
|
37
|
+
expect(testObj).toHaveProperty('value', 42);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should handle arrays', () => {
|
|
41
|
+
const testArray = [1, 2, 3, 4, 5];
|
|
42
|
+
expect(testArray).toHaveLength(5);
|
|
43
|
+
expect(testArray).toContain(3);
|
|
44
|
+
expect(testArray.filter(x => x > 3)).toEqual([4, 5]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should work with async operations', async () => {
|
|
48
|
+
const result = await Promise.resolve('async test');
|
|
49
|
+
expect(result).toBe('async test');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** @type {import('jest').Config} */
|
|
2
|
+
module.exports = {
|
|
3
|
+
preset: 'ts-jest',
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
roots: ['<rootDir>/src', '<rootDir>/__tests__'],
|
|
6
|
+
testMatch: [
|
|
7
|
+
'**/__tests__/**/*.{ts,tsx,js}',
|
|
8
|
+
'**/*.{test,spec}.{ts,tsx,js}'
|
|
9
|
+
],
|
|
10
|
+
transform: {
|
|
11
|
+
'^.+\\.tsx?$': 'ts-jest',
|
|
12
|
+
},
|
|
13
|
+
collectCoverageFrom: [
|
|
14
|
+
'src/**/*.{ts,tsx}',
|
|
15
|
+
'!src/**/*.d.ts',
|
|
16
|
+
'!src/**/index.ts',
|
|
17
|
+
],
|
|
18
|
+
coverageDirectory: 'coverage',
|
|
19
|
+
coverageReporters: ['text', 'lcov'],
|
|
20
|
+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
|
21
|
+
testTimeout: 10000,
|
|
22
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@{{workspaceScope}}/shared",
|
|
3
|
+
"version": "{{version}}",
|
|
4
|
+
"description": "{{description}}",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"module": "src/index.ts",
|
|
7
|
+
"types": "src/index.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./src/index.ts",
|
|
11
|
+
"require": "./src/index.ts",
|
|
12
|
+
"types": "./src/index.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"test:watch": "jest --watch",
|
|
18
|
+
"test:coverage": "jest --coverage",
|
|
19
|
+
"type-check": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@idealyst/components": "^{{idealystVersion}}",
|
|
23
|
+
"@idealyst/navigation": "^{{idealystVersion}}",
|
|
24
|
+
"@idealyst/theme": "^{{idealystVersion}}",
|
|
25
|
+
"@tanstack/react-query": "^5.83.0",
|
|
26
|
+
"@trpc/client": "^11.5.1",
|
|
27
|
+
"@trpc/react-query": "^11.5.1",
|
|
28
|
+
"@trpc/server": "^11.5.1",
|
|
29
|
+
"react": "^19.1.0",
|
|
30
|
+
"react-native": "^0.80.1",
|
|
31
|
+
"@{{workspaceScope}}/api": "*"
|
|
32
|
+
},
|
|
33
|
+
"peerDependenciesMeta": {
|
|
34
|
+
"react-native": {
|
|
35
|
+
"optional": true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@idealyst/components": "^{{idealystVersion}}",
|
|
40
|
+
"@idealyst/navigation": "^{{idealystVersion}}",
|
|
41
|
+
"@idealyst/theme": "^{{idealystVersion}}",
|
|
42
|
+
"@tanstack/react-query": "^5.83.0",
|
|
43
|
+
"@trpc/client": "^11.5.1",
|
|
44
|
+
"@trpc/react-query": "^11.5.1",
|
|
45
|
+
"@trpc/server": "^11.5.1",
|
|
46
|
+
"@types/jest": "^29.5.12",
|
|
47
|
+
"@types/react": "^19.1.0",
|
|
48
|
+
"jest": "^29.7.0",
|
|
49
|
+
"ts-jest": "^29.1.2",
|
|
50
|
+
"typescript": "^5.0.0"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"src"
|
|
54
|
+
],
|
|
55
|
+
"keywords": [
|
|
56
|
+
"react",
|
|
57
|
+
"react-native",
|
|
58
|
+
"cross-platform",
|
|
59
|
+
"shared",
|
|
60
|
+
"library"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { NavigatorProvider } from "@idealyst/navigation";
|
|
2
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import AppRouter from "../navigation/AppRouter";
|
|
5
|
+
import { createTRPCClient, trpc } from "../trpc/client";
|
|
6
|
+
|
|
7
|
+
interface AppProps {
|
|
8
|
+
apiUrl?: string;
|
|
9
|
+
queryClient?: QueryClient;
|
|
10
|
+
headers?: () => Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Default query client instance
|
|
14
|
+
const defaultQueryClient = new QueryClient({
|
|
15
|
+
defaultOptions: {
|
|
16
|
+
queries: {
|
|
17
|
+
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Unified App component that sets up tRPC, React Query providers, and Navigation
|
|
24
|
+
* This component can be used by both web and mobile platforms
|
|
25
|
+
*/
|
|
26
|
+
export const App: React.FC<AppProps> = ({
|
|
27
|
+
apiUrl = "http://localhost:3000/trpc",
|
|
28
|
+
queryClient = defaultQueryClient,
|
|
29
|
+
headers,
|
|
30
|
+
}) => {
|
|
31
|
+
// Create tRPC client with the provided configuration
|
|
32
|
+
const trpcClient = createTRPCClient({
|
|
33
|
+
apiUrl,
|
|
34
|
+
headers,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
|
39
|
+
<QueryClientProvider client={queryClient}>
|
|
40
|
+
<NavigatorProvider route={AppRouter} />
|
|
41
|
+
</QueryClientProvider>
|
|
42
|
+
</trpc.Provider>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default App;
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { Button, Card, Input, Screen, Text, View } from "@idealyst/components";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { trpc } from "../trpc/client";
|
|
4
|
+
|
|
5
|
+
interface HelloWorldProps {
|
|
6
|
+
name?: string;
|
|
7
|
+
platform?: "web" | "mobile";
|
|
8
|
+
projectName?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const HelloWorld = ({
|
|
12
|
+
name = "World",
|
|
13
|
+
platform = "web",
|
|
14
|
+
projectName = "Your Project",
|
|
15
|
+
}: HelloWorldProps) => {
|
|
16
|
+
const [newTestName, setNewTestName] = useState("");
|
|
17
|
+
const [newTestMessage, setNewTestMessage] = useState("");
|
|
18
|
+
|
|
19
|
+
// Use tRPC hooks directly
|
|
20
|
+
const tests = trpc.test.getAll.useQuery({});
|
|
21
|
+
const createTestMutation = trpc.test.create.useMutation({
|
|
22
|
+
onSuccess: () => {
|
|
23
|
+
tests.refetch();
|
|
24
|
+
setNewTestName("");
|
|
25
|
+
setNewTestMessage("");
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
const deleteTestMutation = trpc.test.delete.useMutation({
|
|
29
|
+
onSuccess: () => {
|
|
30
|
+
tests.refetch();
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const handleCreateTest = async () => {
|
|
35
|
+
if (!newTestName || !newTestMessage) return;
|
|
36
|
+
|
|
37
|
+
await createTestMutation.mutateAsync({
|
|
38
|
+
name: newTestName,
|
|
39
|
+
message: newTestMessage,
|
|
40
|
+
status: "active",
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handleDeleteTest = async (id: string) => {
|
|
45
|
+
await deleteTestMutation.mutateAsync({ id });
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const platformEmoji = platform === "mobile" ? "📱" : "🌐";
|
|
49
|
+
const platformText =
|
|
50
|
+
platform === "mobile"
|
|
51
|
+
? "Your mobile development environment is ready. This shared component works seamlessly across mobile and web platforms."
|
|
52
|
+
: "Your web development environment is ready. This shared component works seamlessly across web and mobile platforms.";
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Screen style={{ flex: 1, padding: 20 }}>
|
|
56
|
+
<View style={{ maxWidth: 600, alignSelf: "center" }}>
|
|
57
|
+
<Text
|
|
58
|
+
size="xl"
|
|
59
|
+
weight="bold"
|
|
60
|
+
style={{
|
|
61
|
+
marginBottom: 16,
|
|
62
|
+
textAlign: "center",
|
|
63
|
+
color: "#1e293b",
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
Welcome to {projectName}! {platformEmoji}
|
|
67
|
+
</Text>
|
|
68
|
+
|
|
69
|
+
<Text
|
|
70
|
+
size="lg"
|
|
71
|
+
style={{
|
|
72
|
+
marginBottom: 32,
|
|
73
|
+
textAlign: "center",
|
|
74
|
+
color: "#64748b",
|
|
75
|
+
lineHeight: 24,
|
|
76
|
+
paddingHorizontal: 16,
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
{platformText}
|
|
80
|
+
</Text>
|
|
81
|
+
{/* Framework Branding Card */}
|
|
82
|
+
<Card type="elevated" padding="lg" intent="primary">
|
|
83
|
+
<View style={{ alignItems: "center" }}>
|
|
84
|
+
<Text style={{ fontSize: 32, marginBottom: 16 }}>🚀</Text>
|
|
85
|
+
<Text
|
|
86
|
+
size="xl"
|
|
87
|
+
weight="bold"
|
|
88
|
+
style={{ marginBottom: 8, textAlign: "center" }}
|
|
89
|
+
>
|
|
90
|
+
Idealyst Framework
|
|
91
|
+
</Text>
|
|
92
|
+
<Text size="md" style={{ marginBottom: 16, textAlign: "center" }}>
|
|
93
|
+
Hello, {name}! Welcome to your cross-platform workspace.
|
|
94
|
+
</Text>
|
|
95
|
+
|
|
96
|
+
{/* Technology Tags */}
|
|
97
|
+
<View
|
|
98
|
+
style={{
|
|
99
|
+
flexDirection: "row",
|
|
100
|
+
flexWrap: "wrap",
|
|
101
|
+
justifyContent: "center",
|
|
102
|
+
gap: 8,
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
<Card
|
|
106
|
+
type="filled"
|
|
107
|
+
padding="sm"
|
|
108
|
+
style={{ backgroundColor: "rgba(255, 255, 255, 0.2)" }}
|
|
109
|
+
>
|
|
110
|
+
<Text size="sm" weight="semibold">
|
|
111
|
+
React
|
|
112
|
+
</Text>
|
|
113
|
+
</Card>
|
|
114
|
+
<Card
|
|
115
|
+
type="filled"
|
|
116
|
+
padding="sm"
|
|
117
|
+
style={{ backgroundColor: "rgba(255, 255, 255, 0.2)" }}
|
|
118
|
+
>
|
|
119
|
+
<Text size="sm" weight="semibold">
|
|
120
|
+
TypeScript
|
|
121
|
+
</Text>
|
|
122
|
+
</Card>
|
|
123
|
+
<Card
|
|
124
|
+
type="filled"
|
|
125
|
+
padding="sm"
|
|
126
|
+
style={{ backgroundColor: "rgba(255, 255, 255, 0.2)" }}
|
|
127
|
+
>
|
|
128
|
+
<Text size="sm" weight="semibold">
|
|
129
|
+
Cross-Platform
|
|
130
|
+
</Text>
|
|
131
|
+
</Card>
|
|
132
|
+
</View>
|
|
133
|
+
</View>
|
|
134
|
+
</Card>
|
|
135
|
+
|
|
136
|
+
{/* Quick Start Guide Card */}
|
|
137
|
+
<Card type="outlined" padding="lg" style={{ marginTop: 16 }}>
|
|
138
|
+
<Text size="lg" weight="bold" style={{ marginBottom: 16 }}>
|
|
139
|
+
🎯 Quick Start Guide
|
|
140
|
+
</Text>
|
|
141
|
+
|
|
142
|
+
<View style={{ marginBottom: 16 }}>
|
|
143
|
+
<Text size="md" weight="semibold" style={{ marginBottom: 8 }}>
|
|
144
|
+
Your Workspace Overview:
|
|
145
|
+
</Text>
|
|
146
|
+
<Text size="sm" style={{ marginBottom: 4 }}>
|
|
147
|
+
• <Text weight="semibold">packages/web/</Text> - React web
|
|
148
|
+
application
|
|
149
|
+
</Text>
|
|
150
|
+
<Text size="sm" style={{ marginBottom: 4 }}>
|
|
151
|
+
• <Text weight="semibold">packages/mobile/</Text> - React Native
|
|
152
|
+
mobile app
|
|
153
|
+
</Text>
|
|
154
|
+
<Text size="sm" style={{ marginBottom: 4 }}>
|
|
155
|
+
• <Text weight="semibold">packages/shared/</Text> - Cross-platform
|
|
156
|
+
components
|
|
157
|
+
</Text>
|
|
158
|
+
<Text size="sm" style={{ marginBottom: 4 }}>
|
|
159
|
+
• <Text weight="semibold">packages/api/</Text> - tRPC API server
|
|
160
|
+
</Text>
|
|
161
|
+
</View>
|
|
162
|
+
|
|
163
|
+
<View style={{ marginBottom: 16 }}>
|
|
164
|
+
<Text size="md" weight="semibold" style={{ marginBottom: 8 }}>
|
|
165
|
+
Try Editing:
|
|
166
|
+
</Text>
|
|
167
|
+
<Text size="sm" style={{ marginBottom: 4 }}>
|
|
168
|
+
1. Edit this component in{" "}
|
|
169
|
+
<Text weight="semibold">
|
|
170
|
+
packages/shared/src/components/HelloWorld.tsx
|
|
171
|
+
</Text>
|
|
172
|
+
</Text>
|
|
173
|
+
<Text size="sm" style={{ marginBottom: 4 }}>
|
|
174
|
+
2. Watch changes appear in both web and mobile apps instantly!
|
|
175
|
+
</Text>
|
|
176
|
+
<Text size="sm" style={{ marginBottom: 4 }}>
|
|
177
|
+
3. Run <Text weight="semibold">yarn dev</Text> to start all
|
|
178
|
+
development servers
|
|
179
|
+
</Text>
|
|
180
|
+
</View>
|
|
181
|
+
|
|
182
|
+
<Card type="filled" intent="success" padding="md">
|
|
183
|
+
<Text size="sm" weight="semibold" style={{ marginBottom: 4 }}>
|
|
184
|
+
✨ Framework Features:
|
|
185
|
+
</Text>
|
|
186
|
+
<Text size="sm">
|
|
187
|
+
Shared components • Type safety • Hot reload • Cross-platform
|
|
188
|
+
compatibility
|
|
189
|
+
</Text>
|
|
190
|
+
</Card>
|
|
191
|
+
</Card>
|
|
192
|
+
|
|
193
|
+
{/* API Testing Section */}
|
|
194
|
+
<Card type="outlined" padding="lg" style={{ marginTop: 16 }}>
|
|
195
|
+
<Text size="lg" weight="bold" style={{ marginBottom: 16 }}>
|
|
196
|
+
🚀 API Demo - Database Integration
|
|
197
|
+
</Text>
|
|
198
|
+
<Text size="md" style={{ marginBottom: 16, color: "#64748b" }}>
|
|
199
|
+
Test your full-stack integration! This section demonstrates
|
|
200
|
+
real-time database operations.
|
|
201
|
+
</Text>
|
|
202
|
+
|
|
203
|
+
{/* Create New Test Form */}
|
|
204
|
+
<Card
|
|
205
|
+
type="filled"
|
|
206
|
+
padding="md"
|
|
207
|
+
style={{ marginBottom: 16, backgroundColor: "#f8fafc" }}
|
|
208
|
+
>
|
|
209
|
+
<Text size="md" weight="semibold" style={{ marginBottom: 12 }}>
|
|
210
|
+
Create New Test Entry
|
|
211
|
+
</Text>
|
|
212
|
+
|
|
213
|
+
<View style={{ gap: 12 }}>
|
|
214
|
+
<Input
|
|
215
|
+
placeholder="Test name"
|
|
216
|
+
value={newTestName}
|
|
217
|
+
onChangeText={setNewTestName}
|
|
218
|
+
/>
|
|
219
|
+
<Input
|
|
220
|
+
placeholder="Test message"
|
|
221
|
+
value={newTestMessage}
|
|
222
|
+
onChangeText={setNewTestMessage}
|
|
223
|
+
/>
|
|
224
|
+
<Button
|
|
225
|
+
onPress={handleCreateTest}
|
|
226
|
+
disabled={
|
|
227
|
+
!newTestName ||
|
|
228
|
+
!newTestMessage ||
|
|
229
|
+
createTestMutation.isPending
|
|
230
|
+
}
|
|
231
|
+
style={{ alignSelf: "flex-start" }}
|
|
232
|
+
>
|
|
233
|
+
{createTestMutation.isPending ? "Creating..." : "Create Test"}
|
|
234
|
+
</Button>
|
|
235
|
+
</View>
|
|
236
|
+
</Card>
|
|
237
|
+
|
|
238
|
+
{/* Tests List */}
|
|
239
|
+
<View>
|
|
240
|
+
<Text size="md" weight="semibold" style={{ marginBottom: 12 }}>
|
|
241
|
+
Database Records ({tests.data?.length || 0})
|
|
242
|
+
</Text>
|
|
243
|
+
|
|
244
|
+
{tests.isPending ? (
|
|
245
|
+
<Card type="outlined" padding="md">
|
|
246
|
+
<Text size="sm" style={{ color: "#64748b" }}>
|
|
247
|
+
Loading tests...
|
|
248
|
+
</Text>
|
|
249
|
+
</Card>
|
|
250
|
+
) : tests.data?.length === 0 ? (
|
|
251
|
+
<Card type="outlined" padding="md">
|
|
252
|
+
<Text size="sm" style={{ color: "#64748b" }}>
|
|
253
|
+
No tests found. Create one above!
|
|
254
|
+
</Text>
|
|
255
|
+
</Card>
|
|
256
|
+
) : (
|
|
257
|
+
<View style={{ gap: 8 }}>
|
|
258
|
+
{tests.data?.map((test: any) => (
|
|
259
|
+
<Card key={test.id} type="outlined" padding="md">
|
|
260
|
+
<View
|
|
261
|
+
style={{
|
|
262
|
+
flexDirection: "row",
|
|
263
|
+
justifyContent: "space-between",
|
|
264
|
+
alignItems: "center",
|
|
265
|
+
}}
|
|
266
|
+
>
|
|
267
|
+
<View style={{ flex: 1 }}>
|
|
268
|
+
<Text
|
|
269
|
+
size="sm"
|
|
270
|
+
weight="semibold"
|
|
271
|
+
style={{ marginBottom: 4 }}
|
|
272
|
+
>
|
|
273
|
+
{test.name}
|
|
274
|
+
</Text>
|
|
275
|
+
<Text
|
|
276
|
+
size="sm"
|
|
277
|
+
style={{ color: "#64748b", marginBottom: 4 }}
|
|
278
|
+
>
|
|
279
|
+
{test.message}
|
|
280
|
+
</Text>
|
|
281
|
+
<Text size="sm" style={{ color: "#10b981" }}>
|
|
282
|
+
Status: {test.status} •{" "}
|
|
283
|
+
{new Date(test.createdAt).toLocaleDateString()}
|
|
284
|
+
</Text>
|
|
285
|
+
</View>
|
|
286
|
+
<Button
|
|
287
|
+
intent="error"
|
|
288
|
+
size="sm"
|
|
289
|
+
onPress={() => handleDeleteTest(test.id)}
|
|
290
|
+
disabled={deleteTestMutation.isPending}
|
|
291
|
+
>
|
|
292
|
+
Delete
|
|
293
|
+
</Button>
|
|
294
|
+
</View>
|
|
295
|
+
</Card>
|
|
296
|
+
))}
|
|
297
|
+
</View>
|
|
298
|
+
)}
|
|
299
|
+
</View>
|
|
300
|
+
</Card>
|
|
301
|
+
</View>
|
|
302
|
+
</Screen>
|
|
303
|
+
);
|
|
304
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { App } from './App';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Export the unified App component
|
|
2
|
+
export { App } from './components';
|
|
3
|
+
|
|
4
|
+
// Export navigation router
|
|
5
|
+
export { default as AppRouter } from './navigation/AppRouter';
|
|
6
|
+
|
|
7
|
+
// Export tRPC client utilities
|
|
8
|
+
export { trpc, createTRPCClient, createVanillaTRPCClient } from './trpc/client';
|
|
9
|
+
export type { TRPCClientConfig, AppRouter } from './trpc/client';
|
|
10
|
+
|
|
11
|
+
// Simple type for the HelloWorld component props
|
|
12
|
+
export interface HelloWorldProps {
|
|
13
|
+
name?: string;
|
|
14
|
+
}
|