create-pilotprojects-app 0.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.
- package/dist/helpers/copy.js +32 -0
- package/dist/helpers/install.js +18 -0
- package/dist/helpers/package-json.js +25 -0
- package/dist/index.js +54 -0
- package/dist/prompts.js +75 -0
- package/dist/scaffold.js +84 -0
- package/dist/types.js +1 -0
- package/package.json +39 -0
- package/templates/apps/mobile/.env.example +15 -0
- package/templates/apps/mobile/app/(auth)/login.tsx +86 -0
- package/templates/apps/mobile/app/(tabs)/_layout.tsx +10 -0
- package/templates/apps/mobile/app/(tabs)/index.tsx +30 -0
- package/templates/apps/mobile/app/_layout.tsx +58 -0
- package/templates/apps/mobile/app.config.ts +73 -0
- package/templates/apps/mobile/babel.config.js +9 -0
- package/templates/apps/mobile/eas.json +48 -0
- package/templates/apps/mobile/global.css +44 -0
- package/templates/apps/mobile/lib/supabase.ts +15 -0
- package/templates/apps/mobile/lib/trpc/client.ts +30 -0
- package/templates/apps/mobile/package.json +48 -0
- package/templates/apps/mobile/tsconfig.json +16 -0
- package/templates/apps/web/.env.development.example +22 -0
- package/templates/apps/web/app/(auth)/login/page.tsx +102 -0
- package/templates/apps/web/app/(dashboard)/dashboard/page.tsx +21 -0
- package/templates/apps/web/app/(dashboard)/layout.tsx +14 -0
- package/templates/apps/web/app/api/trpc/[trpc]/route.ts +32 -0
- package/templates/apps/web/app/globals.css +51 -0
- package/templates/apps/web/app/layout.tsx +25 -0
- package/templates/apps/web/lib/trpc/client.tsx +7 -0
- package/templates/apps/web/lib/trpc/provider.tsx +37 -0
- package/templates/apps/web/lib/trpc/server.ts +20 -0
- package/templates/apps/web/middleware.ts +10 -0
- package/templates/apps/web/package.json +44 -0
- package/templates/apps/web/postcss.config.js +6 -0
- package/templates/apps/web/sentry.client.config.ts +10 -0
- package/templates/apps/web/sentry.edge.config.ts +6 -0
- package/templates/apps/web/sentry.server.config.ts +7 -0
- package/templates/apps/web/tailwind.config.ts +12 -0
- package/templates/apps/web/tsconfig.json +16 -0
- package/templates/apps/web/types/css.d.ts +1 -0
- package/templates/base/.prettierrc.js +9 -0
- package/templates/base/_gitignore +30 -0
- package/templates/base/package.json +30 -0
- package/templates/base/turbo.json +33 -0
- package/templates/packages/api/package.json +23 -0
- package/templates/packages/api/src/features/auth/auth.router.ts +8 -0
- package/templates/packages/api/src/features/auth/auth.schema.ts +9 -0
- package/templates/packages/api/src/features/auth/auth.service.ts +24 -0
- package/templates/packages/api/src/features/user/user.router.ts +21 -0
- package/templates/packages/api/src/features/user/user.schema.ts +13 -0
- package/templates/packages/api/src/features/user/user.service.ts +41 -0
- package/templates/packages/api/src/index.ts +9 -0
- package/templates/packages/api/src/root.ts +10 -0
- package/templates/packages/api/src/trpc.ts +42 -0
- package/templates/packages/api/tsconfig.json +4 -0
- package/templates/packages/auth/package.json +26 -0
- package/templates/packages/auth/src/client.ts +8 -0
- package/templates/packages/auth/src/index.ts +3 -0
- package/templates/packages/auth/src/middleware.ts +25 -0
- package/templates/packages/auth/src/server.ts +15 -0
- package/templates/packages/auth/tsconfig.json +4 -0
- package/templates/packages/config/eslint/base.js +28 -0
- package/templates/packages/config/eslint/nextjs.js +10 -0
- package/templates/packages/config/eslint/react-native.js +18 -0
- package/templates/packages/config/package.json +13 -0
- package/templates/packages/config/typescript/base.json +17 -0
- package/templates/packages/config/typescript/nextjs.json +18 -0
- package/templates/packages/config/typescript/react-native.json +11 -0
- package/templates/packages/db/.env.example +1 -0
- package/templates/packages/db/drizzle.config.ts +13 -0
- package/templates/packages/db/package.json +28 -0
- package/templates/packages/db/src/index.ts +14 -0
- package/templates/packages/db/src/schema/index.ts +1 -0
- package/templates/packages/db/src/schema/users.ts +13 -0
- package/templates/packages/db/tsconfig.json +4 -0
- package/templates/packages/email/package.json +23 -0
- package/templates/packages/email/src/index.ts +2 -0
- package/templates/packages/email/src/resend.ts +8 -0
- package/templates/packages/email/src/templates/welcome.tsx +54 -0
- package/templates/packages/email/tsconfig.json +8 -0
- package/templates/packages/ui/package.json +38 -0
- package/templates/packages/ui/src/lib/utils.ts +6 -0
- package/templates/packages/ui/src/native/button.tsx +58 -0
- package/templates/packages/ui/src/native/card.tsx +41 -0
- package/templates/packages/ui/src/native/input.tsx +24 -0
- package/templates/packages/ui/src/native.d.ts +24 -0
- package/templates/packages/ui/src/tailwind-preset.ts +50 -0
- package/templates/packages/ui/src/web/button.tsx +49 -0
- package/templates/packages/ui/src/web/card.tsx +51 -0
- package/templates/packages/ui/src/web/input.tsx +22 -0
- package/templates/packages/ui/tsconfig.json +8 -0
- package/templates/packages/validators/package.json +20 -0
- package/templates/packages/validators/src/auth.ts +15 -0
- package/templates/packages/validators/src/index.ts +2 -0
- package/templates/packages/validators/src/user.ts +8 -0
- package/templates/packages/validators/tsconfig.json +4 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Body, Button, Container, Head, Heading,
|
|
3
|
+
Html, Preview, Section, Text,
|
|
4
|
+
} from "@react-email/components";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
|
|
7
|
+
interface WelcomeEmailProps {
|
|
8
|
+
displayName: string;
|
|
9
|
+
dashboardUrl: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function WelcomeEmail({ displayName, dashboardUrl }: WelcomeEmailProps) {
|
|
13
|
+
return (
|
|
14
|
+
<Html>
|
|
15
|
+
<Head />
|
|
16
|
+
<Preview>Welcome to {{PROJECT_NAME}}, {displayName}!</Preview>
|
|
17
|
+
<Body style={{ backgroundColor: "#f6f9fc", fontFamily: "sans-serif" }}>
|
|
18
|
+
<Container style={{ maxWidth: "560px", margin: "0 auto", padding: "40px 0" }}>
|
|
19
|
+
<Heading style={{ fontSize: "24px", color: "#1a1a1a" }}>
|
|
20
|
+
Welcome, {displayName}
|
|
21
|
+
</Heading>
|
|
22
|
+
<Text style={{ color: "#555", lineHeight: "1.6" }}>
|
|
23
|
+
Your account is ready. Click below to get started.
|
|
24
|
+
</Text>
|
|
25
|
+
<Section style={{ textAlign: "center", marginTop: "32px" }}>
|
|
26
|
+
<Button
|
|
27
|
+
href={dashboardUrl}
|
|
28
|
+
style={{
|
|
29
|
+
backgroundColor: "#3b82f6",
|
|
30
|
+
color: "#fff",
|
|
31
|
+
borderRadius: "6px",
|
|
32
|
+
padding: "12px 24px",
|
|
33
|
+
fontSize: "14px",
|
|
34
|
+
fontWeight: "600",
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
37
|
+
Go to Dashboard
|
|
38
|
+
</Button>
|
|
39
|
+
</Section>
|
|
40
|
+
<Text style={{ color: "#aaa", fontSize: "12px", marginTop: "32px" }}>
|
|
41
|
+
If you didn't create this account, you can safely ignore this email.
|
|
42
|
+
</Text>
|
|
43
|
+
</Container>
|
|
44
|
+
</Body>
|
|
45
|
+
</Html>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
WelcomeEmail.PreviewProps = {
|
|
50
|
+
displayName: "John Doe",
|
|
51
|
+
dashboardUrl: "https://yourapp.com/dashboard",
|
|
52
|
+
} satisfies WelcomeEmailProps;
|
|
53
|
+
|
|
54
|
+
export default WelcomeEmail;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PACKAGE_SCOPE}}/ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./tailwind-preset": "./src/tailwind-preset.ts",
|
|
8
|
+
"./web/*": "./src/web/*.tsx",
|
|
9
|
+
"./native/*": "./src/native/*.tsx",
|
|
10
|
+
"./lib/utils": "./src/lib/utils.ts"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"type-check": "tsc --noEmit",
|
|
14
|
+
"lint": "eslint src"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@radix-ui/react-slot": "^1.1.0",
|
|
18
|
+
"class-variance-authority": "^0.7.0",
|
|
19
|
+
"clsx": "^2.1.0",
|
|
20
|
+
"tailwind-merge": "^2.5.0",
|
|
21
|
+
"react": "^18.3.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"{{PACKAGE_SCOPE}}/config": "workspace:*",
|
|
25
|
+
"@types/react": "^18.3.0",
|
|
26
|
+
"@types/react-native": "^0.73.0",
|
|
27
|
+
"nativewind": "~4.1.0",
|
|
28
|
+
"tailwindcss": "^3.4.0",
|
|
29
|
+
"typescript": "^5.5.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react": "^18.3.0",
|
|
33
|
+
"react-native": "*"
|
|
34
|
+
},
|
|
35
|
+
"peerDependenciesMeta": {
|
|
36
|
+
"react-native": { "optional": true }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Pressable, Text, type PressableProps } from "react-native";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
|
|
6
|
+
interface ButtonProps extends PressableProps {
|
|
7
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost";
|
|
8
|
+
size?: "default" | "sm" | "lg";
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
textClassName?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function Button({
|
|
15
|
+
variant = "default",
|
|
16
|
+
size = "default",
|
|
17
|
+
children,
|
|
18
|
+
className,
|
|
19
|
+
textClassName,
|
|
20
|
+
disabled,
|
|
21
|
+
...props
|
|
22
|
+
}: ButtonProps) {
|
|
23
|
+
return (
|
|
24
|
+
<Pressable
|
|
25
|
+
disabled={disabled}
|
|
26
|
+
className={cn(
|
|
27
|
+
"flex-row items-center justify-center rounded-md",
|
|
28
|
+
variant === "default" && "bg-primary",
|
|
29
|
+
variant === "destructive" && "bg-destructive",
|
|
30
|
+
variant === "outline" && "border border-input bg-background",
|
|
31
|
+
variant === "secondary" && "bg-secondary",
|
|
32
|
+
variant === "ghost" && "bg-transparent",
|
|
33
|
+
size === "default" && "h-10 px-4",
|
|
34
|
+
size === "sm" && "h-9 px-3",
|
|
35
|
+
size === "lg" && "h-11 px-8",
|
|
36
|
+
disabled && "opacity-50",
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
<Text
|
|
42
|
+
className={cn(
|
|
43
|
+
"text-sm font-medium",
|
|
44
|
+
variant === "default" && "text-primary-foreground",
|
|
45
|
+
variant === "destructive" && "text-destructive-foreground",
|
|
46
|
+
variant === "outline" && "text-foreground",
|
|
47
|
+
variant === "secondary" && "text-secondary-foreground",
|
|
48
|
+
variant === "ghost" && "text-foreground",
|
|
49
|
+
textClassName,
|
|
50
|
+
)}
|
|
51
|
+
>
|
|
52
|
+
{children}
|
|
53
|
+
</Text>
|
|
54
|
+
</Pressable>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { Button };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { View, Text, type ViewProps } from "react-native";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
|
|
6
|
+
function Card({ className, ...props }: ViewProps & { className?: string }) {
|
|
7
|
+
return (
|
|
8
|
+
<View
|
|
9
|
+
className={cn("rounded-lg border border-border bg-card p-4 shadow-sm", className)}
|
|
10
|
+
{...props}
|
|
11
|
+
/>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function CardHeader({ className, ...props }: ViewProps & { className?: string }) {
|
|
16
|
+
return <View className={cn("mb-3 flex-col gap-1", className)} {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function CardTitle({ children, className }: { children: React.ReactNode; className?: string }) {
|
|
20
|
+
return (
|
|
21
|
+
<Text className={cn("text-xl font-semibold text-card-foreground", className)}>
|
|
22
|
+
{children}
|
|
23
|
+
</Text>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function CardDescription({ children, className }: { children: React.ReactNode; className?: string }) {
|
|
28
|
+
return (
|
|
29
|
+
<Text className={cn("text-sm text-muted-foreground", className)}>{children}</Text>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function CardContent({ className, ...props }: ViewProps & { className?: string }) {
|
|
34
|
+
return <View className={cn("mt-2", className)} {...props} />;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function CardFooter({ className, ...props }: ViewProps & { className?: string }) {
|
|
38
|
+
return <View className={cn("mt-4 flex-row items-center", className)} {...props} />;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { TextInput, type TextInputProps } from "react-native";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
|
|
6
|
+
interface InputProps extends TextInputProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function Input({ className, ...props }: InputProps) {
|
|
11
|
+
return (
|
|
12
|
+
<TextInput
|
|
13
|
+
className={cn(
|
|
14
|
+
"h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground",
|
|
15
|
+
props.editable === false && "opacity-50",
|
|
16
|
+
className,
|
|
17
|
+
)}
|
|
18
|
+
placeholderTextColor="#64748b"
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { Input };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "react-native";
|
|
2
|
+
|
|
3
|
+
// NativeWind adds className to all React Native components at runtime.
|
|
4
|
+
// Declare it here so TypeScript accepts it in {{PACKAGE_SCOPE}}/ui native components.
|
|
5
|
+
declare module "react-native" {
|
|
6
|
+
interface ViewProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
interface TextProps {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
interface PressableProps {
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
interface TextInputProps {
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
interface ImageProps {
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
interface ScrollViewProps {
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Config } from "tailwindcss";
|
|
2
|
+
|
|
3
|
+
export const preset = {
|
|
4
|
+
content: [],
|
|
5
|
+
theme: {
|
|
6
|
+
extend: {
|
|
7
|
+
colors: {
|
|
8
|
+
background: "hsl(var(--background))",
|
|
9
|
+
foreground: "hsl(var(--foreground))",
|
|
10
|
+
primary: {
|
|
11
|
+
DEFAULT: "hsl(var(--primary))",
|
|
12
|
+
foreground: "hsl(var(--primary-foreground))",
|
|
13
|
+
},
|
|
14
|
+
secondary: {
|
|
15
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
16
|
+
foreground: "hsl(var(--secondary-foreground))",
|
|
17
|
+
},
|
|
18
|
+
destructive: {
|
|
19
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
20
|
+
foreground: "hsl(var(--destructive-foreground))",
|
|
21
|
+
},
|
|
22
|
+
muted: {
|
|
23
|
+
DEFAULT: "hsl(var(--muted))",
|
|
24
|
+
foreground: "hsl(var(--muted-foreground))",
|
|
25
|
+
},
|
|
26
|
+
accent: {
|
|
27
|
+
DEFAULT: "hsl(var(--accent))",
|
|
28
|
+
foreground: "hsl(var(--accent-foreground))",
|
|
29
|
+
},
|
|
30
|
+
card: {
|
|
31
|
+
DEFAULT: "hsl(var(--card))",
|
|
32
|
+
foreground: "hsl(var(--card-foreground))",
|
|
33
|
+
},
|
|
34
|
+
border: "hsl(var(--border))",
|
|
35
|
+
input: "hsl(var(--input))",
|
|
36
|
+
ring: "hsl(var(--ring))",
|
|
37
|
+
},
|
|
38
|
+
borderRadius: {
|
|
39
|
+
sm: "calc(var(--radius) - 4px)",
|
|
40
|
+
md: "calc(var(--radius) - 2px)",
|
|
41
|
+
lg: "var(--radius)",
|
|
42
|
+
xl: "calc(var(--radius) + 4px)",
|
|
43
|
+
},
|
|
44
|
+
fontFamily: {
|
|
45
|
+
sans: ["var(--font-sans)"],
|
|
46
|
+
mono: ["var(--font-mono)"],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
} satisfies Omit<Config, "content"> & { content: [] };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../lib/utils";
|
|
6
|
+
|
|
7
|
+
const buttonVariants = cva(
|
|
8
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
13
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
14
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
15
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
16
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
17
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
18
|
+
},
|
|
19
|
+
size: {
|
|
20
|
+
default: "h-10 px-4 py-2",
|
|
21
|
+
sm: "h-9 rounded-md px-3",
|
|
22
|
+
lg: "h-11 rounded-md px-8",
|
|
23
|
+
icon: "h-10 w-10",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
variant: "default",
|
|
28
|
+
size: "default",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export interface ButtonProps
|
|
34
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
35
|
+
VariantProps<typeof buttonVariants> {
|
|
36
|
+
asChild?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
40
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
41
|
+
const Comp = asChild ? Slot : "button";
|
|
42
|
+
return (
|
|
43
|
+
<Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
|
|
44
|
+
);
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
Button.displayName = "Button";
|
|
48
|
+
|
|
49
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../lib/utils";
|
|
4
|
+
|
|
5
|
+
const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
6
|
+
({ className, ...props }, ref) => (
|
|
7
|
+
<div
|
|
8
|
+
ref={ref}
|
|
9
|
+
className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
|
|
10
|
+
{...props}
|
|
11
|
+
/>
|
|
12
|
+
),
|
|
13
|
+
);
|
|
14
|
+
Card.displayName = "Card";
|
|
15
|
+
|
|
16
|
+
const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
17
|
+
({ className, ...props }, ref) => (
|
|
18
|
+
<div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
|
|
19
|
+
),
|
|
20
|
+
);
|
|
21
|
+
CardHeader.displayName = "CardHeader";
|
|
22
|
+
|
|
23
|
+
const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
|
24
|
+
({ className, ...props }, ref) => (
|
|
25
|
+
<h3 ref={ref} className={cn("text-2xl font-semibold leading-none tracking-tight", className)} {...props} />
|
|
26
|
+
),
|
|
27
|
+
);
|
|
28
|
+
CardTitle.displayName = "CardTitle";
|
|
29
|
+
|
|
30
|
+
const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
|
|
31
|
+
({ className, ...props }, ref) => (
|
|
32
|
+
<p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
|
|
33
|
+
),
|
|
34
|
+
);
|
|
35
|
+
CardDescription.displayName = "CardDescription";
|
|
36
|
+
|
|
37
|
+
const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
38
|
+
({ className, ...props }, ref) => (
|
|
39
|
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
CardContent.displayName = "CardContent";
|
|
43
|
+
|
|
44
|
+
const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
45
|
+
({ className, ...props }, ref) => (
|
|
46
|
+
<div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
CardFooter.displayName = "CardFooter";
|
|
50
|
+
|
|
51
|
+
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../lib/utils";
|
|
4
|
+
|
|
5
|
+
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
|
|
6
|
+
|
|
7
|
+
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
8
|
+
({ className, type, ...props }, ref) => (
|
|
9
|
+
<input
|
|
10
|
+
type={type}
|
|
11
|
+
className={cn(
|
|
12
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
ref={ref}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
),
|
|
19
|
+
);
|
|
20
|
+
Input.displayName = "Input";
|
|
21
|
+
|
|
22
|
+
export { Input };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PACKAGE_SCOPE}}/validators",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/index.ts"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"type-check": "tsc --noEmit",
|
|
11
|
+
"lint": "eslint src"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"zod": "^3.23.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"{{PACKAGE_SCOPE}}/config": "workspace:*",
|
|
18
|
+
"typescript": "^5.5.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const signInSchema = z.object({
|
|
4
|
+
email: z.string().email(),
|
|
5
|
+
password: z.string().min(8),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export const signUpSchema = z.object({
|
|
9
|
+
email: z.string().email(),
|
|
10
|
+
password: z.string().min(8),
|
|
11
|
+
displayName: z.string().min(1).max(50),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type SignInInput = z.infer<typeof signInSchema>;
|
|
15
|
+
export type SignUpInput = z.infer<typeof signUpSchema>;
|