refactor: Consolidate global styling with Tailwind and HeroUI theme variables and refactor devtools integration.
This commit is contained in:
23
.cta.json
23
.cta.json
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"formatter": {
|
||||
"quoteStyle": "double",
|
||||
"semicolons": "asNeeded",
|
||||
"trailingCommas": "es5"
|
||||
"trailingCommas": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4280
package-lock.json
generated
4280
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
68
package.json
68
package.json
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,112 +1,111 @@
|
||||
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)
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="p-4 flex items-center bg-gray-800 text-white shadow-lg">
|
||||
<button
|
||||
onClick={() => setIsOpen(true)}
|
||||
className="p-2 hover:bg-gray-700 rounded-lg transition-colors"
|
||||
aria-label="Open menu"
|
||||
>
|
||||
<Menu size={24} />
|
||||
</button>
|
||||
<h1 className="ml-4 text-xl font-semibold">
|
||||
<Link to="/">
|
||||
<img
|
||||
src="/tanstack-word-logo-white.svg"
|
||||
alt="TanStack Logo"
|
||||
className="h-10"
|
||||
/>
|
||||
</Link>
|
||||
</h1>
|
||||
</header>
|
||||
return (
|
||||
<>
|
||||
<header className="p-4 flex items-center bg-gray-800 text-white shadow-lg">
|
||||
<button
|
||||
onClick={() => setIsOpen(true)}
|
||||
className="p-2 hover:bg-gray-700 rounded-lg transition-colors"
|
||||
aria-label="Open menu"
|
||||
>
|
||||
<Menu size={24} />
|
||||
</button>
|
||||
<h1 className="ml-4 text-xl font-semibold">
|
||||
<Link to="/">
|
||||
<img
|
||||
src="/tanstack-word-logo-white.svg"
|
||||
alt="TanStack Logo"
|
||||
className="h-10"
|
||||
/>
|
||||
</Link>
|
||||
</h1>
|
||||
</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'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-700">
|
||||
<h2 className="text-xl font-bold">Navigation</h2>
|
||||
<button
|
||||
onClick={() => setIsOpen(false)}
|
||||
className="p-2 hover:bg-gray-800 rounded-lg transition-colors"
|
||||
aria-label="Close menu"
|
||||
>
|
||||
<X size={24} />
|
||||
</button>
|
||||
</div>
|
||||
<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"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-700">
|
||||
<h2 className="text-xl font-bold">Navigation</h2>
|
||||
<button
|
||||
onClick={() => setIsOpen(false)}
|
||||
className="p-2 hover:bg-gray-800 rounded-lg transition-colors"
|
||||
aria-label="Close menu"
|
||||
>
|
||||
<X size={24} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav className="flex-1 p-4 overflow-y-auto">
|
||||
<Link
|
||||
to="/"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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',
|
||||
}}
|
||||
>
|
||||
<Home size={20} />
|
||||
<span className="font-medium">Home</span>
|
||||
</Link>
|
||||
<nav className="flex-1 p-4 overflow-y-auto">
|
||||
<Link
|
||||
to="/"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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"
|
||||
}}
|
||||
>
|
||||
<Home size={20} />
|
||||
<span className="font-medium">Home</span>
|
||||
</Link>
|
||||
|
||||
{/* Demo Links Start */}
|
||||
{/* Demo Links Start */}
|
||||
|
||||
<Link
|
||||
to="/demo/tanstack-query"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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',
|
||||
}}
|
||||
>
|
||||
<Network size={20} />
|
||||
<span className="font-medium">TanStack Query</span>
|
||||
</Link>
|
||||
<Link
|
||||
to="/demo/tanstack-query"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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"
|
||||
}}
|
||||
>
|
||||
<Network size={20} />
|
||||
<span className="font-medium">TanStack Query</span>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to="/demo/sentry/testing"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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',
|
||||
}}
|
||||
>
|
||||
<Globe size={20} />
|
||||
<span className="font-medium">Sentry</span>
|
||||
</Link>
|
||||
<Link
|
||||
to="/demo/sentry/testing"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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"
|
||||
}}
|
||||
>
|
||||
<Globe size={20} />
|
||||
<span className="font-medium">Sentry</span>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to="/demo/i18n"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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',
|
||||
}}
|
||||
>
|
||||
<Languages size={20} />
|
||||
<span className="font-medium">I18n example</span>
|
||||
</Link>
|
||||
<Link
|
||||
to="/demo/i18n"
|
||||
onClick={() => setIsOpen(false)}
|
||||
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"
|
||||
}}
|
||||
>
|
||||
<Languages size={20} />
|
||||
<span className="font-medium">I18n example</span>
|
||||
</Link>
|
||||
|
||||
{/* Demo Links End */}
|
||||
</nav>
|
||||
{/* Demo Links End */}
|
||||
</nav>
|
||||
|
||||
<div className="p-4 border-t border-gray-700 bg-gray-800 flex flex-col gap-2">
|
||||
<ParaglideLocaleSwitcher />
|
||||
</div>
|
||||
</aside>
|
||||
</>
|
||||
)
|
||||
<div className="p-4 border-t border-gray-700 bg-gray-800 flex flex-col gap-2">
|
||||
<ParaglideLocaleSwitcher />
|
||||
</div>
|
||||
</aside>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
14
src/integrations/devtools/index.tsx
Normal file
14
src/integrations/devtools/index.tsx
Normal 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 /> }
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -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 />
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -1,24 +1,30 @@
|
||||
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 router = createTanStackRouter({
|
||||
routeTree,
|
||||
const queryClient = new QueryClient()
|
||||
const router = createTanStackRouter({
|
||||
routeTree,
|
||||
context: {
|
||||
queryClient
|
||||
},
|
||||
scrollRestoration: true,
|
||||
defaultPreload: "intent",
|
||||
defaultPreloadStaleTime: 0
|
||||
})
|
||||
|
||||
context: getContext(),
|
||||
setupRouterSsrQueryIntegration({
|
||||
router,
|
||||
queryClient
|
||||
})
|
||||
|
||||
scrollRestoration: true,
|
||||
defaultPreload: 'intent',
|
||||
defaultPreloadStaleTime: 0,
|
||||
})
|
||||
|
||||
return router
|
||||
return router
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface Register {
|
||||
router: ReturnType<typeof getRouter>
|
||||
}
|
||||
declare module "@tanstack/react-router" {
|
||||
interface Register {
|
||||
router: ReturnType<typeof getRouter>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
<Header />
|
||||
{children}
|
||||
<Devtools />
|
||||
<Scripts />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
]
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user