refactor: Consolidate global styling with Tailwind and HeroUI theme variables and refactor devtools integration.

This commit is contained in:
Jrodenas
2026-03-04 20:23:03 +01:00
parent 841f43285e
commit b4a6555e5e
16 changed files with 3702 additions and 1102 deletions

View File

@@ -1,23 +0,0 @@
{
"projectName": "findyourpilot",
"mode": "file-router",
"typescript": true,
"tailwind": true,
"packageManager": "npm",
"git": true,
"install": true,
"addOnOptions": {},
"includeExamples": true,
"envVarValues": {},
"routerOnly": false,
"version": 1,
"framework": "react-cra",
"chosenAddOns": [
"tanstack-query",
"shadcn",
"railway",
"sentry",
"biome",
"paraglide"
]
}

View File

@@ -20,10 +20,3 @@ Sentry.startSpan({ name: 'Requesting all the pokemon' }, async () => {
await fetch('https://api.pokemon.com/data/')
})
```
# shadcn instructions
Use the latest version of Shadcn to install new components, like this command to add a button component:
```bash
pnpm dlx shadcn@latest add button
```

View File

@@ -36,7 +36,7 @@
"formatter": {
"quoteStyle": "double",
"semicolons": "asNeeded",
"trailingCommas": "es5"
"trailingCommas": "none"
}
}
}

4276
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,45 +13,41 @@
"check": "biome check"
},
"dependencies": {
"@heroui/react": "3.0.0-beta.7",
"@heroui/styles": "3.0.0-beta.7",
"@sentry/tanstackstart-react": "^10.34.0",
"@supabase/ssr": "^0.8.0",
"@heroui/react": "^3.0.0-beta.8",
"@heroui/styles": "^3.0.0-beta.8",
"@sentry/tanstackstart-react": "^10.42.0",
"@supabase/ssr": "^0.9.0",
"@supabase/supabase-js": "^2.98.0",
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-devtools": "^0.7.0",
"@tanstack/react-query": "^5.66.5",
"@tanstack/react-query-devtools": "^5.84.2",
"@tanstack/react-router": "^1.132.0",
"@tanstack/react-router-devtools": "^1.132.0",
"@tanstack/react-router-ssr-query": "^1.131.7",
"@tanstack/react-start": "^1.132.0",
"@tanstack/router-plugin": "^1.132.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dotenv-cli": "^11.0.0",
"lucide-react": "^0.561.0",
"nitro": "npm:nitro-nightly@latest",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"tailwind-merge": "^3.0.2",
"tailwindcss": "^4.1.18",
"tw-animate-css": "^1.3.6"
"@tailwindcss/vite": "^4.2.1",
"@tanstack/react-query": "^5.90.21",
"@tanstack/react-router": "^1.163.3",
"@tanstack/react-router-ssr-query": "^1.163.3",
"@tanstack/react-start": "^1.166.1",
"@tanstack/router-plugin": "^1.164.0",
"lucide-react": "^0.577.0",
"nitro": "^3.0.1-alpha.2",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"tailwindcss": "^4.2.1",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@biomejs/biome": "2.4.4",
"@inlang/paraglide-js": "^2.8.0",
"@tanstack/devtools-vite": "^0.3.11",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.2.0",
"@biomejs/biome": "^2.4.5",
"@inlang/paraglide-js": "^2.13.1",
"@tanstack/devtools-vite": "^0.5.3",
"@tanstack/react-devtools": "^0.9.9",
"@tanstack/react-router-devtools": "^1.163.3",
"@tanstack/react-query-devtools": "^5.91.3",
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2",
"@types/node": "^22.10.2",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@vitejs/plugin-react": "^5.0.4",
"jsdom": "^27.0.0",
"typescript": "^5.7.2",
"vite": "^7.1.7",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.5"
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.4",
"jsdom": "^28.1.0",
"typescript": "^5.9.3",
"vite": "^7.3.1",
"vite-tsconfig-paths": "^6.1.1",
"vitest": "^3.2.4"
}
}

View File

@@ -1,9 +1,8 @@
import { Link } from '@tanstack/react-router'
import { Link } from "@tanstack/react-router"
import { Globe, Home, Languages, Menu, Network, X } from "lucide-react"
import ParaglideLocaleSwitcher from './LocaleSwitcher.tsx'
import { useState } from 'react'
import { Globe, Home, Languages, Menu, Network, X } from 'lucide-react'
import { useState } from "react"
import ParaglideLocaleSwitcher from "./LocaleSwitcher.tsx"
export default function Header() {
const [isOpen, setIsOpen] = useState(false)
@@ -31,7 +30,7 @@ export default function Header() {
<aside
className={`fixed top-0 left-0 h-full w-80 bg-gray-900 text-white shadow-2xl z-50 transform transition-transform duration-300 ease-in-out flex flex-col ${
isOpen ? 'translate-x-0' : '-translate-x-full'
isOpen ? "translate-x-0" : "-translate-x-full"
}`}
>
<div className="flex items-center justify-between p-4 border-b border-gray-700">
@@ -52,7 +51,7 @@ export default function Header() {
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Home size={20} />
@@ -67,7 +66,7 @@ export default function Header() {
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Network size={20} />
@@ -80,7 +79,7 @@ export default function Header() {
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Globe size={20} />
@@ -93,7 +92,7 @@ export default function Header() {
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Languages size={20} />

View File

@@ -0,0 +1,14 @@
import { TanStackDevtools } from "@tanstack/react-devtools"
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"
export const Devtools = () => {
return (
<TanStackDevtools
plugins={[
{ name: "TanStack Router", render: <TanStackRouterDevtools /> },
{ name: "TanStack Query", render: <ReactQueryDevtools /> }
]}
/>
)
}

View File

@@ -1,6 +1,6 @@
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools'
import { ReactQueryDevtoolsPanel } from "@tanstack/react-query-devtools"
export default {
name: 'Tanstack Query',
render: <ReactQueryDevtoolsPanel />,
name: "Tanstack Query",
render: <ReactQueryDevtoolsPanel />
}

View File

@@ -1,34 +0,0 @@
import type { ReactNode } from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
let context:
| {
queryClient: QueryClient
}
| undefined
export function getContext() {
if (context) {
return context
}
const queryClient = new QueryClient()
context = {
queryClient,
}
return context
}
export default function TanStackQueryProvider({
children,
}: {
children: ReactNode
}) {
const { queryClient } = getContext()
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
}

View File

@@ -1,7 +0,0 @@
import type { ClassValue } from 'clsx'
import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

View File

@@ -1,23 +1,29 @@
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
import { getContext } from './integrations/tanstack-query/root-provider'
import { QueryClient } from "@tanstack/react-query"
import { createRouter as createTanStackRouter } from "@tanstack/react-router"
import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query"
import { routeTree } from "./routeTree.gen"
export function getRouter() {
const queryClient = new QueryClient()
const router = createTanStackRouter({
routeTree,
context: getContext(),
context: {
queryClient
},
scrollRestoration: true,
defaultPreload: 'intent',
defaultPreloadStaleTime: 0,
defaultPreload: "intent",
defaultPreloadStaleTime: 0
})
setupRouterSsrQueryIntegration({
router,
queryClient
})
return router
}
declare module '@tanstack/react-router' {
declare module "@tanstack/react-router" {
interface Register {
router: ReturnType<typeof getRouter>
}

View File

@@ -1,19 +1,16 @@
import { TanStackDevtools } from "@tanstack/react-devtools";
import type { QueryClient } from "@tanstack/react-query";
import type { QueryClient } from "@tanstack/react-query"
import {
createRootRouteWithContext,
HeadContent,
Scripts,
} from "@tanstack/react-router";
import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools";
import { getLocale } from "@/paraglide/runtime";
import Header from "../components/Header";
import TanStackQueryDevtools from "../integrations/tanstack-query/devtools";
import TanStackQueryProvider from "../integrations/tanstack-query/root-provider";
import appCss from "../styles.css?url";
Scripts
} from "@tanstack/react-router"
import { Devtools } from "@/integrations/devtools"
import { getLocale } from "@/paraglide/runtime"
import appCss from "@/styles/globals.css?url"
import Header from "../components/Header"
interface MyRouterContext {
queryClient: QueryClient;
queryClient: QueryClient
}
export const Route = createRootRouteWithContext<MyRouterContext>()({
@@ -21,32 +18,32 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({
// Other redirect strategies are possible; see
// https://github.com/TanStack/router/tree/main/examples/react/i18n-paraglide#offline-redirect
if (typeof document !== "undefined") {
document.documentElement.setAttribute("lang", getLocale());
document.documentElement.setAttribute("lang", getLocale())
}
},
head: () => ({
meta: [
{
charSet: "utf-8",
charSet: "utf-8"
},
{
name: "viewport",
content: "width=device-width, initial-scale=1",
content: "width=device-width, initial-scale=1"
},
{
title: "TanStack Start Starter",
},
title: "TanStack Start Starter"
}
],
links: [
{
rel: "stylesheet",
href: appCss,
},
],
href: appCss
}
]
}),
shellComponent: RootDocument,
});
shellComponent: RootDocument
})
function RootDocument({ children }: { children: React.ReactNode }) {
return (
@@ -55,24 +52,11 @@ function RootDocument({ children }: { children: React.ReactNode }) {
<HeadContent />
</head>
<body>
<TanStackQueryProvider>
<Header />
{children}
<TanStackDevtools
config={{
position: "bottom-right",
}}
plugins={[
{
name: "Tanstack Router",
render: <TanStackRouterDevtoolsPanel />,
},
TanStackQueryDevtools,
]}
/>
</TanStackQueryProvider>
<Devtools />
<Scripts />
</body>
</html>
);
)
}

View File

@@ -1,10 +1,10 @@
import { createFileRoute } from "@tanstack/react-router";
import { m } from "@/paraglide/messages";
import LocaleSwitcher from "../components/LocaleSwitcher";
import { createFileRoute } from "@tanstack/react-router"
import { m } from "@/paraglide/messages"
import LocaleSwitcher from "../components/LocaleSwitcher"
export const Route = createFileRoute("/demo/i18n")({
component: App,
});
component: App
})
function App() {
return (
@@ -24,5 +24,5 @@ function App() {
</div>
</header>
</div>
);
)
}

View File

@@ -6,7 +6,7 @@ import {
Shield,
Sparkles,
Waves,
Zap,
Zap
} from "lucide-react"
export const Route = createFileRoute("/")({ component: App })
@@ -17,45 +17,45 @@ function App() {
icon: <Zap className="w-12 h-12 text-cyan-400" />,
title: "Powerful Server Functions",
description:
"Write server-side code that seamlessly integrates with your client components. Type-safe, secure, and simple.",
"Write server-side code that seamlessly integrates with your client components. Type-safe, secure, and simple."
},
{
icon: <Server className="w-12 h-12 text-cyan-400" />,
title: "Flexible Server Side Rendering",
description:
"Full-document SSR, streaming, and progressive enhancement out of the box. Control exactly what renders where.",
"Full-document SSR, streaming, and progressive enhancement out of the box. Control exactly what renders where."
},
{
icon: <RouteIcon className="w-12 h-12 text-cyan-400" />,
title: "API Routes",
description:
"Build type-safe API endpoints alongside your application. No separate backend needed.",
"Build type-safe API endpoints alongside your application. No separate backend needed."
},
{
icon: <Shield className="w-12 h-12 text-cyan-400" />,
title: "Strongly Typed Everything",
description:
"End-to-end type safety from server to client. Catch errors before they reach production.",
"End-to-end type safety from server to client. Catch errors before they reach production."
},
{
icon: <Waves className="w-12 h-12 text-cyan-400" />,
title: "Full Streaming Support",
description:
"Stream data from server to client progressively. Perfect for AI applications and real-time updates.",
"Stream data from server to client progressively. Perfect for AI applications and real-time updates."
},
{
icon: <Sparkles className="w-12 h-12 text-cyan-400" />,
title: "Next Generation Ready",
description:
"Built from the ground up for modern web applications. Deploy anywhere JavaScript runs.",
},
"Built from the ground up for modern web applications. Deploy anywhere JavaScript runs."
}
]
return (
<div className="min-h-screen bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900">
<div className="min-h-screen bg-linear-to-b from-slate-900 via-slate-800 to-slate-900">
<Button> Hola</Button>
<section className="relative py-20 px-6 text-center overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10"></div>
<div className="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10"></div>
<div className="relative max-w-5xl mx-auto">
<div className="flex items-center justify-center gap-6 mb-6">
<img
@@ -63,9 +63,9 @@ function App() {
alt="TanStack Logo"
className="w-24 h-24 md:w-32 md:h-32"
/>
<h1 className="text-6xl md:text-7xl font-black text-white [letter-spacing:-0.08em]">
<h1 className="text-6xl md:text-7xl font-black text-white tracking-[-0.08em]">
<span className="text-gray-300">TANSTACK</span>{" "}
<span className="bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent">
<span className="bg-linear-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent">
START
</span>
</h1>

View File

@@ -1,26 +1,24 @@
import { paraglideVitePlugin } from "@inlang/paraglide-js";
import tailwindcss from "@tailwindcss/vite";
import { devtools } from "@tanstack/devtools-vite";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import viteReact from "@vitejs/plugin-react";
import { nitro } from "nitro/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
import { paraglideVitePlugin } from "@inlang/paraglide-js"
import tailwindcss from "@tailwindcss/vite"
import { devtools } from "@tanstack/devtools-vite"
import { tanstackStart } from "@tanstack/react-start/plugin/vite"
import viteReact from "@vitejs/plugin-react"
import { nitro } from "nitro/vite"
import { defineConfig } from "vite"
import tsconfigPaths from "vite-tsconfig-paths"
const config = defineConfig({
export default defineConfig({
plugins: [
devtools(),
paraglideVitePlugin({
project: "./project.inlang",
outdir: "./src/paraglide",
strategy: ["url", "baseLocale"],
strategy: ["url", "baseLocale"]
}),
nitro({ rollupConfig: { external: [/^@sentry\//] } }),
tsconfigPaths({ projects: ["./tsconfig.json"] }),
tailwindcss(),
tanstackStart(),
viteReact(),
],
});
export default config;
viteReact()
]
})