Bring the codebase in line with CLAUDE.md conventions

- Convert getRouter, OrderingPage, and OrderStatusRoute from function
  declarations to arrow functions
- Migrate header-user.tsx off raw Tailwind classes onto a co-located
  SCSS module, and remove Tailwind entirely (deps, Vite plugin,
  styles.css) since it was the only consumer and duplicated the
  documented SCSS Modules system
- Fix CLAUDE.md's stale ~/ alias example and structure diagram to
  match the project's actual #/ and @/ aliases and directories

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-10 08:06:22 +02:00
co-authored by Claude Sonnet 5
parent ff8fc388c0
commit 0d8f8f8148
12 changed files with 113 additions and 338 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
"projectName": "ghost-kitchen-scaffold",
"mode": "file-router",
"typescript": true,
"tailwind": true,
"tailwind": false,
"packageManager": "npm",
"git": false,
"install": true,
+13 -4
View File
@@ -38,8 +38,13 @@ src/
├── routeTree.gen.ts # AUTO-GENERATED — never edit by hand
├── router.tsx # router instance/config
├── components/
│ ├── ui/ # base primitives (buttons, inputs, etc.)
│ └── <domain>/ # feature-specific components, e.g. posts/, auth/
│ ├── ui/ # base primitives (buttons, inputs, etc.) — not
│ │ populated yet; add it when a shared primitive
│ │ is needed
│ └── <domain>/ # feature-specific components, e.g. ordering/, orders/
├── domain/ # framework-free business logic, e.g. ordering.ts
├── server/ # server functions (createServerFn) callable from routes
├── integrations/ # third-party integration glue, e.g. better-auth/
├── lib/ # shared utilities, API clients, helpers
├── db/
│ ├── schema.ts # Drizzle schema definitions
@@ -73,7 +78,8 @@ drizzle/ # generated SQL migrations — never hand-edit
- Class names in `.module.scss` files are camelCase (e.g. `.cardHeader`, not
`.card-header`) so they read naturally as `styles.cardHeader`.
- Shared tokens (colors, spacing, breakpoints) live in `src/styles/_variables.scss`
and are pulled in with `@use '~/styles/variables' as *;` — don't hardcode
and are pulled in with a relative `@use '../styles/variables' as *;` (Sass
doesn't resolve the `#/`/`@/` TS path aliases) — don't hardcode
colors/spacing that already exist as a variable.
- `src/styles/globals.scss` is for resets and truly global rules only
(imported once in `__root.tsx`); component-specific styles always go in a
@@ -94,7 +100,10 @@ drizzle/ # generated SQL migrations — never hand-edit
the `function` keyword — e.g. `const getUser = async (id: string) => {...}`
and `export const Button = (props: ButtonProps) => {...}`.
- [Naming conventions: PascalCase components, camelCase functions/vars, etc.]
- [Import order / path aliases, e.g. `~/` or `@/` for `src/`]
- Path aliases `#/*` and `@/*` both resolve to `src/*` (see `tsconfig.json`
and `package.json`'s `imports` field) — use either for TS/TSX imports.
SCSS files can't use these aliases; use relative `@use`/`@import` paths
there instead.
- Co-locate a component's test file next to it unless it's a shared
primitive in `components/ui/` (see "Styling" for `.module.scss` placement).
- No comments unless they're unavoidable for understanding — e.g. explaining
+20 -277
View File
@@ -6,7 +6,6 @@
"": {
"name": "ghost-kitchen",
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-devtools": "latest",
"@tanstack/react-router": "latest",
"@tanstack/react-router-devtools": "latest",
@@ -18,7 +17,6 @@
"react": "^19.2.0",
"react-dom": "^19.2.0",
"stripe": "^22.6.1",
"tailwindcss": "^4.1.18",
"zod": "^4.5.4"
},
"devDependencies": {
@@ -457,8 +455,10 @@
"version": "1.11.3",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz",
"integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@emnapi/wasi-threads": "1.2.3",
"tslib": "^2.4.0"
@@ -468,8 +468,10 @@
"version": "1.11.3",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
"integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
@@ -478,8 +480,10 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz",
"integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
@@ -1759,6 +1763,7 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz",
"integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -2879,6 +2884,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
"integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
"devOptional": true,
"license": "MIT"
},
"node_modules/@solid-primitives/event-listener": {
@@ -2982,275 +2988,6 @@
"eslint": "^9.0.0 || ^10.0.0"
}
},
"node_modules/@tailwindcss/node": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz",
"integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.5",
"enhanced-resolve": "^5.24.1",
"jiti": "^2.7.0",
"lightningcss": "1.32.0",
"magic-string": "^0.30.21",
"source-map-js": "^1.2.1",
"tailwindcss": "4.3.3"
}
},
"node_modules/@tailwindcss/oxide": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz",
"integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==",
"license": "MIT",
"engines": {
"node": ">= 20"
},
"optionalDependencies": {
"@tailwindcss/oxide-android-arm64": "4.3.3",
"@tailwindcss/oxide-darwin-arm64": "4.3.3",
"@tailwindcss/oxide-darwin-x64": "4.3.3",
"@tailwindcss/oxide-freebsd-x64": "4.3.3",
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3",
"@tailwindcss/oxide-linux-arm64-gnu": "4.3.3",
"@tailwindcss/oxide-linux-arm64-musl": "4.3.3",
"@tailwindcss/oxide-linux-x64-gnu": "4.3.3",
"@tailwindcss/oxide-linux-x64-musl": "4.3.3",
"@tailwindcss/oxide-wasm32-wasi": "4.3.3",
"@tailwindcss/oxide-win32-arm64-msvc": "4.3.3",
"@tailwindcss/oxide-win32-x64-msvc": "4.3.3"
}
},
"node_modules/@tailwindcss/oxide-android-arm64": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz",
"integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-darwin-arm64": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz",
"integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-darwin-x64": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz",
"integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-freebsd-x64": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz",
"integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz",
"integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz",
"integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz",
"integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz",
"integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz",
"integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz",
"integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==",
"bundleDependencies": [
"@napi-rs/wasm-runtime",
"@emnapi/core",
"@emnapi/runtime",
"@tybys/wasm-util",
"@emnapi/wasi-threads",
"tslib"
],
"cpu": [
"wasm32"
],
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "^1.11.1",
"@emnapi/runtime": "^1.11.1",
"@emnapi/wasi-threads": "^1.2.2",
"@napi-rs/wasm-runtime": "^1.1.4",
"@tybys/wasm-util": "^0.10.2",
"tslib": "^2.8.1"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz",
"integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz",
"integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/vite": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz",
"integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==",
"license": "MIT",
"dependencies": {
"@tailwindcss/node": "4.3.3",
"@tailwindcss/oxide": "4.3.3",
"tailwindcss": "4.3.3"
},
"peerDependencies": {
"vite": "^5.2.0 || ^6 || ^7 || ^8"
}
},
"node_modules/@tanstack/devtools": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/@tanstack/devtools/-/devtools-0.14.2.tgz",
@@ -3994,6 +3731,7 @@
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
"integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -6606,6 +6344,7 @@
"version": "5.24.5",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz",
"integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==",
"dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -7409,6 +7148,7 @@
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true,
"license": "ISC"
},
"node_modules/h3-v2": {
@@ -8177,6 +7917,7 @@
"version": "3.3.18",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
"integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
"devOptional": true,
"funding": [
{
"type": "github",
@@ -8548,6 +8289,7 @@
"version": "8.5.28",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
"integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
"devOptional": true,
"funding": [
{
"type": "opencollective",
@@ -8862,6 +8604,7 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.8.tgz",
"integrity": "sha512-Z67nTmhZe7anqnM/EjI392w5i/ANUinjip7QYsOyN37oayduxt3ksdX0hf5OOamkAd53BiIHfbfSzfUmzKFQqQ==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"@oxc-project/types": "=0.149.0",
@@ -8895,6 +8638,7 @@
"version": "0.149.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.149.0.tgz",
"integrity": "sha512-Efcc+iF0j3Bf67YjEqIqWXbX5XddXoK/Mw4K1/JuXwRCZ8N16VR7iT23nlCc9XrveFVh/E5Rqs2StT0V8v9LdA==",
"devOptional": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/oxc-project"
@@ -9098,6 +8842,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"devOptional": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -9337,16 +9082,11 @@
"node": ">=8"
}
},
"node_modules/tailwindcss": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz",
"integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==",
"license": "MIT"
},
"node_modules/tapable": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",
"integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -9524,6 +9264,7 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD",
"optional": true
},
@@ -9778,6 +9519,7 @@
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz",
"integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"lightningcss": "^1.33.0",
@@ -9855,6 +9597,7 @@
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
"integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
"devOptional": true,
"license": "MPL-2.0",
"dependencies": {
"detect-libc": "^2.0.3"
-2
View File
@@ -24,7 +24,6 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-devtools": "latest",
"@tanstack/react-router": "latest",
"@tanstack/react-router-devtools": "latest",
@@ -36,7 +35,6 @@
"react": "^19.2.0",
"react-dom": "^19.2.0",
"stripe": "^22.6.1",
"tailwindcss": "^4.1.18",
"zod": "^4.5.4"
},
"devDependencies": {
@@ -0,0 +1,52 @@
@use '../../styles/variables' as *;
.avatar {
height: 2rem;
width: 2rem;
background: $color-surface;
}
.avatarPulse {
animation: pulse 1.5s ease-in-out infinite;
}
.avatarInitial {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.75rem;
font-weight: 500;
color: $color-text-muted;
}
.session {
display: flex;
align-items: center;
gap: $space-2;
}
.signOut {
flex: 1;
height: 2.25rem;
padding: 0 $space-3;
font-size: 0.875rem;
font-weight: 500;
background: $color-background;
color: $color-text;
border: 1px solid $color-border;
transition: background-color 0.15s ease;
&:hover {
background: $color-surface;
}
}
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
+8 -10
View File
@@ -1,31 +1,29 @@
import { authClient } from '#/lib/auth-client'
import styles from './header-user.module.scss'
const BetterAuthHeader = () => {
const { data: session, isPending } = authClient.useSession()
if (isPending) {
return (
<div className="h-8 w-8 bg-neutral-100 dark:bg-neutral-800 animate-pulse" />
)
return <div className={`${styles.avatar} ${styles.avatarPulse}`} />
}
if (session?.user) {
return (
<div className="flex items-center gap-2">
<div className={styles.session}>
{session.user.image ? (
<img src={session.user.image} alt="" className="h-8 w-8" />
<img src={session.user.image} alt="" className={styles.avatar} />
) : (
<div className="h-8 w-8 bg-neutral-100 dark:bg-neutral-800 flex items-center justify-center">
<span className="text-xs font-medium text-neutral-600 dark:text-neutral-400">
{session.user.name.charAt(0).toUpperCase() || 'U'}
</span>
<div className={`${styles.avatar} ${styles.avatarInitial}`}>
<span>{session.user.name.charAt(0).toUpperCase() || 'U'}</span>
</div>
)}
<button
onClick={() => {
void authClient.signOut()
}}
className="flex-1 h-9 px-4 text-sm font-medium bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-50 border border-neutral-300 dark:border-neutral-700 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors"
className={styles.signOut}
>
Sign out
</button>
+1 -1
View File
@@ -1,7 +1,7 @@
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
export function getRouter() {
export const getRouter = () => {
const router = createTanStackRouter({
routeTree,
scrollRestoration: true,
-7
View File
@@ -2,7 +2,6 @@ import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router'
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
import { TanStackDevtools } from '@tanstack/react-devtools'
import appCss from '../styles.css?url'
import '../styles/globals.scss'
const RootDocument = ({ children }: { children: React.ReactNode }) => (
@@ -42,12 +41,6 @@ export const Route = createRootRoute({
title: 'Ghost Kitchen',
},
],
links: [
{
rel: 'stylesheet',
href: appCss,
},
],
}),
shellComponent: RootDocument,
})
+10 -10
View File
@@ -9,16 +9,7 @@ import { getMenu } from '#/server/menu.ts'
import styles from './index.module.scss'
export const Route = createFileRoute('/')({
loader: async () => {
const brand = await getBrand()
const menu = await getMenu({ data: { brandId: brand.id } })
return { brand, menu }
},
component: OrderingPage,
})
function OrderingPage() {
const OrderingPage = () => {
const { brand, menu } = Route.useLoaderData()
const navigate = useNavigate()
const [quantities, setQuantities] = useState<Record<number, number>>({})
@@ -76,3 +67,12 @@ function OrderingPage() {
</main>
)
}
export const Route = createFileRoute('/')({
loader: async () => {
const brand = await getBrand()
const menu = await getMenu({ data: { brandId: brand.id } })
return { brand, menu }
},
component: OrderingPage,
})
+7 -7
View File
@@ -6,6 +6,13 @@ import { getOrderStatus } from '#/server/orders.ts'
const searchSchema = z.object({ token: z.string().optional() })
const OrderStatusRoute = () => {
const status = Route.useLoaderData()
const { token } = Route.useSearch()
return <OrderStatusView status={status} guestAccessToken={token} />
}
export const Route = createFileRoute('/orders/$orderId')({
validateSearch: (search: Record<string, unknown>) =>
searchSchema.parse(search),
@@ -19,10 +26,3 @@ export const Route = createFileRoute('/orders/$orderId')({
}),
component: OrderStatusRoute,
})
function OrderStatusRoute() {
const status = Route.useLoaderData()
const { token } = Route.useSearch()
return <OrderStatusView status={status} guestAccessToken={token} />
}
-17
View File
@@ -1,17 +0,0 @@
@import "tailwindcss";
* {
box-sizing: border-box;
}
html,
body,
#app {
min-height: 100%;
}
body {
margin: 0;
}
+1 -2
View File
@@ -4,11 +4,10 @@ import { devtools } from '@tanstack/devtools-vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import viteReact from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
const config = defineConfig({
resolve: { tsconfigPaths: true },
plugins: [devtools(), tailwindcss(), tanstackStart(), viteReact()],
plugins: [devtools(), tanstackStart(), viteReact()],
})
export default config