@creativault/powerdata-cli 0.0.1
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/index.js +240 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
- package/template/nextjs_template/.dockerignore +12 -0
- package/template/nextjs_template/.editorconfig +15 -0
- package/template/nextjs_template/.env.example +43 -0
- package/template/nextjs_template/Dockerfile +57 -0
- package/template/nextjs_template/README.md +83 -0
- package/template/nextjs_template/_gitignore +55 -0
- package/template/nextjs_template/biome.json +58 -0
- package/template/nextjs_template/components.json +21 -0
- package/template/nextjs_template/eslint.config.mjs +16 -0
- package/template/nextjs_template/next.config.ts +31 -0
- package/template/nextjs_template/package.json +57 -0
- package/template/nextjs_template/postcss.config.mjs +8 -0
- package/template/nextjs_template/public/.gitkeep +0 -0
- package/template/nextjs_template/src/app/demo/page.tsx +258 -0
- package/template/nextjs_template/src/app/layout.tsx +46 -0
- package/template/nextjs_template/src/app/page.tsx +101 -0
- package/template/nextjs_template/src/components/layout/footer.tsx +11 -0
- package/template/nextjs_template/src/components/layout/header.tsx +25 -0
- package/template/nextjs_template/src/components/theme-provider.tsx +17 -0
- package/template/nextjs_template/src/components/theme-toggle.tsx +21 -0
- package/template/nextjs_template/src/components/ui/badge.tsx +35 -0
- package/template/nextjs_template/src/components/ui/button.tsx +56 -0
- package/template/nextjs_template/src/components/ui/card.tsx +82 -0
- package/template/nextjs_template/src/config/index.ts +1 -0
- package/template/nextjs_template/src/config/website.ts +9 -0
- package/template/nextjs_template/src/env.js +22 -0
- package/template/nextjs_template/src/hooks/index.ts +1 -0
- package/template/nextjs_template/src/lib/constants.ts +15 -0
- package/template/nextjs_template/src/lib/urls.ts +22 -0
- package/template/nextjs_template/src/lib/utils.ts +6 -0
- package/template/nextjs_template/src/middleware.ts +53 -0
- package/template/nextjs_template/src/routes.ts +47 -0
- package/template/nextjs_template/src/styles/globals.css +157 -0
- package/template/nextjs_template/src/test/setup.ts +1 -0
- package/template/nextjs_template/src/types/index.ts +25 -0
- package/template/nextjs_template/tsconfig.json +34 -0
- package/template/nextjs_template/vitest.config.mts +34 -0
- package/template/nextjs_template_monorepo/.dockerignore +11 -0
- package/template/nextjs_template_monorepo/.env.example +43 -0
- package/template/nextjs_template_monorepo/Dockerfile +65 -0
- package/template/nextjs_template_monorepo/README.md +55 -0
- package/template/nextjs_template_monorepo/components.json +21 -0
- package/template/nextjs_template_monorepo/eslint.config.mjs +16 -0
- package/template/nextjs_template_monorepo/next.config.ts +38 -0
- package/template/nextjs_template_monorepo/package.json +44 -0
- package/template/nextjs_template_monorepo/postcss.config.mjs +8 -0
- package/template/nextjs_template_monorepo/public/.gitkeep +0 -0
- package/template/nextjs_template_monorepo/src/app/demo/page.tsx +255 -0
- package/template/nextjs_template_monorepo/src/app/layout.tsx +46 -0
- package/template/nextjs_template_monorepo/src/app/page.tsx +102 -0
- package/template/nextjs_template_monorepo/src/components/layout/footer.tsx +11 -0
- package/template/nextjs_template_monorepo/src/components/layout/header.tsx +25 -0
- package/template/nextjs_template_monorepo/src/components/theme-provider.tsx +17 -0
- package/template/nextjs_template_monorepo/src/components/theme-toggle.tsx +21 -0
- package/template/nextjs_template_monorepo/src/config/index.ts +1 -0
- package/template/nextjs_template_monorepo/src/config/website.ts +13 -0
- package/template/nextjs_template_monorepo/src/env.js +22 -0
- package/template/nextjs_template_monorepo/src/hooks/index.ts +6 -0
- package/template/nextjs_template_monorepo/src/lib/utils.ts +2 -0
- package/template/nextjs_template_monorepo/src/middleware.ts +53 -0
- package/template/nextjs_template_monorepo/src/routes.ts +47 -0
- package/template/nextjs_template_monorepo/src/styles/globals.css +157 -0
- package/template/nextjs_template_monorepo/src/test/setup.ts +1 -0
- package/template/nextjs_template_monorepo/src/types/index.ts +30 -0
- package/template/nextjs_template_monorepo/tsconfig.json +34 -0
- package/template/nextjs_template_monorepo/vitest.config.mts +34 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import nextCoreWebVitals from 'eslint-config-next/core-web-vitals';
|
|
2
|
+
|
|
3
|
+
const eslintConfig = [
|
|
4
|
+
...nextCoreWebVitals,
|
|
5
|
+
{
|
|
6
|
+
ignores: [
|
|
7
|
+
'node_modules/**',
|
|
8
|
+
'.next/**',
|
|
9
|
+
'out/**',
|
|
10
|
+
'build/**',
|
|
11
|
+
'next-env.d.ts',
|
|
12
|
+
],
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export default eslintConfig;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { NextConfig } from 'next';
|
|
2
|
+
|
|
3
|
+
const nextConfig: NextConfig = {
|
|
4
|
+
// Standalone output for Docker deployment
|
|
5
|
+
output: 'standalone',
|
|
6
|
+
|
|
7
|
+
devIndicators: false,
|
|
8
|
+
|
|
9
|
+
// https://nextjs.org/docs/architecture/nextjs-compiler#remove-console
|
|
10
|
+
compiler: {
|
|
11
|
+
// removeConsole: process.env.NODE_ENV === 'production',
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
experimental: {
|
|
15
|
+
// 优化大型依赖包的 tree-shaking
|
|
16
|
+
optimizePackageImports: ['lucide-react', '@radix-ui/react-icons'],
|
|
17
|
+
// 为 next dev 启用文件系统缓存
|
|
18
|
+
turbopackFileSystemCacheForDev: true,
|
|
19
|
+
// 为 next build 启用文件系统缓存
|
|
20
|
+
turbopackFileSystemCacheForBuild: true,
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
images: {
|
|
24
|
+
remotePatterns: [
|
|
25
|
+
// 添加允许的远程图片域名
|
|
26
|
+
// { protocol: 'https', hostname: 'example.com' },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default nextConfig;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nextjs-template",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev --port 3000",
|
|
7
|
+
"build": "next build",
|
|
8
|
+
"start": "next start",
|
|
9
|
+
"lint": "biome check .",
|
|
10
|
+
"lint:fix": "biome check --fix --unsafe .",
|
|
11
|
+
"lint:next": "next lint",
|
|
12
|
+
"format": "biome format --write .",
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
14
|
+
"test": "vitest --run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"test:coverage": "vitest --run --coverage"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@radix-ui/react-slot": "^1.1.2",
|
|
20
|
+
"@t3-oss/env-nextjs": "^0.11.1",
|
|
21
|
+
"class-variance-authority": "^0.7.1",
|
|
22
|
+
"clsx": "^2.1.1",
|
|
23
|
+
"lucide-react": "^0.483.0",
|
|
24
|
+
"next": "16.1.6",
|
|
25
|
+
"next-themes": "^0.4.6",
|
|
26
|
+
"react": "19.2.4",
|
|
27
|
+
"react-dom": "19.2.4",
|
|
28
|
+
"tailwind-merge": "^3.0.2",
|
|
29
|
+
"zod": "^3.24.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@biomejs/biome": "^1.9.4",
|
|
33
|
+
"@tailwindcss/postcss": "^4",
|
|
34
|
+
"@tailwindcss/typography": "^0.5.19",
|
|
35
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
36
|
+
"@testing-library/react": "^16.3.1",
|
|
37
|
+
"@types/node": "^22",
|
|
38
|
+
"@types/react": "19.2.14",
|
|
39
|
+
"@types/react-dom": "19.2.3",
|
|
40
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
41
|
+
"eslint": "^9",
|
|
42
|
+
"eslint-config-next": "16.1.6",
|
|
43
|
+
"happy-dom": "^20.3.1",
|
|
44
|
+
"tailwindcss": "^4",
|
|
45
|
+
"tw-animate-css": "^1",
|
|
46
|
+
"typescript": "^5.8.3",
|
|
47
|
+
"vitest": "^4.0.16"
|
|
48
|
+
},
|
|
49
|
+
"pnpm": {
|
|
50
|
+
"overrides": {
|
|
51
|
+
"@types/react": "19.2.14",
|
|
52
|
+
"@types/react-dom": "19.2.3",
|
|
53
|
+
"react": "19.2.4",
|
|
54
|
+
"react-dom": "19.2.4"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { Badge } from '@/components/ui/badge';
|
|
2
|
+
import { Button } from '@/components/ui/button';
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardFooter,
|
|
8
|
+
CardHeader,
|
|
9
|
+
CardTitle,
|
|
10
|
+
} from '@/components/ui/card';
|
|
11
|
+
import {
|
|
12
|
+
ArrowRight,
|
|
13
|
+
Bell,
|
|
14
|
+
Check,
|
|
15
|
+
Heart,
|
|
16
|
+
Mail,
|
|
17
|
+
Settings,
|
|
18
|
+
Shield,
|
|
19
|
+
Star,
|
|
20
|
+
Zap,
|
|
21
|
+
} from 'lucide-react';
|
|
22
|
+
import type { Metadata } from 'next';
|
|
23
|
+
|
|
24
|
+
export const metadata: Metadata = {
|
|
25
|
+
title: 'Demo',
|
|
26
|
+
description: 'Component showcase and demo page',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default function DemoPage() {
|
|
30
|
+
return (
|
|
31
|
+
<div className="container mx-auto px-4 md:px-8 py-12 space-y-16">
|
|
32
|
+
{/* Page Header */}
|
|
33
|
+
<div className="space-y-2">
|
|
34
|
+
<h1 className="text-3xl font-bold tracking-tight">Component Demo</h1>
|
|
35
|
+
<p className="text-muted-foreground">
|
|
36
|
+
A showcase of available UI components and patterns.
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
{/* Buttons Section */}
|
|
41
|
+
<section className="space-y-4">
|
|
42
|
+
<h2 className="text-xl font-semibold">Buttons</h2>
|
|
43
|
+
<div className="flex flex-wrap gap-3">
|
|
44
|
+
<Button>Default</Button>
|
|
45
|
+
<Button variant="secondary">Secondary</Button>
|
|
46
|
+
<Button variant="destructive">Destructive</Button>
|
|
47
|
+
<Button variant="outline">Outline</Button>
|
|
48
|
+
<Button variant="ghost">Ghost</Button>
|
|
49
|
+
<Button variant="link">Link</Button>
|
|
50
|
+
</div>
|
|
51
|
+
<div className="flex flex-wrap gap-3">
|
|
52
|
+
<Button size="sm">Small</Button>
|
|
53
|
+
<Button size="default">Default</Button>
|
|
54
|
+
<Button size="lg">Large</Button>
|
|
55
|
+
<Button size="icon" aria-label="Settings">
|
|
56
|
+
<Settings className="h-4 w-4" />
|
|
57
|
+
</Button>
|
|
58
|
+
</div>
|
|
59
|
+
<div className="flex flex-wrap gap-3">
|
|
60
|
+
<Button>
|
|
61
|
+
<Mail className="mr-2 h-4 w-4" /> Login with Email
|
|
62
|
+
</Button>
|
|
63
|
+
<Button variant="outline">
|
|
64
|
+
<Bell className="mr-2 h-4 w-4" /> Notifications
|
|
65
|
+
</Button>
|
|
66
|
+
<Button disabled>Disabled</Button>
|
|
67
|
+
</div>
|
|
68
|
+
</section>
|
|
69
|
+
|
|
70
|
+
{/* Badges Section */}
|
|
71
|
+
<section className="space-y-4">
|
|
72
|
+
<h2 className="text-xl font-semibold">Badges</h2>
|
|
73
|
+
<div className="flex flex-wrap gap-3">
|
|
74
|
+
<Badge>Default</Badge>
|
|
75
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
76
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
77
|
+
<Badge variant="outline">Outline</Badge>
|
|
78
|
+
</div>
|
|
79
|
+
</section>
|
|
80
|
+
|
|
81
|
+
{/* Cards Section */}
|
|
82
|
+
<section className="space-y-4">
|
|
83
|
+
<h2 className="text-xl font-semibold">Cards</h2>
|
|
84
|
+
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
85
|
+
{/* Pricing Card */}
|
|
86
|
+
<Card>
|
|
87
|
+
<CardHeader>
|
|
88
|
+
<CardTitle className="flex items-center gap-2">
|
|
89
|
+
<Zap className="h-5 w-5 text-primary" />
|
|
90
|
+
Starter
|
|
91
|
+
</CardTitle>
|
|
92
|
+
<CardDescription>Perfect for side projects</CardDescription>
|
|
93
|
+
</CardHeader>
|
|
94
|
+
<CardContent>
|
|
95
|
+
<div className="text-3xl font-bold">$0</div>
|
|
96
|
+
<p className="text-sm text-muted-foreground">Free forever</p>
|
|
97
|
+
<ul className="mt-4 space-y-2 text-sm">
|
|
98
|
+
<li className="flex items-center gap-2">
|
|
99
|
+
<Check className="h-4 w-4 text-primary" /> 3 projects
|
|
100
|
+
</li>
|
|
101
|
+
<li className="flex items-center gap-2">
|
|
102
|
+
<Check className="h-4 w-4 text-primary" /> Basic analytics
|
|
103
|
+
</li>
|
|
104
|
+
<li className="flex items-center gap-2">
|
|
105
|
+
<Check className="h-4 w-4 text-primary" /> Community support
|
|
106
|
+
</li>
|
|
107
|
+
</ul>
|
|
108
|
+
</CardContent>
|
|
109
|
+
<CardFooter>
|
|
110
|
+
<Button className="w-full">Get Started</Button>
|
|
111
|
+
</CardFooter>
|
|
112
|
+
</Card>
|
|
113
|
+
|
|
114
|
+
{/* Pro Card */}
|
|
115
|
+
<Card className="border-primary">
|
|
116
|
+
<CardHeader>
|
|
117
|
+
<div className="flex items-center justify-between">
|
|
118
|
+
<CardTitle className="flex items-center gap-2">
|
|
119
|
+
<Star className="h-5 w-5 text-primary" />
|
|
120
|
+
Pro
|
|
121
|
+
</CardTitle>
|
|
122
|
+
<Badge>Popular</Badge>
|
|
123
|
+
</div>
|
|
124
|
+
<CardDescription>For growing teams</CardDescription>
|
|
125
|
+
</CardHeader>
|
|
126
|
+
<CardContent>
|
|
127
|
+
<div className="text-3xl font-bold">$29</div>
|
|
128
|
+
<p className="text-sm text-muted-foreground">/month</p>
|
|
129
|
+
<ul className="mt-4 space-y-2 text-sm">
|
|
130
|
+
<li className="flex items-center gap-2">
|
|
131
|
+
<Check className="h-4 w-4 text-primary" /> Unlimited projects
|
|
132
|
+
</li>
|
|
133
|
+
<li className="flex items-center gap-2">
|
|
134
|
+
<Check className="h-4 w-4 text-primary" /> Advanced analytics
|
|
135
|
+
</li>
|
|
136
|
+
<li className="flex items-center gap-2">
|
|
137
|
+
<Check className="h-4 w-4 text-primary" /> Priority support
|
|
138
|
+
</li>
|
|
139
|
+
</ul>
|
|
140
|
+
</CardContent>
|
|
141
|
+
<CardFooter>
|
|
142
|
+
<Button className="w-full">
|
|
143
|
+
Upgrade <ArrowRight className="ml-2 h-4 w-4" />
|
|
144
|
+
</Button>
|
|
145
|
+
</CardFooter>
|
|
146
|
+
</Card>
|
|
147
|
+
|
|
148
|
+
{/* Enterprise Card */}
|
|
149
|
+
<Card>
|
|
150
|
+
<CardHeader>
|
|
151
|
+
<CardTitle className="flex items-center gap-2">
|
|
152
|
+
<Shield className="h-5 w-5 text-primary" />
|
|
153
|
+
Enterprise
|
|
154
|
+
</CardTitle>
|
|
155
|
+
<CardDescription>For large organizations</CardDescription>
|
|
156
|
+
</CardHeader>
|
|
157
|
+
<CardContent>
|
|
158
|
+
<div className="text-3xl font-bold">Custom</div>
|
|
159
|
+
<p className="text-sm text-muted-foreground">Contact us</p>
|
|
160
|
+
<ul className="mt-4 space-y-2 text-sm">
|
|
161
|
+
<li className="flex items-center gap-2">
|
|
162
|
+
<Check className="h-4 w-4 text-primary" /> Everything in Pro
|
|
163
|
+
</li>
|
|
164
|
+
<li className="flex items-center gap-2">
|
|
165
|
+
<Check className="h-4 w-4 text-primary" /> SSO & SAML
|
|
166
|
+
</li>
|
|
167
|
+
<li className="flex items-center gap-2">
|
|
168
|
+
<Check className="h-4 w-4 text-primary" /> Dedicated support
|
|
169
|
+
</li>
|
|
170
|
+
</ul>
|
|
171
|
+
</CardContent>
|
|
172
|
+
<CardFooter>
|
|
173
|
+
<Button variant="outline" className="w-full">
|
|
174
|
+
Contact Sales
|
|
175
|
+
</Button>
|
|
176
|
+
</CardFooter>
|
|
177
|
+
</Card>
|
|
178
|
+
</div>
|
|
179
|
+
</section>
|
|
180
|
+
|
|
181
|
+
{/* Typography Section */}
|
|
182
|
+
<section className="space-y-4">
|
|
183
|
+
<h2 className="text-xl font-semibold">Typography</h2>
|
|
184
|
+
<Card>
|
|
185
|
+
<CardContent className="pt-6 space-y-4">
|
|
186
|
+
<h1 className="text-4xl font-bold tracking-tight">Heading 1</h1>
|
|
187
|
+
<h2 className="text-3xl font-semibold tracking-tight">Heading 2</h2>
|
|
188
|
+
<h3 className="text-2xl font-semibold tracking-tight">Heading 3</h3>
|
|
189
|
+
<h4 className="text-xl font-semibold tracking-tight">Heading 4</h4>
|
|
190
|
+
<p className="leading-7">
|
|
191
|
+
This is a paragraph with <strong>bold text</strong>,{' '}
|
|
192
|
+
<em>italic text</em>, and{' '}
|
|
193
|
+
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
|
194
|
+
inline code
|
|
195
|
+
</code>
|
|
196
|
+
.
|
|
197
|
+
</p>
|
|
198
|
+
<p className="text-sm text-muted-foreground">
|
|
199
|
+
This is muted text, commonly used for descriptions and secondary
|
|
200
|
+
information.
|
|
201
|
+
</p>
|
|
202
|
+
</CardContent>
|
|
203
|
+
</Card>
|
|
204
|
+
</section>
|
|
205
|
+
|
|
206
|
+
{/* Color Palette */}
|
|
207
|
+
<section className="space-y-4">
|
|
208
|
+
<h2 className="text-xl font-semibold">Color Palette</h2>
|
|
209
|
+
<div className="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 gap-3">
|
|
210
|
+
{[
|
|
211
|
+
{
|
|
212
|
+
name: 'Primary',
|
|
213
|
+
bg: 'bg-primary',
|
|
214
|
+
fg: 'text-primary-foreground',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'Secondary',
|
|
218
|
+
bg: 'bg-secondary',
|
|
219
|
+
fg: 'text-secondary-foreground',
|
|
220
|
+
},
|
|
221
|
+
{ name: 'Accent', bg: 'bg-accent', fg: 'text-accent-foreground' },
|
|
222
|
+
{ name: 'Muted', bg: 'bg-muted', fg: 'text-muted-foreground' },
|
|
223
|
+
{
|
|
224
|
+
name: 'Destructive',
|
|
225
|
+
bg: 'bg-destructive',
|
|
226
|
+
fg: 'text-destructive-foreground',
|
|
227
|
+
},
|
|
228
|
+
{ name: 'Card', bg: 'bg-card', fg: 'text-card-foreground' },
|
|
229
|
+
].map((color) => (
|
|
230
|
+
<div
|
|
231
|
+
key={color.name}
|
|
232
|
+
className={`${color.bg} ${color.fg} rounded-lg p-4 text-center text-sm font-medium`}
|
|
233
|
+
>
|
|
234
|
+
{color.name}
|
|
235
|
+
</div>
|
|
236
|
+
))}
|
|
237
|
+
</div>
|
|
238
|
+
</section>
|
|
239
|
+
|
|
240
|
+
{/* Icons */}
|
|
241
|
+
<section className="space-y-4">
|
|
242
|
+
<h2 className="text-xl font-semibold">Icons (Lucide)</h2>
|
|
243
|
+
<div className="flex flex-wrap gap-4">
|
|
244
|
+
{[Heart, Star, Zap, Shield, Mail, Bell, Settings, Check].map(
|
|
245
|
+
(Icon, i) => (
|
|
246
|
+
<div
|
|
247
|
+
key={i}
|
|
248
|
+
className="flex h-12 w-12 items-center justify-center rounded-lg border bg-card"
|
|
249
|
+
>
|
|
250
|
+
<Icon className="h-5 w-5 text-muted-foreground" />
|
|
251
|
+
</div>
|
|
252
|
+
)
|
|
253
|
+
)}
|
|
254
|
+
</div>
|
|
255
|
+
</section>
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Footer } from '@/components/layout/footer';
|
|
2
|
+
import { Header } from '@/components/layout/header';
|
|
3
|
+
import { ThemeProvider } from '@/components/theme-provider';
|
|
4
|
+
import type { Metadata } from 'next';
|
|
5
|
+
import { Geist, Geist_Mono } from 'next/font/google';
|
|
6
|
+
import '@/styles/globals.css';
|
|
7
|
+
|
|
8
|
+
const geistSans = Geist({
|
|
9
|
+
variable: '--font-geist-sans',
|
|
10
|
+
subsets: ['latin'],
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const geistMono = Geist_Mono({
|
|
14
|
+
variable: '--font-geist-mono',
|
|
15
|
+
subsets: ['latin'],
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const metadata: Metadata = {
|
|
19
|
+
title: {
|
|
20
|
+
default: 'MyApp',
|
|
21
|
+
template: '%s | MyApp',
|
|
22
|
+
},
|
|
23
|
+
description: 'A modern Next.js application',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default function RootLayout({
|
|
27
|
+
children,
|
|
28
|
+
}: Readonly<{
|
|
29
|
+
children: React.ReactNode;
|
|
30
|
+
}>) {
|
|
31
|
+
return (
|
|
32
|
+
<html lang="en" suppressHydrationWarning>
|
|
33
|
+
<body
|
|
34
|
+
className={`${geistSans.variable} ${geistMono.variable} min-h-screen bg-background font-sans antialiased`}
|
|
35
|
+
>
|
|
36
|
+
<ThemeProvider>
|
|
37
|
+
<div className="relative flex min-h-screen flex-col">
|
|
38
|
+
<Header />
|
|
39
|
+
<main className="flex-1">{children}</main>
|
|
40
|
+
<Footer />
|
|
41
|
+
</div>
|
|
42
|
+
</ThemeProvider>
|
|
43
|
+
</body>
|
|
44
|
+
</html>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Badge } from '@/components/ui/badge';
|
|
2
|
+
import { Button } from '@/components/ui/button';
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
} from '@/components/ui/card';
|
|
10
|
+
import { ArrowRight, Code2, Layers, Palette } from 'lucide-react';
|
|
11
|
+
import Link from 'next/link';
|
|
12
|
+
|
|
13
|
+
export default function HomePage() {
|
|
14
|
+
return (
|
|
15
|
+
<div className="container mx-auto px-4 md:px-8 py-16">
|
|
16
|
+
{/* Hero */}
|
|
17
|
+
<section className="flex flex-col items-center text-center space-y-6 py-16">
|
|
18
|
+
<Badge variant="secondary" className="text-sm">
|
|
19
|
+
Next.js Template
|
|
20
|
+
</Badge>
|
|
21
|
+
<h1 className="text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
|
|
22
|
+
Build Something
|
|
23
|
+
<span className="text-primary"> Amazing</span>
|
|
24
|
+
</h1>
|
|
25
|
+
<p className="max-w-[600px] text-lg text-muted-foreground">
|
|
26
|
+
A clean, modern Next.js starter with Tailwind CSS, shadcn/ui
|
|
27
|
+
components, dark mode, and best practices baked in.
|
|
28
|
+
</p>
|
|
29
|
+
<div className="flex gap-4">
|
|
30
|
+
<Button asChild size="lg">
|
|
31
|
+
<Link href="/demo">
|
|
32
|
+
View Demo <ArrowRight className="ml-2 h-4 w-4" />
|
|
33
|
+
</Link>
|
|
34
|
+
</Button>
|
|
35
|
+
<Button variant="outline" size="lg" asChild>
|
|
36
|
+
<a
|
|
37
|
+
href="https://nextjs.org/docs"
|
|
38
|
+
target="_blank"
|
|
39
|
+
rel="noopener noreferrer"
|
|
40
|
+
>
|
|
41
|
+
Documentation
|
|
42
|
+
</a>
|
|
43
|
+
</Button>
|
|
44
|
+
</div>
|
|
45
|
+
</section>
|
|
46
|
+
|
|
47
|
+
{/* Features */}
|
|
48
|
+
<section className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3 py-16">
|
|
49
|
+
<Card>
|
|
50
|
+
<CardHeader>
|
|
51
|
+
<Code2 className="h-10 w-10 text-primary mb-2" />
|
|
52
|
+
<CardTitle>TypeScript First</CardTitle>
|
|
53
|
+
<CardDescription>
|
|
54
|
+
Strict TypeScript configuration with path aliases and modern
|
|
55
|
+
module resolution.
|
|
56
|
+
</CardDescription>
|
|
57
|
+
</CardHeader>
|
|
58
|
+
<CardContent>
|
|
59
|
+
<p className="text-sm text-muted-foreground">
|
|
60
|
+
Biome for linting and formatting, ensuring consistent code quality
|
|
61
|
+
across the project.
|
|
62
|
+
</p>
|
|
63
|
+
</CardContent>
|
|
64
|
+
</Card>
|
|
65
|
+
|
|
66
|
+
<Card>
|
|
67
|
+
<CardHeader>
|
|
68
|
+
<Palette className="h-10 w-10 text-primary mb-2" />
|
|
69
|
+
<CardTitle>Theme System</CardTitle>
|
|
70
|
+
<CardDescription>
|
|
71
|
+
shadcn/ui design tokens with light and dark mode support out of
|
|
72
|
+
the box.
|
|
73
|
+
</CardDescription>
|
|
74
|
+
</CardHeader>
|
|
75
|
+
<CardContent>
|
|
76
|
+
<p className="text-sm text-muted-foreground">
|
|
77
|
+
CSS variables based theming with oklch colors for consistent,
|
|
78
|
+
accessible design.
|
|
79
|
+
</p>
|
|
80
|
+
</CardContent>
|
|
81
|
+
</Card>
|
|
82
|
+
|
|
83
|
+
<Card>
|
|
84
|
+
<CardHeader>
|
|
85
|
+
<Layers className="h-10 w-10 text-primary mb-2" />
|
|
86
|
+
<CardTitle>Component Library</CardTitle>
|
|
87
|
+
<CardDescription>
|
|
88
|
+
Pre-configured shadcn/ui with Button, Card, Badge and more ready
|
|
89
|
+
to use.
|
|
90
|
+
</CardDescription>
|
|
91
|
+
</CardHeader>
|
|
92
|
+
<CardContent>
|
|
93
|
+
<p className="text-sm text-muted-foreground">
|
|
94
|
+
Easily extend with additional shadcn/ui components using the CLI.
|
|
95
|
+
</p>
|
|
96
|
+
</CardContent>
|
|
97
|
+
</Card>
|
|
98
|
+
</section>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function Footer() {
|
|
2
|
+
return (
|
|
3
|
+
<footer className="border-t py-6 md:py-0">
|
|
4
|
+
<div className="container flex flex-col items-center justify-between gap-4 md:h-14 md:flex-row px-4 md:px-8">
|
|
5
|
+
<p className="text-sm text-muted-foreground">
|
|
6
|
+
Built with Next.js & Tailwind CSS
|
|
7
|
+
</p>
|
|
8
|
+
</div>
|
|
9
|
+
</footer>
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ThemeToggle } from '@/components/theme-toggle';
|
|
2
|
+
import Link from 'next/link';
|
|
3
|
+
|
|
4
|
+
export function Header() {
|
|
5
|
+
return (
|
|
6
|
+
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
7
|
+
<div className="container flex h-14 max-w-screen-2xl items-center px-4 md:px-8">
|
|
8
|
+
<Link href="/" className="mr-6 flex items-center space-x-2">
|
|
9
|
+
<span className="text-lg font-bold">MyApp</span>
|
|
10
|
+
</Link>
|
|
11
|
+
<nav className="flex flex-1 items-center space-x-6 text-sm font-medium">
|
|
12
|
+
<Link
|
|
13
|
+
href="/demo"
|
|
14
|
+
className="transition-colors hover:text-foreground/80 text-foreground/60"
|
|
15
|
+
>
|
|
16
|
+
Demo
|
|
17
|
+
</Link>
|
|
18
|
+
</nav>
|
|
19
|
+
<div className="flex items-center space-x-2">
|
|
20
|
+
<ThemeToggle />
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</header>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ThemeProvider as NextThemesProvider } from 'next-themes';
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
export function ThemeProvider({ children }: { children: ReactNode }) {
|
|
7
|
+
return (
|
|
8
|
+
<NextThemesProvider
|
|
9
|
+
attribute="class"
|
|
10
|
+
defaultTheme="system"
|
|
11
|
+
enableSystem
|
|
12
|
+
disableTransitionOnChange
|
|
13
|
+
>
|
|
14
|
+
{children}
|
|
15
|
+
</NextThemesProvider>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Button } from '@/components/ui/button';
|
|
4
|
+
import { Moon, Sun } from 'lucide-react';
|
|
5
|
+
import { useTheme } from 'next-themes';
|
|
6
|
+
|
|
7
|
+
export function ThemeToggle() {
|
|
8
|
+
const { theme, setTheme } = useTheme();
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Button
|
|
12
|
+
variant="ghost"
|
|
13
|
+
size="icon"
|
|
14
|
+
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
|
15
|
+
aria-label="Toggle theme"
|
|
16
|
+
>
|
|
17
|
+
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
|
18
|
+
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
|
19
|
+
</Button>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
|
|
5
|
+
const badgeVariants = cva(
|
|
6
|
+
'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default:
|
|
11
|
+
'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
|
|
12
|
+
secondary:
|
|
13
|
+
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
14
|
+
destructive:
|
|
15
|
+
'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80',
|
|
16
|
+
outline: 'text-foreground',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: {
|
|
20
|
+
variant: 'default',
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export interface BadgeProps
|
|
26
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
27
|
+
VariantProps<typeof badgeVariants> {}
|
|
28
|
+
|
|
29
|
+
function Badge({ className, variant, ...props }: BadgeProps) {
|
|
30
|
+
return (
|
|
31
|
+
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { Badge, badgeVariants };
|