Prettier / main page

This commit is contained in:
Leons Aleksandrovs
2025-07-02 14:51:00 +03:00
parent 20d173b276
commit 9803b5b35d
19 changed files with 341 additions and 346 deletions

View File

@@ -1,13 +1,11 @@
{
"projectName": ".",
"mode": "file-router",
"typescript": true,
"tailwind": true,
"packageManager": "bun",
"git": true,
"version": 1,
"framework": "react-cra",
"chosenAddOns": [
"tanstack-query"
]
}
"projectName": ".",
"mode": "file-router",
"typescript": true,
"tailwind": true,
"packageManager": "bun",
"git": true,
"version": 1,
"framework": "react-cra",
"chosenAddOns": ["tanstack-query"]
}

9
frontend/.prettierrc.mjs Normal file
View File

@@ -0,0 +1,9 @@
const config = {
trailingComma: "es5",
printWidth: 120,
tabWidth: 4,
semi: true,
singleQuote: false,
};
export default config;

View File

@@ -1,4 +1,4 @@
Welcome to your new TanStack app!
Welcome to your new TanStack app!
# Getting Started
@@ -6,7 +6,7 @@ To run this application:
```bash
bun install
bunx --bun run start
bunx --bun run start
```
# Building For Production
@@ -29,10 +29,8 @@ bunx --bun run test
This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
## Routing
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`.
### Adding A Route
@@ -68,32 +66,31 @@ In the File Based Routing setup the layout is located in `src/routes/__root.tsx`
Here is an example layout that includes a header:
```tsx
import { Outlet, createRootRoute } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
import { Outlet, createRootRoute } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import { Link } from "@tanstack/react-router";
export const Route = createRootRoute({
component: () => (
<>
<header>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
</header>
<Outlet />
<TanStackRouterDevtools />
</>
),
})
component: () => (
<>
<header>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
</header>
<Outlet />
<TanStackRouterDevtools />
</>
),
});
```
The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.
More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).
## Data Fetching
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.
@@ -102,26 +99,26 @@ For example:
```tsx
const peopleRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/people",
loader: async () => {
const response = await fetch("https://swapi.dev/api/people");
return response.json() as Promise<{
results: {
name: string;
}[];
}>;
},
component: () => {
const data = peopleRoute.useLoaderData();
return (
<ul>
{data.results.map((person) => (
<li key={person.name}>{person.name}</li>
))}
</ul>
);
},
getParentRoute: () => rootRoute,
path: "/people",
loader: async () => {
const response = await fetch("https://swapi.dev/api/people");
return response.json() as Promise<{
results: {
name: string;
}[];
}>;
},
component: () => {
const data = peopleRoute.useLoaderData();
return (
<ul>
{data.results.map((person) => (
<li key={person.name}>{person.name}</li>
))}
</ul>
);
},
});
```
@@ -149,13 +146,13 @@ const queryClient = new QueryClient();
// ...
if (!rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement);
const root = ReactDOM.createRoot(rootElement);
root.render(
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
);
root.render(
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
);
}
```
@@ -165,13 +162,13 @@ You can also add TanStack Query Devtools to the root route (optional).
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
const rootRoute = createRootRoute({
component: () => (
<>
<Outlet />
<ReactQueryDevtools buttonPosition="top-right" />
<TanStackRouterDevtools />
</>
),
component: () => (
<>
<Outlet />
<ReactQueryDevtools buttonPosition="top-right" />
<TanStackRouterDevtools />
</>
),
});
```
@@ -183,24 +180,24 @@ import { useQuery } from "@tanstack/react-query";
import "./App.css";
function App() {
const { data } = useQuery({
queryKey: ["people"],
queryFn: () =>
fetch("https://swapi.dev/api/people")
.then((res) => res.json())
.then((data) => data.results as { name: string }[]),
initialData: [],
});
const { data } = useQuery({
queryKey: ["people"],
queryFn: () =>
fetch("https://swapi.dev/api/people")
.then((res) => res.json())
.then((data) => data.results as { name: string }[]),
initialData: [],
});
return (
<div>
<ul>
{data.map((person) => (
<li key={person.name}>{person.name}</li>
))}
</ul>
</div>
);
return (
<div>
<ul>
{data.map((person) => (
<li key={person.name}>{person.name}</li>
))}
</ul>
</div>
);
}
export default App;
@@ -228,14 +225,12 @@ import "./App.css";
const countStore = new Store(0);
function App() {
const count = useStore(countStore);
return (
<div>
<button onClick={() => countStore.setState((n) => n + 1)}>
Increment - {count}
</button>
</div>
);
const count = useStore(countStore);
return (
<div>
<button onClick={() => countStore.setState((n) => n + 1)}>Increment - {count}</button>
</div>
);
}
export default App;
@@ -253,23 +248,21 @@ import "./App.css";
const countStore = new Store(0);
const doubledStore = new Derived({
fn: () => countStore.state * 2,
deps: [countStore],
fn: () => countStore.state * 2,
deps: [countStore],
});
doubledStore.mount();
function App() {
const count = useStore(countStore);
const doubledCount = useStore(doubledStore);
const count = useStore(countStore);
const doubledCount = useStore(doubledStore);
return (
<div>
<button onClick={() => countStore.setState((n) => n + 1)}>
Increment - {count}
</button>
<div>Doubled - {doubledCount}</div>
</div>
);
return (
<div>
<button onClick={() => countStore.setState((n) => n + 1)}>Increment - {count}</button>
<div>Doubled - {doubledCount}</div>
</div>
);
}
export default App;

View File

@@ -21,6 +21,7 @@
"@types/react-dom": "^19.0.3",
"@vitejs/plugin-react": "^4.3.4",
"jsdom": "^26.0.0",
"prettier": "^3.6.2",
"typescript": "^5.7.2",
"vite": "^6.1.0",
"vitest": "^3.0.5",

View File

@@ -1,20 +1,17 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-tsrouter-app"
/>
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
<title>Create TanStack App - .</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-tsrouter-app" />
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
<title>Bolderjara Serviss</title>
</head>
<body class="bg-gray-900">
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@@ -1,35 +1,36 @@
{
"name": ".",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port 3000",
"start": "vite --port 3000",
"build": "vite build && tsc",
"serve": "vite preview",
"test": "vitest run"
},
"dependencies": {
"@tailwindcss/vite": "^4.0.6",
"@tanstack/react-query": "^5.66.5",
"@tanstack/react-query-devtools": "^5.66.5",
"@tanstack/react-router": "^1.121.2",
"@tanstack/react-router-devtools": "^1.121.2",
"@tanstack/router-plugin": "^1.121.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwindcss": "^4.0.6"
},
"devDependencies": {
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.2.0",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@vitejs/plugin-react": "^4.3.4",
"jsdom": "^26.0.0",
"typescript": "^5.7.2",
"vite": "^6.1.0",
"vitest": "^3.0.5",
"web-vitals": "^4.2.4"
}
}
"name": ".",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port 3000",
"start": "vite --port 3000",
"build": "vite build && tsc",
"serve": "vite preview",
"test": "vitest run"
},
"dependencies": {
"@tailwindcss/vite": "^4.0.6",
"@tanstack/react-query": "^5.66.5",
"@tanstack/react-query-devtools": "^5.66.5",
"@tanstack/react-router": "^1.121.2",
"@tanstack/react-router-devtools": "^1.121.2",
"@tanstack/router-plugin": "^1.121.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwindcss": "^4.0.6"
},
"devDependencies": {
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.2.0",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@vitejs/plugin-react": "^4.3.4",
"jsdom": "^26.0.0",
"prettier": "^3.6.2",
"typescript": "^5.7.2",
"vite": "^6.1.0",
"vitest": "^3.0.5",
"web-vitals": "^4.2.4"
}
}

View File

@@ -1,17 +1,11 @@
import { Link } from '@tanstack/react-router'
import { Link } from "@tanstack/react-router";
export default function Header() {
return (
<header className="p-2 flex gap-2 bg-white text-black justify-between">
<nav className="flex flex-row">
<div className="px-2 font-bold">
<Link to="/">Home</Link>
</div>
<div className="px-2 font-bold">
<Link to="/demo/tanstack-query">TanStack Query</Link>
</div>
</nav>
</header>
)
return (
<header className="flex gap-4 p-4 bg-gray-800 font-bold text-gray-100">
<nav className="">
<Link to="/">Home</Link>
</nav>
</header>
);
}

View File

@@ -0,0 +1,3 @@
export default function MainContainer(props: { children: React.ReactNode; className?: string }) {
return <main className={`max-w-4xl mx-auto ${props.className || ""}`}>{props.children}</main>;
}

View File

@@ -1,5 +1,5 @@
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
export default function LayoutAddition() {
return <ReactQueryDevtools buttonPosition="bottom-right" />
return <ReactQueryDevtools buttonPosition="bottom-right" />;
}

View File

@@ -1,15 +1,13 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient()
const queryClient = new QueryClient();
export function getContext() {
return {
queryClient,
}
return {
queryClient,
};
}
export function Provider({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}

View File

@@ -1,48 +1,46 @@
import { StrictMode } from 'react'
import ReactDOM from 'react-dom/client'
import { RouterProvider, createRouter } from '@tanstack/react-router'
import { StrictMode } from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider, createRouter } from "@tanstack/react-router";
import * as TanStackQueryProvider from './integrations/tanstack-query/root-provider.tsx'
import * as TanStackQueryProvider from "./integrations/tanstack-query/root-provider.tsx";
// Import the generated route tree
import { routeTree } from './routeTree.gen'
import { routeTree } from "./routeTree.gen";
import './styles.css'
import reportWebVitals from './reportWebVitals.ts'
import "./styles.css";
import reportWebVitals from "./reportWebVitals.ts";
// Create a new router instance
const router = createRouter({
routeTree,
context: {
...TanStackQueryProvider.getContext(),
},
defaultPreload: 'intent',
scrollRestoration: true,
defaultStructuralSharing: true,
defaultPreloadStaleTime: 0,
})
routeTree,
context: {
...TanStackQueryProvider.getContext(),
},
defaultPreload: "intent",
scrollRestoration: true,
defaultStructuralSharing: true,
defaultPreloadStaleTime: 0,
});
// Register the router instance for type safety
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}
// Render the app
const rootElement = document.getElementById('app')
const rootElement = document.getElementById("app");
if (rootElement && !rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement)
root.render(
<StrictMode>
<TanStackQueryProvider.Provider>
<RouterProvider router={router} />
</TanStackQueryProvider.Provider>
</StrictMode>,
)
const root = ReactDOM.createRoot(rootElement);
root.render(
<TanStackQueryProvider.Provider>
<RouterProvider router={router} />
</TanStackQueryProvider.Provider>
);
}
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()
reportWebVitals();

View File

@@ -1,13 +1,13 @@
const reportWebVitals = (onPerfEntry?: () => void) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ onCLS, onINP, onFCP, onLCP, onTTFB }) => {
onCLS(onPerfEntry)
onINP(onPerfEntry)
onFCP(onPerfEntry)
onLCP(onPerfEntry)
onTTFB(onPerfEntry)
})
}
}
if (onPerfEntry && onPerfEntry instanceof Function) {
import("web-vitals").then(({ onCLS, onINP, onFCP, onLCP, onTTFB }) => {
onCLS(onPerfEntry);
onINP(onPerfEntry);
onFCP(onPerfEntry);
onLCP(onPerfEntry);
onTTFB(onPerfEntry);
});
}
};
export default reportWebVitals
export default reportWebVitals;

View File

@@ -0,0 +1,59 @@
/* eslint-disable */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// This file was automatically generated by TanStack Router.
// You should NOT make any changes in this file as it will be overwritten.
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
import { Route as IndexRouteImport } from './routes/index'
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRouteImport,
} as any)
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/'
fileRoutesByTo: FileRoutesByTo
to: '/'
id: '__root__' | '/'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexRouteImport
parentRoute: typeof rootRouteImport
}
}
}
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()

View File

@@ -1,25 +1,25 @@
import { Outlet, createRootRouteWithContext } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
import { Outlet, createRootRouteWithContext } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import Header from '../components/Header'
import Header from "../components/Header";
import TanStackQueryLayout from '../integrations/tanstack-query/layout.tsx'
import TanStackQueryLayout from "../integrations/tanstack-query/layout.tsx";
import type { QueryClient } from '@tanstack/react-query'
import type { QueryClient } from "@tanstack/react-query";
interface MyRouterContext {
queryClient: QueryClient
queryClient: QueryClient;
}
export const Route = createRootRouteWithContext<MyRouterContext>()({
component: () => (
<>
<Header />
component: () => (
<>
<Header />
<Outlet />
<TanStackRouterDevtools />
<Outlet />
<TanStackRouterDevtools />
<TanStackQueryLayout />
</>
),
})
<TanStackQueryLayout />
</>
),
});

View File

@@ -1,26 +0,0 @@
import { createFileRoute } from '@tanstack/react-router'
import { useQuery } from '@tanstack/react-query'
export const Route = createFileRoute('/demo/tanstack-query')({
component: TanStackQueryDemo,
})
function TanStackQueryDemo() {
const { data } = useQuery({
queryKey: ['people'],
queryFn: () =>
Promise.resolve([{ name: 'John Doe' }, { name: 'Jane Doe' }]),
initialData: [],
})
return (
<div className="p-4">
<h1 className="text-2xl mb-4">People list</h1>
<ul>
{data.map((person) => (
<li key={person.name}>{person.name}</li>
))}
</ul>
</div>
)
}

View File

@@ -1,39 +1,14 @@
import { createFileRoute } from '@tanstack/react-router'
import logo from '../logo.svg'
import MainContainer from "@/components/MainContainer";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute('/')({
component: App,
})
export const Route = createFileRoute("/")({
component: App,
});
function App() {
return (
<div className="text-center">
<header className="min-h-screen flex flex-col items-center justify-center bg-[#282c34] text-white text-[calc(10px+2vmin)]">
<img
src={logo}
className="h-[40vmin] pointer-events-none animate-[spin_20s_linear_infinite]"
alt="logo"
/>
<p>
Edit <code>src/routes/index.tsx</code> and save to reload.
</p>
<a
className="text-[#61dafb] hover:underline"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<a
className="text-[#61dafb] hover:underline"
href="https://tanstack.com"
target="_blank"
rel="noopener noreferrer"
>
Learn TanStack
</a>
</header>
</div>
)
return (
<MainContainer className="pt-8">
<h1 className="text-4xl font-bold text-center text-gray-100">Darbinieki</h1>
</MainContainer>
);
}

View File

@@ -1,15 +1,14 @@
@import "tailwindcss";
body {
@apply m-0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@apply m-0;
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
"Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}

View File

@@ -1,28 +1,28 @@
{
"include": ["**/*.ts", "**/*.tsx"],
"compilerOptions": {
"target": "ES2022",
"jsx": "react-jsx",
"module": "ESNext",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["vite/client"],
"include": ["**/*.ts", "**/*.tsx"],
"compilerOptions": {
"target": "ES2022",
"jsx": "react-jsx",
"module": "ESNext",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["vite/client"],
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
/* Linting */
"skipLibCheck": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
/* Linting */
"skipLibCheck": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
}

View File

@@ -1,24 +1,20 @@
import { defineConfig } from 'vite'
import viteReact from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from "vite";
import viteReact from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
import { resolve } from 'node:path'
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
import { resolve } from "node:path";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
TanStackRouterVite({ autoCodeSplitting: true }),
viteReact(),
tailwindcss(),
],
test: {
globals: true,
environment: 'jsdom',
},
resolve: {
alias: {
'@': resolve(__dirname, './src'),
plugins: [TanStackRouterVite({ autoCodeSplitting: true }), viteReact(), tailwindcss()],
test: {
globals: true,
environment: "jsdom",
},
},
})
resolve: {
alias: {
"@": resolve(__dirname, "./src"),
},
},
});