diff --git a/index.html b/index.html index 87d7036..9f1774a 100644 --- a/index.html +++ b/index.html @@ -4,11 +4,36 @@ + + + + + + + + - + + Maintainable Frontend Architecture with React diff --git a/package.json b/package.json index cd6190f..ac2b272 100644 --- a/package.json +++ b/package.json @@ -46,8 +46,6 @@ "@tailwindcss/vite": "^4.3.3", "@tanstack/react-form": "^1.33.5", "@tanstack/react-router": "^1.170.32", - "@tanstack/react-router-devtools": "^1.167.1", - "@tanstack/router-plugin": "^1.168.35", "@tanstack/store": "^0.11.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -69,6 +67,8 @@ "@commitlint/cli": "21.2.2", "@commitlint/config-conventional": "21.2.2", "@playwright/test": "1.62.1", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/router-plugin": "^1.168.35", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^7.0.1", "@testing-library/react": "^16.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 428d257..f735def 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,12 +32,6 @@ importers: '@tanstack/react-router': specifier: ^1.170.32 version: 1.170.32(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@tanstack/react-router-devtools': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(rolldown@1.2.6)(rollup@4.63.1)(vite@8.2.2(@types/node@22.20.1)(jiti@2.7.0)(yaml@2.9.0)) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -96,6 +90,12 @@ importers: '@playwright/test': specifier: 1.62.1 version: 1.62.1 + '@tanstack/react-router-devtools': + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@tanstack/router-plugin': + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(rolldown@1.2.6)(rollup@4.63.1)(vite@8.2.2(@types/node@22.20.1)(jiti@2.7.0)(yaml@2.9.0)) '@testing-library/dom': specifier: ^10.4.1 version: 10.4.1 diff --git a/public/manifest.json b/public/manifest.json index 078ef50..3d896f0 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,6 +1,7 @@ { - "short_name": "TanStack App", - "name": "Create TanStack App Sample", + "short_name": "Azeroth's Finest Wares", + "name": "Azeroth's Finest Wares — Object Calisthenics Demo", + "description": "Interactive React demo showing how to apply Object Calisthenics rules for maintainable, well-structured front-end code.", "icons": [ { "src": "favicon.ico", @@ -20,6 +21,6 @@ ], "start_url": ".", "display": "standalone", - "theme_color": "#000000", + "theme_color": "#ffffff", "background_color": "#ffffff" } diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/main.tsx b/src/app/main.tsx index 9a37b80..5c2e177 100644 --- a/src/app/main.tsx +++ b/src/app/main.tsx @@ -1,6 +1,7 @@ import { createRouter, RouterProvider } from "@tanstack/react-router"; import { StrictMode } from "react"; import ReactDOM from "react-dom/client"; +import { ANALYTICS_CONFIG } from "@/config/analytics.config"; import { SITE_CONFIG } from "@/config/site.config"; // Import the generated route tree import { routeTree } from "./routeTree.gen.ts"; @@ -45,7 +46,12 @@ if (rootElement && !rootElement.innerHTML) { ); } -// 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(); +// Forward Core Web Vitals to Umami. window.umami is undefined until the analytics +// script has loaded, so this is a safe no-op if it never does. +reportWebVitals((metric) => { + window.umami?.track(ANALYTICS_CONFIG.events.webVital, { + name: metric.name, + value: Math.round(metric.name === "CLS" ? metric.value * 1000 : metric.value), + rating: metric.rating, + }); +}); diff --git a/src/app/routes/__root.tsx b/src/app/routes/__root.tsx index 7ecff40..b3d095d 100644 --- a/src/app/routes/__root.tsx +++ b/src/app/routes/__root.tsx @@ -1,12 +1,21 @@ import { createRootRoute, Outlet } from "@tanstack/react-router"; -import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"; import { MotionConfig } from "motion/react"; +import { lazy, Suspense } from "react"; +import { SITE_CONFIG } from "@/config/site.config"; import Header from "@/ui/components/Header"; +const TanStackRouterDevtools = import.meta.env.DEV + ? lazy(() => + import("@tanstack/react-router-devtools").then((module) => ({ + default: module.TanStackRouterDevtools, + })), + ) + : () => null; + export const Route = createRootRoute({ component: () => ( -
+
- - +
+ +
+
+ {import.meta.env.DEV && ( + + + + )}
), diff --git a/src/app/routes/index.tsx b/src/app/routes/index.tsx index f52e4d5..dc70a2d 100644 --- a/src/app/routes/index.tsx +++ b/src/app/routes/index.tsx @@ -9,14 +9,14 @@ export const Route = createFileRoute("/")({ component: App, }); -const linkClassName = - "inline-flex items-center gap-2 font-semibold text-[#61dafb] transition-colors duration-200 hover:text-white hover:underline underline-offset-4 rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-[#61dafb] focus-visible:ring-offset-2 focus-visible:ring-offset-[#282c34]"; +const secondaryLinkClassName = + "inline-flex items-center gap-2 rounded-sm font-semibold text-foreground underline-offset-4 outline-none transition-colors duration-200 hover:text-primary hover:underline focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"; function App() { return (
-

+

Maintainable Frontend Architecture with React

-

+

This site is a hands-on demo showing how to apply{" "} - Object Calisthenics in a front-end app. - You'll see how keeping objects small, simple, and focused makes your React code - easier to understand and maintain. + Object Calisthenics in a front-end + app. You'll see how keeping objects small, simple, and focused makes your React + code easier to understand and maintain.

-

+

Take a few moments to explore the interactive experience, then dive into the code to see these principles in action.

@@ -44,7 +44,7 @@ function App() {