Skip to content

Commit e2283a1

Browse files
committed
feat(examples): add AI-powered search example
- Introduces a comprehensive React example demonstrating natural language search capabilities - Users can query merchant data (orders, disputes, settlements) using conversational language like "show me orders from last week" - AI converts natural language prompts into structured search parameters with proper filtering and date ranges - Includes full UI with data tables, filters, and responsive design using Tailwind CSS - Leverages TanStack Start, TanStack Router, TanStack AI
1 parent a641bad commit e2283a1

Some content is hidden

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

66 files changed

+10003
-4487
lines changed

examples/ts-react-search/.cta.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"projectName": "ts-react-search",
3+
"mode": "file-router",
4+
"typescript": true,
5+
"tailwind": true,
6+
"packageManager": "pnpm",
7+
"addOnOptions": {},
8+
"git": true,
9+
"version": 1,
10+
"framework": "react-cra",
11+
"chosenAddOns": ["nitro", "start"]
12+
}
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+
.output
12+
.vinxi
13+
todos.json
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"files.watcherExclude": {
3+
"**/routeTree.gen.ts": true
4+
},
5+
"search.exclude": {
6+
"**/routeTree.gen.ts": true
7+
},
8+
"files.readonlyInclude": {
9+
"**/routeTree.gen.ts": true
10+
}
11+
}

examples/ts-react-search/README.md

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
Welcome to your new TanStack app!
2+
3+
# Getting Started
4+
5+
To run this application:
6+
7+
```bash
8+
pnpm install
9+
pnpm start
10+
```
11+
12+
# Building For Production
13+
14+
To build this application for production:
15+
16+
```bash
17+
pnpm 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+
pnpm test
26+
```
27+
28+
## Styling
29+
30+
This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
31+
32+
## Routing
33+
34+
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`.
35+
36+
### Adding A Route
37+
38+
To add a new route to your application just add another a new file in the `./src/routes` directory.
39+
40+
TanStack will automatically generate the content of the route file for you.
41+
42+
Now that you have two routes you can use a `Link` component to navigate between them.
43+
44+
### Adding Links
45+
46+
To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`.
47+
48+
```tsx
49+
import { Link } from '@tanstack/react-router'
50+
```
51+
52+
Then anywhere in your JSX you can use it like so:
53+
54+
```tsx
55+
<Link to="/about">About</Link>
56+
```
57+
58+
This will create a link that will navigate to the `/about` route.
59+
60+
More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).
61+
62+
### Using A Layout
63+
64+
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.
65+
66+
Here is an example layout that includes a header:
67+
68+
```tsx
69+
import { Outlet, createRootRoute } from '@tanstack/react-router'
70+
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
71+
72+
import { Link } from '@tanstack/react-router'
73+
74+
export const Route = createRootRoute({
75+
component: () => (
76+
<>
77+
<header>
78+
<nav>
79+
<Link to="/">Home</Link>
80+
<Link to="/about">About</Link>
81+
</nav>
82+
</header>
83+
<Outlet />
84+
<TanStackRouterDevtools />
85+
</>
86+
),
87+
})
88+
```
89+
90+
The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.
91+
92+
More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).
93+
94+
## Data Fetching
95+
96+
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.
97+
98+
For example:
99+
100+
```tsx
101+
const peopleRoute = createRoute({
102+
getParentRoute: () => rootRoute,
103+
path: '/people',
104+
loader: async () => {
105+
const response = await fetch('https://swapi.dev/api/people')
106+
return response.json() as Promise<{
107+
results: {
108+
name: string
109+
}[]
110+
}>
111+
},
112+
component: () => {
113+
const data = peopleRoute.useLoaderData()
114+
return (
115+
<ul>
116+
{data.results.map((person) => (
117+
<li key={person.name}>{person.name}</li>
118+
))}
119+
</ul>
120+
)
121+
},
122+
})
123+
```
124+
125+
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).
126+
127+
### React-Query
128+
129+
React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze.
130+
131+
First add your dependencies:
132+
133+
```bash
134+
pnpm add @tanstack/react-query @tanstack/react-query-devtools
135+
```
136+
137+
Next we'll need to create a query client and provider. We recommend putting those in `main.tsx`.
138+
139+
```tsx
140+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
141+
142+
// ...
143+
144+
const queryClient = new QueryClient()
145+
146+
// ...
147+
148+
if (!rootElement.innerHTML) {
149+
const root = ReactDOM.createRoot(rootElement)
150+
151+
root.render(
152+
<QueryClientProvider client={queryClient}>
153+
<RouterProvider router={router} />
154+
</QueryClientProvider>,
155+
)
156+
}
157+
```
158+
159+
You can also add TanStack Query Devtools to the root route (optional).
160+
161+
```tsx
162+
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
163+
164+
const rootRoute = createRootRoute({
165+
component: () => (
166+
<>
167+
<Outlet />
168+
<ReactQueryDevtools buttonPosition="top-right" />
169+
<TanStackRouterDevtools />
170+
</>
171+
),
172+
})
173+
```
174+
175+
Now you can use `useQuery` to fetch your data.
176+
177+
```tsx
178+
import { useQuery } from '@tanstack/react-query'
179+
180+
import './App.css'
181+
182+
function App() {
183+
const { data } = useQuery({
184+
queryKey: ['people'],
185+
queryFn: () =>
186+
fetch('https://swapi.dev/api/people')
187+
.then((res) => res.json())
188+
.then((data) => data.results as { name: string }[]),
189+
initialData: [],
190+
})
191+
192+
return (
193+
<div>
194+
<ul>
195+
{data.map((person) => (
196+
<li key={person.name}>{person.name}</li>
197+
))}
198+
</ul>
199+
</div>
200+
)
201+
}
202+
203+
export default App
204+
```
205+
206+
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).
207+
208+
## State Management
209+
210+
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.
211+
212+
First you need to add TanStack Store as a dependency:
213+
214+
```bash
215+
pnpm add @tanstack/store
216+
```
217+
218+
Now let's create a simple counter in the `src/App.tsx` file as a demonstration.
219+
220+
```tsx
221+
import { useStore } from '@tanstack/react-store'
222+
import { Store } from '@tanstack/store'
223+
import './App.css'
224+
225+
const countStore = new Store(0)
226+
227+
function App() {
228+
const count = useStore(countStore)
229+
return (
230+
<div>
231+
<button onClick={() => countStore.setState((n) => n + 1)}>
232+
Increment - {count}
233+
</button>
234+
</div>
235+
)
236+
}
237+
238+
export default App
239+
```
240+
241+
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.
242+
243+
Let's check this out by doubling the count using derived state.
244+
245+
```tsx
246+
import { useStore } from '@tanstack/react-store'
247+
import { Store, Derived } from '@tanstack/store'
248+
import './App.css'
249+
250+
const countStore = new Store(0)
251+
252+
const doubledStore = new Derived({
253+
fn: () => countStore.state * 2,
254+
deps: [countStore],
255+
})
256+
doubledStore.mount()
257+
258+
function App() {
259+
const count = useStore(countStore)
260+
const doubledCount = useStore(doubledStore)
261+
262+
return (
263+
<div>
264+
<button onClick={() => countStore.setState((n) => n + 1)}>
265+
Increment - {count}
266+
</button>
267+
<div>Doubled - {doubledCount}</div>
268+
</div>
269+
)
270+
}
271+
272+
export default App
273+
```
274+
275+
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.
276+
277+
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.
278+
279+
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).
280+
281+
# Demo files
282+
283+
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.
284+
285+
# Learn More
286+
287+
You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "ts-react-search",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"dev": "vite dev --port 3000",
7+
"build": "vite build",
8+
"serve": "vite preview",
9+
"test": "exit 0"
10+
},
11+
"dependencies": {
12+
"@radix-ui/react-slot": "^1.2.4",
13+
"@tailwindcss/vite": "^4.1.17",
14+
"@tanstack/ai": "workspace:*",
15+
"@tanstack/ai-openai": "workspace:*",
16+
"@tanstack/ai-react": "workspace:*",
17+
"@tanstack/react-devtools": "^0.8.2",
18+
"@tanstack/react-router": "^1.139.7",
19+
"@tanstack/react-router-devtools": "^1.139.7",
20+
"@tanstack/react-router-ssr-query": "^1.139.7",
21+
"@tanstack/react-start": "^1.139.8",
22+
"@tanstack/router-plugin": "^1.139.7",
23+
"class-variance-authority": "^0.7.1",
24+
"clsx": "^2.1.1",
25+
"lucide-react": "^0.555.0",
26+
"nitro": "latest",
27+
"radix-ui": "^1.4.3",
28+
"react": "^19.2.0",
29+
"react-day-picker": "^9.12.0",
30+
"react-dom": "^19.2.0",
31+
"tailwind-merge": "^3.4.0",
32+
"tailwindcss": "^4.1.17",
33+
"tw-animate-css": "^1.4.0",
34+
"vite-tsconfig-paths": "^5.1.4",
35+
"zod": "^4.1.13"
36+
},
37+
"devDependencies": {
38+
"@tanstack/devtools-vite": "^0.3.11",
39+
"@testing-library/dom": "^10.4.1",
40+
"@testing-library/react": "^16.3.0",
41+
"@types/node": "^24.10.1",
42+
"@types/react": "^19.2.7",
43+
"@types/react-dom": "^19.2.3",
44+
"@vitejs/plugin-react": "^5.1.1",
45+
"jsdom": "^27.2.0",
46+
"typescript": "5.9.3",
47+
"vite": "^7.2.4",
48+
"vitest": "^4.0.14",
49+
"web-vitals": "^5.1.0"
50+
}
51+
}

examples/ts-react-search/public/favicon.ico

Whitespace-only changes.

examples/ts-react-search/public/logo192.png

Loading

examples/ts-react-search/public/logo512.png

Loading

0 commit comments

Comments
 (0)