better-ts-stack 0.1.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +12 -6
  2. package/dist/builder/configGenerator.d.ts.map +1 -1
  3. package/dist/builder/configGenerator.js +30 -24
  4. package/dist/builder/configGenerator.js.map +1 -1
  5. package/dist/builder/dependencyInstaller.d.ts.map +1 -1
  6. package/dist/builder/dependencyInstaller.js +1 -10
  7. package/dist/builder/dependencyInstaller.js.map +1 -1
  8. package/dist/builder/index.d.ts.map +1 -1
  9. package/dist/builder/index.js +3 -7
  10. package/dist/builder/index.js.map +1 -1
  11. package/dist/builder/moduleSelector.d.ts.map +1 -1
  12. package/dist/builder/moduleSelector.js +1 -1
  13. package/dist/builder/moduleSelector.js.map +1 -1
  14. package/dist/builder/templateContext.d.ts +2 -2
  15. package/dist/builder/templateContext.d.ts.map +1 -1
  16. package/dist/builder/templateContext.js +1 -3
  17. package/dist/builder/templateContext.js.map +1 -1
  18. package/dist/modules/registry.d.ts.map +1 -1
  19. package/dist/modules/registry.js +2 -5
  20. package/dist/modules/registry.js.map +1 -1
  21. package/dist/output/nextSteps.d.ts.map +1 -1
  22. package/dist/output/nextSteps.js +7 -34
  23. package/dist/output/nextSteps.js.map +1 -1
  24. package/dist/prompts/index.d.ts.map +1 -1
  25. package/dist/prompts/index.js +3 -14
  26. package/dist/prompts/index.js.map +1 -1
  27. package/dist/prompts/stack.d.ts +3 -0
  28. package/dist/prompts/stack.d.ts.map +1 -0
  29. package/dist/prompts/stack.js +77 -0
  30. package/dist/prompts/stack.js.map +1 -0
  31. package/dist/types/index.d.ts +12 -10
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/types/index.js +6 -10
  34. package/dist/types/index.js.map +1 -1
  35. package/dist/validators/index.d.ts +1 -1
  36. package/dist/validators/index.d.ts.map +1 -1
  37. package/dist/validators/index.js +1 -1
  38. package/package.json +12 -12
  39. package/templates/backend/express/config.json +44 -42
  40. package/templates/backend/express/eslint.config.mjs +40 -31
  41. package/templates/backend/express/src/index.ts +61 -46
  42. package/templates/backend/express/src/routes/health.ts +12 -12
  43. package/templates/backend/express/tsconfig.json +25 -23
  44. package/templates/frontend/nextjs/config.json +33 -27
  45. package/templates/frontend/nextjs/eslint.config.mjs +11 -11
  46. package/templates/frontend/nextjs/proxy.ts.hbs +9 -8
  47. package/templates/frontend/nextjs/tsconfig.json +34 -21
  48. package/templates/frontend/tanstack/components.json +18 -0
  49. package/templates/frontend/tanstack/config.json +49 -0
  50. package/templates/frontend/tanstack/eslint.config.mjs +23 -0
  51. package/templates/frontend/tanstack/gitignore +38 -0
  52. package/templates/frontend/tanstack/public/favicon.svg +7 -0
  53. package/templates/frontend/tanstack/src/components/ui/button.tsx +51 -0
  54. package/templates/frontend/tanstack/src/components/ui/card.tsx +60 -0
  55. package/templates/frontend/tanstack/src/components/ui/field.tsx +67 -0
  56. package/templates/frontend/tanstack/src/components/ui/input.tsx +18 -0
  57. package/templates/frontend/tanstack/src/lib/utils.ts +6 -0
  58. package/templates/frontend/tanstack/src/routeTree.gen.ts +68 -0
  59. package/templates/frontend/tanstack/src/router.tsx +32 -0
  60. package/templates/frontend/tanstack/src/routes/__root.tsx +70 -0
  61. package/templates/frontend/tanstack/src/routes/index.tsx.hbs +102 -0
  62. package/templates/frontend/tanstack/src/styles/app.css +85 -0
  63. package/templates/frontend/tanstack/tsconfig.json +22 -0
  64. package/templates/frontend/tanstack/vite.config.ts +14 -0
  65. package/templates/modules/auth/express/config.json +26 -1
  66. package/templates/modules/auth/express/src/routes/auth.ts.hbs +1 -1
  67. package/templates/modules/auth/express/src/services/userStore.ts.hbs +95 -107
  68. package/templates/modules/auth/nextjs/config.json +6 -6
  69. package/templates/modules/auth/nextjs/lib/auth.ts.hbs +34 -32
  70. package/templates/modules/auth/tanstack/config.json +33 -0
  71. package/templates/modules/auth/tanstack/src/components/auth/sign-in-form.tsx +135 -0
  72. package/templates/modules/auth/tanstack/src/components/auth/sign-out-button.tsx +49 -0
  73. package/templates/modules/auth/tanstack/src/components/auth/sign-up-form.tsx +153 -0
  74. package/templates/modules/auth/tanstack/src/lib/auth-client.ts +3 -0
  75. package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +12 -0
  76. package/templates/modules/auth/tanstack/src/lib/auth-schema.ts +39 -0
  77. package/templates/modules/auth/tanstack/src/lib/auth.ts.hbs +38 -0
  78. package/templates/modules/auth/tanstack/src/routeTree.gen.ts +140 -0
  79. package/templates/modules/auth/tanstack/src/routes/api/auth/$.ts +16 -0
  80. package/templates/modules/auth/tanstack/src/routes/dashboard.tsx +111 -0
  81. package/templates/modules/auth/tanstack/src/routes/sign-in.tsx +37 -0
  82. package/templates/modules/auth/tanstack/src/routes/sign-up.tsx +37 -0
  83. package/templates/modules/docker/.dockerignore +14 -13
  84. package/templates/modules/docker/Dockerfile.hbs +64 -9
  85. package/templates/modules/docker/config.json +19 -16
  86. package/templates/modules/docker/docker-compose.yml.hbs +9 -9
  87. package/templates/modules/drizzle/express/config.json +27 -0
  88. package/templates/modules/drizzle/express/drizzle.config.ts +13 -0
  89. package/templates/modules/drizzle/express/src/lib/db.ts +13 -0
  90. package/templates/modules/drizzle/express/src/lib/schema.ts +10 -0
  91. package/templates/modules/drizzle/nextjs/config.json +27 -19
  92. package/templates/modules/drizzle/nextjs/lib/db.ts +3 -1
  93. package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -84
  94. package/templates/modules/drizzle/tanstack/config.json +26 -0
  95. package/templates/modules/drizzle/tanstack/drizzle.config.ts +13 -0
  96. package/templates/modules/drizzle/tanstack/src/lib/db.ts +13 -0
  97. package/templates/modules/drizzle/tanstack/src/lib/schema.ts.hbs +84 -0
  98. package/templates/modules/mongoose/config.json +16 -16
  99. package/templates/modules/mongoose/src/lib/db.ts.hbs +0 -13
  100. package/templates/modules/mongoose/src/models/User.ts +48 -47
  101. package/templates/modules/prisma/express/config.json +27 -21
  102. package/templates/modules/prisma/express/prisma/schema.prisma +3 -2
  103. package/templates/modules/prisma/express/prisma.config.ts +12 -13
  104. package/templates/modules/prisma/express/src/lib/prisma.ts +24 -37
  105. package/templates/modules/prisma/nextjs/config.json +28 -23
  106. package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +91 -90
  107. package/templates/modules/prisma/tanstack/config.json +28 -0
  108. package/templates/modules/prisma/tanstack/prisma/schema.prisma.hbs +91 -0
  109. package/templates/modules/prisma/tanstack/prisma.config.ts +12 -0
  110. package/templates/modules/prisma/tanstack/src/lib/prisma.ts +18 -0
  111. package/dist/prompts/backend/index.d.ts +0 -3
  112. package/dist/prompts/backend/index.d.ts.map +0 -1
  113. package/dist/prompts/backend/index.js +0 -128
  114. package/dist/prompts/backend/index.js.map +0 -1
  115. package/dist/prompts/frontend/index.d.ts +0 -3
  116. package/dist/prompts/frontend/index.d.ts.map +0 -1
  117. package/dist/prompts/frontend/index.js +0 -111
  118. package/dist/prompts/frontend/index.js.map +0 -1
@@ -1,33 +1,39 @@
1
- {
2
- "id": "nextjs",
3
- "name": "Next.js",
4
- "description": "Next.js 16 App Router with TypeScript and Tailwind CSS",
5
- "type": "base",
6
- "scripts": {
7
- "dev": "next dev",
8
- "build": "next build",
9
- "start": "next start",
10
- "lint": "eslint"
11
- },
1
+ {
2
+ "id": "nextjs",
3
+ "name": "Next.js",
4
+ "description": "Next.js 16 App Router with TypeScript and Tailwind CSS",
5
+ "type": "base",
6
+ "scripts": {
7
+ "dev": "next dev",
8
+ "build": "next build",
9
+ "start": "next start",
10
+ "lint": "eslint",
11
+ "type:check": "tsc --noEmit"
12
+ },
12
13
  "dependencies": {
13
14
  "class-variance-authority": "^0.7.1",
14
15
  "clsx": "^2.1.1",
15
- "lucide-react": "^0.542.0",
16
- "next": "^16.2.0",
17
- "react": "19.2.3",
18
- "react-dom": "19.2.3",
19
- "tailwind-merge": "^3.3.1"
16
+ "lucide-react": "^1.41.0",
17
+ "next": "^16.3.4",
18
+ "react": "^19.2.8",
19
+ "react-dom": "^19.2.8",
20
+ "tailwind-merge": "^3.6.0",
21
+ "@radix-ui/react-slot": "^1.3.3"
22
+ },
23
+ "devDependencies": {
24
+ "@tailwindcss/postcss": "^4.3.3",
25
+ "@types/node": "^24.13.3",
26
+ "@types/react": "^19.2.18",
27
+ "@types/react-dom": "^19.2.7",
28
+ "eslint": "^10.10.0",
29
+ "eslint-config-next": "^16.3.4",
30
+ "tailwindcss": "^4.3.3",
31
+ "typescript": "^6.0.3",
32
+ "@eslint/compat": "^2.1.1"
33
+ },
34
+ "envVars": {
35
+ "NODE_ENV": "development",
36
+ "PORT": "3000"
20
37
  },
21
- "devDependencies": {
22
- "@tailwindcss/postcss": "^4",
23
- "@types/node": "^20",
24
- "@types/react": "^19",
25
- "@types/react-dom": "^19",
26
- "eslint": "^9",
27
- "eslint-config-next": "16.1.6",
28
- "tailwindcss": "^4",
29
- "typescript": "^5"
30
- },
31
- "envVars": { "NODE_ENV": "development", "PORT": "3000" },
32
38
  "templateFiles": ["app/page.tsx.hbs", "proxy.ts.hbs"]
33
39
  }
@@ -1,11 +1,11 @@
1
- import nextVitals from "eslint-config-next/core-web-vitals";
2
- import nextTs from "eslint-config-next/typescript";
3
- import { defineConfig, globalIgnores } from "eslint/config";
4
-
5
- const eslintConfig = defineConfig([
6
- ...nextVitals,
7
- ...nextTs,
8
- globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
9
- ]);
10
-
11
- export default eslintConfig;
1
+ import { fixupConfigRules } from "@eslint/compat";
2
+ import nextVitals from "eslint-config-next/core-web-vitals";
3
+ import nextTs from "eslint-config-next/typescript";
4
+ import { defineConfig, globalIgnores } from "eslint/config";
5
+
6
+ const eslintConfig = defineConfig([
7
+ ...fixupConfigRules([...nextVitals, ...nextTs]),
8
+ globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
9
+ ]);
10
+
11
+ export default eslintConfig;
@@ -1,23 +1,24 @@
1
- import { NextResponse, type NextRequest } from "next/server";
1
+ import { NextResponse } from "next/server";
2
2
 
3
3
  {{#if useAuth}}
4
+ import type { NextRequest } from "next/server";
4
5
  import { getSessionCookie } from "better-auth/cookies";
5
6
 
6
- export async function proxy(request: NextRequest) {
7
+ export function proxy(request: NextRequest) {
7
8
  const sessionCookie = getSessionCookie(request);
8
-
9
+
9
10
  if (!sessionCookie) {
10
11
  return NextResponse.redirect(new URL("/sign-in", request.url));
11
12
  }
12
-
13
- return NextResponse.next();
14
- }
15
-
13
+
14
+ return NextResponse.next();
15
+ }
16
+
16
17
  export const config = {
17
18
  matcher: ["/dashboard/:path*"],
18
19
  };
19
20
  {{else}}
20
- export function proxy(_request: NextRequest) {
21
+ export function proxy() {
21
22
  return NextResponse.next();
22
23
  }
23
24
  {{/if}}
@@ -1,21 +1,34 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2017",
4
- "lib": ["dom", "dom.iterable", "esnext"],
5
- "allowJs": true,
6
- "skipLibCheck": true,
7
- "strict": true,
8
- "noEmit": true,
9
- "esModuleInterop": true,
10
- "module": "esnext",
11
- "moduleResolution": "bundler",
12
- "resolveJsonModule": true,
13
- "isolatedModules": true,
14
- "jsx": "react-jsx",
15
- "incremental": true,
16
- "plugins": [{ "name": "next" }],
17
- "paths": { "@/*": ["./*"] }
18
- },
19
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts", "**/*.mts"],
20
- "exclude": ["node_modules"]
21
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./*"]
23
+ }
24
+ },
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ ".next/types/**/*.ts",
30
+ ".next/dev/types/**/*.ts",
31
+ "**/*.mts"
32
+ ],
33
+ "exclude": ["node_modules"]
34
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "tsx": true,
5
+ "tailwind": {
6
+ "config": "",
7
+ "css": "src/styles/app.css",
8
+ "baseColor": "neutral",
9
+ "cssVariables": true
10
+ },
11
+ "iconLibrary": "lucide",
12
+ "aliases": {
13
+ "components": "~/components",
14
+ "lib": "~/lib",
15
+ "ui": "~/components/ui",
16
+ "utils": "~/lib/utils"
17
+ }
18
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "id": "tanstack",
3
+ "name": "TanStack Start",
4
+ "description": "TanStack Start with TanStack Router, React 19, and Tailwind CSS v4",
5
+ "type": "base",
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "start": "srvx --prod -s ../client dist/server/server.js",
10
+ "preview": "vite preview",
11
+ "type:check": "tsc --noEmit",
12
+ "lint": "eslint src"
13
+ },
14
+ "dependencies": {
15
+ "@tanstack/react-query": "^5.102.8",
16
+ "@tanstack/react-query-devtools": "^5.102.8",
17
+ "@tanstack/react-router": "^1.170.36",
18
+ "@tanstack/react-router-devtools": "^1.167.2",
19
+ "@tanstack/react-router-ssr-query": "^1.167.2",
20
+ "@tanstack/react-start": "^1.168.53",
21
+ "class-variance-authority": "^0.7.1",
22
+ "clsx": "^2.1.1",
23
+ "lucide-react": "^1.41.0",
24
+ "react": "^19.2.8",
25
+ "react-dom": "^19.2.8",
26
+ "srvx": "^1.0.4",
27
+ "tailwind-merge": "^3.6.0"
28
+ },
29
+ "devDependencies": {
30
+ "@eslint/js": "^10.0.1",
31
+ "@tailwindcss/vite": "^4.3.3",
32
+ "@types/node": "^24.13.3",
33
+ "@types/react": "^19.2.18",
34
+ "@types/react-dom": "^19.2.7",
35
+ "@vitejs/plugin-react": "^6.1.1",
36
+ "eslint": "^10.10.0",
37
+ "tailwindcss": "^4.3.3",
38
+ "typescript": "^6.0.3",
39
+ "typescript-eslint": "^8.69.0",
40
+ "vite": "^8.3.0"
41
+ },
42
+ "envVars": {
43
+ "NODE_ENV": "development",
44
+ "PORT": "3000"
45
+ },
46
+ "templateFiles": [
47
+ "src/routes/index.tsx.hbs"
48
+ ]
49
+ }
@@ -0,0 +1,23 @@
1
+ import eslint from "@eslint/js";
2
+ import { defineConfig, globalIgnores } from "eslint/config";
3
+ import tseslint from "typescript-eslint";
4
+
5
+ const eslintConfig = defineConfig([
6
+ globalIgnores([
7
+ "dist/**",
8
+ ".output/**",
9
+ "src/routeTree.gen.ts",
10
+ ".tanstack/**",
11
+ "public/**",
12
+ ]),
13
+ eslint.configs.recommended,
14
+ ...tseslint.configs.recommended,
15
+ {
16
+ rules: {
17
+ "@typescript-eslint/no-explicit-any": "warn",
18
+ "no-console": "off",
19
+ },
20
+ },
21
+ ]);
22
+
23
+ export default eslintConfig;
@@ -0,0 +1,38 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.*
7
+ .yarn/*
8
+ !.yarn/patches
9
+ !.yarn/plugins
10
+ !.yarn/releases
11
+ !.yarn/versions
12
+
13
+ # testing
14
+ /coverage
15
+
16
+ # production
17
+ /build
18
+ /dist
19
+ /.output
20
+
21
+ # tanstack
22
+ /.tanstack
23
+
24
+ # misc
25
+ .DS_Store
26
+ *.pem
27
+
28
+ # debug
29
+ npm-debug.log*
30
+ yarn-debug.log*
31
+ yarn-error.log*
32
+ .pnpm-debug.log*
33
+
34
+ # env files (can opt-in for committing if needed)
35
+ .env*
36
+
37
+ # typescript
38
+ *.tsbuildinfo
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none">
2
+ <rect width="128" height="128" rx="24" fill="#0a0a0a"/>
3
+ <circle cx="64" cy="64" r="20" stroke="#38bdf8" stroke-width="3" fill="none"/>
4
+ <circle cx="64" cy="64" r="8" fill="#38bdf8"/>
5
+ <path d="M64 44V24M64 104V84M44 64H24M104 64H84" stroke="#38bdf8" stroke-width="3" stroke-linecap="round"/>
6
+ <path d="M49.9 49.9L35.8 35.8M92.1 92.1L78 78M78.1 49.9L92.2 35.8M35.9 78.1L49.9 92.2" stroke="#38bdf8" stroke-width="2" stroke-linecap="round"/>
7
+ </svg>
@@ -0,0 +1,51 @@
1
+ import * as React from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+
4
+ import { cn } from "~/lib/utils";
5
+
6
+ const buttonVariants = cva(
7
+ "inline-flex items-center justify-center whitespace-nowrap rounded-full text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:pointer-events-none disabled:opacity-50",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default:
12
+ "bg-slate-950 text-white shadow-sm hover:bg-slate-800",
13
+ outline:
14
+ "border border-slate-200 bg-white text-slate-900 hover:bg-slate-100",
15
+ ghost: "text-slate-700 hover:bg-slate-100 hover:text-slate-950",
16
+ },
17
+ size: {
18
+ default: "h-10 px-4 py-2",
19
+ sm: "h-9 px-3",
20
+ lg: "h-11 px-6 text-sm",
21
+ icon: "size-10",
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ variant: "default",
26
+ size: "default",
27
+ },
28
+ }
29
+ );
30
+
31
+ export interface ButtonProps
32
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
33
+ VariantProps<typeof buttonVariants> {}
34
+
35
+ function Button({
36
+ className,
37
+ variant,
38
+ size,
39
+ type = "button",
40
+ ...props
41
+ }: ButtonProps) {
42
+ return (
43
+ <button
44
+ type={type}
45
+ className={cn(buttonVariants({ variant, size }), className)}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ export { Button, buttonVariants };
@@ -0,0 +1,60 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "~/lib/utils";
4
+
5
+ function Card({
6
+ className,
7
+ ...props
8
+ }: React.HTMLAttributes<HTMLDivElement>) {
9
+ return (
10
+ <div
11
+ className={cn(
12
+ "rounded-3xl border border-slate-200/80 bg-white text-slate-950 shadow-sm",
13
+ className
14
+ )}
15
+ {...props}
16
+ />
17
+ );
18
+ }
19
+
20
+ function CardHeader({
21
+ className,
22
+ ...props
23
+ }: React.HTMLAttributes<HTMLDivElement>) {
24
+ return <div className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />;
25
+ }
26
+
27
+ function CardTitle({
28
+ className,
29
+ ...props
30
+ }: React.HTMLAttributes<HTMLHeadingElement>) {
31
+ return (
32
+ <h3
33
+ className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
34
+ {...props}
35
+ />
36
+ );
37
+ }
38
+
39
+ function CardDescription({
40
+ className,
41
+ ...props
42
+ }: React.HTMLAttributes<HTMLParagraphElement>) {
43
+ return <p className={cn("text-sm text-slate-600", className)} {...props} />;
44
+ }
45
+
46
+ function CardContent({
47
+ className,
48
+ ...props
49
+ }: React.HTMLAttributes<HTMLDivElement>) {
50
+ return <div className={cn("p-6 pt-0", className)} {...props} />;
51
+ }
52
+
53
+ function CardFooter({
54
+ className,
55
+ ...props
56
+ }: React.HTMLAttributes<HTMLDivElement>) {
57
+ return <div className={cn("flex items-center p-6 pt-0", className)} {...props} />;
58
+ }
59
+
60
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
@@ -0,0 +1,67 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "~/lib/utils";
4
+
5
+ function FieldGroup({
6
+ className,
7
+ ...props
8
+ }: React.HTMLAttributes<HTMLDivElement>) {
9
+ return <div className={cn("space-y-5", className)} {...props} />;
10
+ }
11
+
12
+ type FieldProps = React.HTMLAttributes<HTMLDivElement> & {
13
+ "data-invalid"?: boolean;
14
+ };
15
+
16
+ function Field({
17
+ className,
18
+ "data-invalid": dataInvalid,
19
+ ...props
20
+ }: FieldProps) {
21
+ return (
22
+ <div
23
+ data-invalid={dataInvalid}
24
+ className={cn("space-y-2", className)}
25
+ {...props}
26
+ />
27
+ );
28
+ }
29
+
30
+ function FieldLabel({
31
+ className,
32
+ ...props
33
+ }: React.LabelHTMLAttributes<HTMLLabelElement>) {
34
+ return (
35
+ <label
36
+ className={cn("text-sm font-medium text-slate-900", className)}
37
+ {...props}
38
+ />
39
+ );
40
+ }
41
+
42
+ function FieldDescription({
43
+ className,
44
+ ...props
45
+ }: React.HTMLAttributes<HTMLParagraphElement>) {
46
+ return <p className={cn("text-sm text-slate-500", className)} {...props} />;
47
+ }
48
+
49
+ type FieldErrorProps = React.HTMLAttributes<HTMLParagraphElement> & {
50
+ errors?: Array<{ message?: string } | undefined>;
51
+ };
52
+
53
+ function FieldError({ className, errors, ...props }: FieldErrorProps) {
54
+ const message = errors?.find((error) => error?.message)?.message;
55
+
56
+ if (!message) {
57
+ return null;
58
+ }
59
+
60
+ return (
61
+ <p className={cn("text-sm font-medium text-rose-600", className)} {...props}>
62
+ {message}
63
+ </p>
64
+ );
65
+ }
66
+
67
+ export { Field, FieldDescription, FieldError, FieldGroup, FieldLabel };
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "~/lib/utils";
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ className={cn(
10
+ "flex h-11 w-full rounded-2xl border border-slate-200 bg-white px-3 py-2 text-sm text-slate-950 shadow-sm transition-[color,box-shadow] outline-none placeholder:text-slate-400 focus-visible:border-sky-500 focus-visible:ring-[3px] focus-visible:ring-sky-500/20 disabled:cursor-not-allowed disabled:opacity-50",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ );
16
+ }
17
+
18
+ export { Input };
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,68 @@
1
+ /* eslint-disable */
2
+
3
+ // @ts-nocheck
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+
7
+ // This file was automatically generated by TanStack Router.
8
+ // You should NOT make any changes in this file as it will be overwritten.
9
+ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+ import { Route as rootRouteImport } from './routes/__root'
12
+ import { Route as IndexRouteImport } from './routes/index'
13
+
14
+ const IndexRoute = IndexRouteImport.update({
15
+ id: '/',
16
+ path: '/',
17
+ getParentRoute: () => rootRouteImport,
18
+ } as any)
19
+
20
+ export interface FileRoutesByFullPath {
21
+ '/': typeof IndexRoute
22
+ }
23
+ export interface FileRoutesByTo {
24
+ '/': typeof IndexRoute
25
+ }
26
+ export interface FileRoutesById {
27
+ __root__: typeof rootRouteImport
28
+ '/': typeof IndexRoute
29
+ }
30
+ export interface FileRouteTypes {
31
+ fileRoutesByFullPath: FileRoutesByFullPath
32
+ fullPaths: '/'
33
+ fileRoutesByTo: FileRoutesByTo
34
+ to: '/'
35
+ id: '__root__' | '/'
36
+ fileRoutesById: FileRoutesById
37
+ }
38
+ export interface RootRouteChildren {
39
+ IndexRoute: typeof IndexRoute
40
+ }
41
+
42
+ declare module '@tanstack/react-router' {
43
+ interface FileRoutesByPath {
44
+ '/': {
45
+ id: '/'
46
+ path: '/'
47
+ fullPath: '/'
48
+ preLoaderRoute: typeof IndexRouteImport
49
+ parentRoute: typeof rootRouteImport
50
+ }
51
+ }
52
+ }
53
+
54
+ const rootRouteChildren: RootRouteChildren = {
55
+ IndexRoute: IndexRoute,
56
+ }
57
+ export const routeTree = rootRouteImport
58
+ ._addFileChildren(rootRouteChildren)
59
+ ._addFileTypes<FileRouteTypes>()
60
+
61
+ import type { getRouter } from './router.tsx'
62
+ import type { createStart } from '@tanstack/react-start'
63
+ declare module '@tanstack/react-start' {
64
+ interface Register {
65
+ ssr: true
66
+ router: Awaited<ReturnType<typeof getRouter>>
67
+ }
68
+ }
@@ -0,0 +1,32 @@
1
+ import { QueryClient } from "@tanstack/react-query";
2
+ import { createRouter } from "@tanstack/react-router";
3
+ import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query";
4
+
5
+ import { routeTree } from "~/routeTree.gen";
6
+
7
+ export function getRouter() {
8
+ const queryClient = new QueryClient({
9
+ defaultOptions: {
10
+ queries: {
11
+ staleTime: 30_000,
12
+ },
13
+ },
14
+ });
15
+
16
+ const router = createRouter({
17
+ routeTree,
18
+ context: {
19
+ queryClient,
20
+ },
21
+ defaultPreload: "intent",
22
+ defaultPreloadStaleTime: 0,
23
+ scrollRestoration: true,
24
+ });
25
+
26
+ setupRouterSsrQueryIntegration({
27
+ router,
28
+ queryClient,
29
+ });
30
+
31
+ return router;
32
+ }