better-ts-stack 2.1.0 → 2.1.2
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.
- package/LICENSE +21 -21
- package/dist/args.js +9 -0
- package/dist/builder/configGenerator.js +3 -1
- package/dist/builder/moduleSelector.js +8 -1
- package/dist/builder/readmeGenerator.js +12 -0
- package/dist/builder/templateContext.js +24 -0
- package/dist/output/nextSteps.js +4 -0
- package/dist/prompts/index.js +3 -1
- package/dist/prompts/stack.js +9 -0
- package/dist/types/index.js +3 -0
- package/dist/ui/messages.js +3 -0
- package/package.json +71 -71
- package/templates/backend/express/.prettierignore +52 -52
- package/templates/backend/express/.prettierrc +16 -16
- package/templates/backend/express/config.json +8 -8
- package/templates/backend/express/gitignore +6 -1
- package/templates/backend/express/tsconfig.eslint.json +9 -9
- package/templates/backend/nestjs/.prettierignore +52 -52
- package/templates/backend/nestjs/config.json +10 -10
- package/templates/backend/nestjs/gitignore +6 -1
- package/templates/backend/nestjs/src/app.module.ts.hbs +1 -1
- package/templates/backend/nestjs/src/health/{health.controller.ts → health.controller.ts.hbs} +8 -0
- package/templates/backend/nestjs/tsconfig.eslint.json +9 -9
- package/templates/frontend/nextjs/app/globals.css +89 -89
- package/templates/frontend/nextjs/app/layout.tsx +34 -34
- package/templates/frontend/nextjs/components/ui/button.tsx +51 -51
- package/templates/frontend/nextjs/components/ui/card.tsx +60 -60
- package/templates/frontend/nextjs/components/ui/field.tsx +67 -67
- package/templates/frontend/nextjs/components/ui/input.tsx +18 -18
- package/templates/frontend/nextjs/config.json +35 -37
- package/templates/frontend/nextjs/eslint.config.mjs +11 -11
- package/templates/frontend/nextjs/gitignore +3 -0
- package/templates/frontend/nextjs/next.config.ts.hbs +12 -12
- package/templates/frontend/nextjs/postcss.config.mjs +7 -7
- package/templates/frontend/nextjs/public/file.svg +1 -1
- package/templates/frontend/nextjs/public/globe.svg +1 -1
- package/templates/frontend/nextjs/public/window.svg +1 -1
- package/templates/frontend/tanstack/components.json +18 -18
- package/templates/frontend/tanstack/config.json +15 -15
- package/templates/frontend/tanstack/eslint.config.mjs +23 -23
- package/templates/frontend/tanstack/gitignore +42 -39
- package/templates/frontend/tanstack/public/favicon.svg +7 -7
- package/templates/frontend/tanstack/src/components/ui/button.tsx +51 -51
- package/templates/frontend/tanstack/src/components/ui/card.tsx +60 -60
- package/templates/frontend/tanstack/src/components/ui/field.tsx +67 -67
- package/templates/frontend/tanstack/src/components/ui/input.tsx +18 -18
- package/templates/frontend/tanstack/src/lib/utils.ts +6 -6
- package/templates/frontend/tanstack/src/router.tsx +31 -31
- package/templates/frontend/tanstack/src/routes/__root.tsx +69 -69
- package/templates/frontend/tanstack/tsconfig.json +22 -22
- package/templates/frontend/tanstack/vite.config.ts +5 -4
- package/templates/modules/agents/AGENTS.md.hbs +237 -0
- package/templates/modules/agents/CLAUDE.md +1 -0
- package/templates/modules/agents/config.json +10 -0
- package/templates/modules/auth/express/config.json +1 -1
- package/templates/modules/auth/express/src/lib/jwt.ts.hbs +27 -27
- package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +1 -2
- package/templates/modules/auth/nestjs/config.json +1 -1
- package/templates/modules/auth/nextjs/app/api/auth/[...all]/route.ts +4 -4
- package/templates/modules/auth/nextjs/config.json +18 -18
- package/templates/modules/auth/nextjs/lib/auth-client.ts +3 -3
- package/templates/{frontend/nextjs/proxy.ts.hbs → modules/auth/nextjs/proxy.ts} +1 -8
- package/templates/modules/auth/tanstack/config.json +18 -18
- package/templates/modules/auth/tanstack/src/lib/auth-client.ts +2 -2
- package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +8 -8
- package/templates/modules/auth/tanstack/src/lib/auth.ts.hbs +37 -37
- package/templates/modules/auth/tanstack/src/routes/api/auth/$.ts +15 -15
- package/templates/modules/auth/tanstack/src/routes/dashboard.tsx +110 -110
- package/templates/modules/auth/tanstack/src/routes/sign-in.tsx +36 -36
- package/templates/modules/auth/tanstack/src/routes/sign-up.tsx +36 -36
- package/templates/modules/ci/.github/workflows/ci.yml.hbs +43 -0
- package/templates/modules/ci/config.json +10 -0
- package/templates/modules/docker/.dockerignore +3 -0
- package/templates/modules/docker/config.json +15 -15
- package/templates/modules/docker/docker-compose.yml.hbs +1 -1
- package/templates/modules/drizzle/express/config.json +26 -26
- package/templates/modules/drizzle/nestjs/config.json +26 -26
- package/templates/modules/drizzle/nextjs/config.json +26 -26
- package/templates/modules/drizzle/nextjs/drizzle.config.ts +13 -13
- package/templates/modules/drizzle/tanstack/config.json +26 -26
- package/templates/modules/drizzle/tanstack/drizzle.config.ts +12 -12
- package/templates/modules/drizzle/tanstack/src/lib/db.ts +13 -13
- package/templates/modules/mongoose/express/config.json +15 -15
- package/templates/modules/mongoose/express/src/lib/db.ts +43 -43
- package/templates/modules/mongoose/express/src/models/User.ts +48 -48
- package/templates/modules/mongoose/nestjs/config.json +15 -15
- package/templates/modules/mongoose/nextjs/config.json +15 -15
- package/templates/modules/mongoose/nextjs/models/User.ts +48 -48
- package/templates/modules/mongoose/tanstack/config.json +16 -16
- package/templates/modules/mongoose/tanstack/src/models/User.ts +48 -48
- package/templates/modules/prisma/express/config.json +27 -27
- package/templates/modules/prisma/express/prisma/schema.prisma +23 -23
- package/templates/modules/prisma/express/prisma.config.ts +4 -2
- package/templates/modules/prisma/nestjs/config.json +27 -27
- package/templates/modules/prisma/nestjs/prisma.config.ts +4 -2
- package/templates/modules/prisma/nextjs/config.json +28 -28
- package/templates/modules/prisma/nextjs/lib/prisma.ts +18 -18
- package/templates/modules/prisma/nextjs/prisma.config.ts +14 -12
- package/templates/modules/prisma/tanstack/config.json +28 -28
- package/templates/modules/prisma/tanstack/prisma/schema.prisma.hbs +91 -91
- package/templates/modules/prisma/tanstack/prisma.config.ts +14 -12
- package/templates/modules/prisma/tanstack/src/lib/prisma.ts +17 -17
- package/templates/modules/rate-limit/express/config.json +1 -1
- package/templates/modules/rate-limit/express/src/middleware/rateLimit.ts +3 -1
- package/templates/modules/vscode/.vscode/extensions.json.hbs +29 -0
- package/templates/modules/vscode/.vscode/settings.json.hbs +22 -0
- package/templates/modules/vscode/config.json +10 -0
|
@@ -1,51 +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 };
|
|
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 };
|
|
@@ -1,60 +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 };
|
|
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 };
|
|
@@ -1,67 +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 };
|
|
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 };
|
|
@@ -1,18 +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 };
|
|
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 };
|
|
@@ -1,6 +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
|
-
}
|
|
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
|
+
}
|
|
@@ -1,32 +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;
|
|
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
32
|
}
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
2
|
-
import {
|
|
3
|
-
HeadContent,
|
|
4
|
-
Outlet,
|
|
5
|
-
Scripts,
|
|
6
|
-
createRootRouteWithContext,
|
|
7
|
-
} from "@tanstack/react-router";
|
|
8
|
-
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
|
9
|
-
import type { QueryClient } from "@tanstack/react-query";
|
|
10
|
-
import * as React from "react";
|
|
11
|
-
|
|
12
|
-
import appCss from "~/styles/app.css?url";
|
|
13
|
-
|
|
14
|
-
export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({
|
|
15
|
-
head: () => ({
|
|
16
|
-
meta: [
|
|
17
|
-
{
|
|
18
|
-
charSet: "utf-8",
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
name: "viewport",
|
|
22
|
-
content: "width=device-width, initial-scale=1",
|
|
23
|
-
},
|
|
24
|
-
],
|
|
25
|
-
links: [
|
|
26
|
-
{
|
|
27
|
-
rel: "icon",
|
|
28
|
-
type: "image/svg+xml",
|
|
29
|
-
href: "/favicon.svg",
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
}),
|
|
33
|
-
component: RootComponent,
|
|
34
|
-
notFoundComponent: () => <NotFound />,
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
function RootComponent() {
|
|
38
|
-
return (
|
|
39
|
-
<RootDocument>
|
|
40
|
-
<Outlet />
|
|
41
|
-
</RootDocument>
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
46
|
-
return (
|
|
47
|
-
<html lang="en">
|
|
48
|
-
<head>
|
|
49
|
-
<HeadContent />
|
|
50
|
-
<link rel="stylesheet" href={appCss} />
|
|
51
|
-
</head>
|
|
52
|
-
<body>
|
|
53
|
-
{children}
|
|
54
|
-
<TanStackRouterDevtools />
|
|
55
|
-
<Scripts />
|
|
56
|
-
</body>
|
|
57
|
-
</html>
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function NotFound() {
|
|
62
|
-
return (
|
|
63
|
-
<div className="flex min-h-[50vh] items-center justify-center">
|
|
64
|
-
<div className="text-center">
|
|
65
|
-
<h1 className="text-4xl font-bold">404</h1>
|
|
66
|
-
<p className="mt-2 text-muted-foreground">Page not found</p>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
)
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
import {
|
|
3
|
+
HeadContent,
|
|
4
|
+
Outlet,
|
|
5
|
+
Scripts,
|
|
6
|
+
createRootRouteWithContext,
|
|
7
|
+
} from "@tanstack/react-router";
|
|
8
|
+
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
|
9
|
+
import type { QueryClient } from "@tanstack/react-query";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
|
|
12
|
+
import appCss from "~/styles/app.css?url";
|
|
13
|
+
|
|
14
|
+
export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({
|
|
15
|
+
head: () => ({
|
|
16
|
+
meta: [
|
|
17
|
+
{
|
|
18
|
+
charSet: "utf-8",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "viewport",
|
|
22
|
+
content: "width=device-width, initial-scale=1",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
links: [
|
|
26
|
+
{
|
|
27
|
+
rel: "icon",
|
|
28
|
+
type: "image/svg+xml",
|
|
29
|
+
href: "/favicon.svg",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
}),
|
|
33
|
+
component: RootComponent,
|
|
34
|
+
notFoundComponent: () => <NotFound />,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
function RootComponent() {
|
|
38
|
+
return (
|
|
39
|
+
<RootDocument>
|
|
40
|
+
<Outlet />
|
|
41
|
+
</RootDocument>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
46
|
+
return (
|
|
47
|
+
<html lang="en">
|
|
48
|
+
<head>
|
|
49
|
+
<HeadContent />
|
|
50
|
+
<link rel="stylesheet" href={appCss} />
|
|
51
|
+
</head>
|
|
52
|
+
<body>
|
|
53
|
+
{children}
|
|
54
|
+
<TanStackRouterDevtools />
|
|
55
|
+
<Scripts />
|
|
56
|
+
</body>
|
|
57
|
+
</html>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function NotFound() {
|
|
62
|
+
return (
|
|
63
|
+
<div className="flex min-h-[50vh] items-center justify-center">
|
|
64
|
+
<div className="text-center">
|
|
65
|
+
<h1 className="text-4xl font-bold">404</h1>
|
|
66
|
+
<p className="mt-2 text-muted-foreground">Page not found</p>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
)
|
|
70
70
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
{
|
|
2
|
-
"include": ["**/*.ts", "**/*.tsx"],
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"strict": true,
|
|
5
|
-
"esModuleInterop": true,
|
|
6
|
-
"jsx": "react-jsx",
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"moduleResolution": "Bundler",
|
|
9
|
-
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
10
|
-
"isolatedModules": true,
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
|
-
"skipLibCheck": true,
|
|
13
|
-
"target": "ES2022",
|
|
14
|
-
"allowJs": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
"forceConsistentCasingInFileNames": true,
|
|
17
|
-
"paths": {
|
|
18
|
-
"~/*": ["./src/*"]
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"exclude": ["node_modules"]
|
|
22
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"include": ["**/*.ts", "**/*.tsx"],
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"strict": true,
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"moduleResolution": "Bundler",
|
|
9
|
+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"target": "ES2022",
|
|
14
|
+
"allowJs": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
"forceConsistentCasingInFileNames": true,
|
|
17
|
+
"paths": {
|
|
18
|
+
"~/*": ["./src/*"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"exclude": ["node_modules"]
|
|
22
|
+
}
|