Skip to content

Commit ee44ff4

Browse files
feat: Web UI init
1 parent d66e84f commit ee44ff4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+4364
-0
lines changed

web/.cta.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"projectName": "web",
3+
"mode": "file-router",
4+
"typescript": true,
5+
"tailwind": true,
6+
"packageManager": "bun",
7+
"addOnOptions": {},
8+
"git": true,
9+
"version": 1,
10+
"framework": "react-cra",
11+
"chosenAddOns": [
12+
"biome",
13+
"form",
14+
"mcp",
15+
"shadcn",
16+
"table",
17+
"tanstack-query",
18+
"start"
19+
]
20+
}

web/.cursorrules

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# shadcn instructions
2+
3+
Use the latest version of Shadcn to install new components, like this command to add a button component:
4+
5+
```bash
6+
pnpm dlx shadcn@latest add button
7+
```

web/.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local
6+
count.txt
7+
.env
8+
.nitro
9+
.tanstack
10+
.wrangler
11+
mcp-todos.json.output
12+
.vinxi
13+
todos.json

web/README.md

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
Welcome to your new TanStack app!
2+
3+
# Getting Started
4+
5+
To run this application:
6+
7+
```bash
8+
bun install
9+
bun --bun run start
10+
```
11+
12+
# Building For Production
13+
14+
To build this application for production:
15+
16+
```bash
17+
bun --bun run build
18+
```
19+
20+
## Testing
21+
22+
This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with:
23+
24+
```bash
25+
bun --bun run test
26+
```
27+
28+
## Styling
29+
30+
This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
31+
32+
33+
## Linting & Formatting
34+
35+
This project uses [Biome](https://biomejs.dev/) for linting and formatting. The following scripts are available:
36+
37+
38+
```bash
39+
bun --bun run lint
40+
bun --bun run format
41+
bun --bun run check
42+
```
43+
44+
45+
## Shadcn
46+
47+
Add components using the latest version of [Shadcn](https://ui.shadcn.com/).
48+
49+
```bash
50+
pnpm dlx shadcn@latest add button
51+
```
52+
53+
54+
55+
## Routing
56+
This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file based router. Which means that the routes are managed as files in `src/routes`.
57+
58+
### Adding A Route
59+
60+
To add a new route to your application just add another a new file in the `./src/routes` directory.
61+
62+
TanStack will automatically generate the content of the route file for you.
63+
64+
Now that you have two routes you can use a `Link` component to navigate between them.
65+
66+
### Adding Links
67+
68+
To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`.
69+
70+
```tsx
71+
import { Link } from "@tanstack/react-router";
72+
```
73+
74+
Then anywhere in your JSX you can use it like so:
75+
76+
```tsx
77+
<Link to="/about">About</Link>
78+
```
79+
80+
This will create a link that will navigate to the `/about` route.
81+
82+
More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).
83+
84+
### Using A Layout
85+
86+
In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you use the `<Outlet />` component.
87+
88+
Here is an example layout that includes a header:
89+
90+
```tsx
91+
import { Outlet, createRootRoute } from '@tanstack/react-router'
92+
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
93+
94+
import { Link } from "@tanstack/react-router";
95+
96+
export const Route = createRootRoute({
97+
component: () => (
98+
<>
99+
<header>
100+
<nav>
101+
<Link to="/">Home</Link>
102+
<Link to="/about">About</Link>
103+
</nav>
104+
</header>
105+
<Outlet />
106+
<TanStackRouterDevtools />
107+
</>
108+
),
109+
})
110+
```
111+
112+
The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.
113+
114+
More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).
115+
116+
117+
## Data Fetching
118+
119+
There are multiple ways to fetch data in your application. You can use TanStack Query to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered.
120+
121+
For example:
122+
123+
```tsx
124+
const peopleRoute = createRoute({
125+
getParentRoute: () => rootRoute,
126+
path: "/people",
127+
loader: async () => {
128+
const response = await fetch("https://swapi.dev/api/people");
129+
return response.json() as Promise<{
130+
results: {
131+
name: string;
132+
}[];
133+
}>;
134+
},
135+
component: () => {
136+
const data = peopleRoute.useLoaderData();
137+
return (
138+
<ul>
139+
{data.results.map((person) => (
140+
<li key={person.name}>{person.name}</li>
141+
))}
142+
</ul>
143+
);
144+
},
145+
});
146+
```
147+
148+
Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters).
149+
150+
### React-Query
151+
152+
React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze.
153+
154+
First add your dependencies:
155+
156+
```bash
157+
bun install @tanstack/react-query @tanstack/react-query-devtools
158+
```
159+
160+
Next we'll need to create a query client and provider. We recommend putting those in `main.tsx`.
161+
162+
```tsx
163+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
164+
165+
// ...
166+
167+
const queryClient = new QueryClient();
168+
169+
// ...
170+
171+
if (!rootElement.innerHTML) {
172+
const root = ReactDOM.createRoot(rootElement);
173+
174+
root.render(
175+
<QueryClientProvider client={queryClient}>
176+
<RouterProvider router={router} />
177+
</QueryClientProvider>
178+
);
179+
}
180+
```
181+
182+
You can also add TanStack Query Devtools to the root route (optional).
183+
184+
```tsx
185+
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
186+
187+
const rootRoute = createRootRoute({
188+
component: () => (
189+
<>
190+
<Outlet />
191+
<ReactQueryDevtools buttonPosition="top-right" />
192+
<TanStackRouterDevtools />
193+
</>
194+
),
195+
});
196+
```
197+
198+
Now you can use `useQuery` to fetch your data.
199+
200+
```tsx
201+
import { useQuery } from "@tanstack/react-query";
202+
203+
import "./App.css";
204+
205+
function App() {
206+
const { data } = useQuery({
207+
queryKey: ["people"],
208+
queryFn: () =>
209+
fetch("https://swapi.dev/api/people")
210+
.then((res) => res.json())
211+
.then((data) => data.results as { name: string }[]),
212+
initialData: [],
213+
});
214+
215+
return (
216+
<div>
217+
<ul>
218+
{data.map((person) => (
219+
<li key={person.name}>{person.name}</li>
220+
))}
221+
</ul>
222+
</div>
223+
);
224+
}
225+
226+
export default App;
227+
```
228+
229+
You can find out everything you need to know on how to use React-Query in the [React-Query documentation](https://tanstack.com/query/latest/docs/framework/react/overview).
230+
231+
## State Management
232+
233+
Another common requirement for React applications is state management. There are many options for state management in React. TanStack Store provides a great starting point for your project.
234+
235+
First you need to add TanStack Store as a dependency:
236+
237+
```bash
238+
bun install @tanstack/store
239+
```
240+
241+
Now let's create a simple counter in the `src/App.tsx` file as a demonstration.
242+
243+
```tsx
244+
import { useStore } from "@tanstack/react-store";
245+
import { Store } from "@tanstack/store";
246+
import "./App.css";
247+
248+
const countStore = new Store(0);
249+
250+
function App() {
251+
const count = useStore(countStore);
252+
return (
253+
<div>
254+
<button onClick={() => countStore.setState((n) => n + 1)}>
255+
Increment - {count}
256+
</button>
257+
</div>
258+
);
259+
}
260+
261+
export default App;
262+
```
263+
264+
One of the many nice features of TanStack Store is the ability to derive state from other state. That derived state will update when the base state updates.
265+
266+
Let's check this out by doubling the count using derived state.
267+
268+
```tsx
269+
import { useStore } from "@tanstack/react-store";
270+
import { Store, Derived } from "@tanstack/store";
271+
import "./App.css";
272+
273+
const countStore = new Store(0);
274+
275+
const doubledStore = new Derived({
276+
fn: () => countStore.state * 2,
277+
deps: [countStore],
278+
});
279+
doubledStore.mount();
280+
281+
function App() {
282+
const count = useStore(countStore);
283+
const doubledCount = useStore(doubledStore);
284+
285+
return (
286+
<div>
287+
<button onClick={() => countStore.setState((n) => n + 1)}>
288+
Increment - {count}
289+
</button>
290+
<div>Doubled - {doubledCount}</div>
291+
</div>
292+
);
293+
}
294+
295+
export default App;
296+
```
297+
298+
We use the `Derived` class to create a new store that is derived from another store. The `Derived` class has a `mount` method that will start the derived store updating.
299+
300+
Once we've created the derived store we can use it in the `App` component just like we would any other store using the `useStore` hook.
301+
302+
You can find out everything you need to know on how to use TanStack Store in the [TanStack Store documentation](https://tanstack.com/store/latest).
303+
304+
# Demo files
305+
306+
Files prefixed with `demo` can be safely deleted. They are there to provide a starting point for you to play around with the features you've installed.
307+
308+
# Learn More
309+
310+
You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).

web/biome.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
3+
"vcs": {
4+
"enabled": false,
5+
"clientKind": "git",
6+
"useIgnoreFile": false
7+
},
8+
"files": {
9+
"ignoreUnknown": false,
10+
"includes": [
11+
"**/src/**/*",
12+
"**/.vscode/**/*",
13+
"**/index.html",
14+
"**/vite.config.js",
15+
"!**/src/routeTree.gen.ts",
16+
"!**/src/styles.css"
17+
]
18+
},
19+
"formatter": {
20+
"enabled": true,
21+
"indentStyle": "tab"
22+
},
23+
"assist": { "actions": { "source": { "organizeImports": "on" } } },
24+
"linter": {
25+
"enabled": true,
26+
"rules": {
27+
"recommended": true
28+
}
29+
},
30+
"javascript": {
31+
"formatter": {
32+
"quoteStyle": "double"
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)