@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,65 @@
|
|
|
1
|
+
# ============================================
|
|
2
|
+
# Stage 1: Dependencies
|
|
3
|
+
# ============================================
|
|
4
|
+
FROM node:20-alpine AS deps
|
|
5
|
+
RUN apk add --no-cache libc6-compat
|
|
6
|
+
WORKDIR /app
|
|
7
|
+
|
|
8
|
+
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
|
9
|
+
|
|
10
|
+
# 复制 workspace 配置
|
|
11
|
+
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
|
|
12
|
+
COPY apps/web/package.json ./apps/web/
|
|
13
|
+
COPY packages/ui/package.json ./packages/ui/
|
|
14
|
+
COPY packages/utils/package.json ./packages/utils/
|
|
15
|
+
|
|
16
|
+
RUN pnpm install --frozen-lockfile
|
|
17
|
+
|
|
18
|
+
# ============================================
|
|
19
|
+
# Stage 2: Builder
|
|
20
|
+
# ============================================
|
|
21
|
+
FROM node:20-alpine AS builder
|
|
22
|
+
RUN apk add --no-cache libc6-compat
|
|
23
|
+
WORKDIR /app
|
|
24
|
+
|
|
25
|
+
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
|
26
|
+
|
|
27
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
28
|
+
COPY --from=deps /app/apps/web/node_modules ./apps/web/node_modules
|
|
29
|
+
COPY --from=deps /app/packages/ui/node_modules ./packages/ui/node_modules
|
|
30
|
+
COPY --from=deps /app/packages/utils/node_modules ./packages/utils/node_modules
|
|
31
|
+
COPY . .
|
|
32
|
+
|
|
33
|
+
ARG NEXT_PUBLIC_APP_URL
|
|
34
|
+
ARG NODE_ENV=production
|
|
35
|
+
|
|
36
|
+
ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL
|
|
37
|
+
ENV NODE_ENV=$NODE_ENV
|
|
38
|
+
ENV NEXT_TELEMETRY_DISABLED=1
|
|
39
|
+
|
|
40
|
+
RUN pnpm --filter @repo/web build
|
|
41
|
+
|
|
42
|
+
# ============================================
|
|
43
|
+
# Stage 3: Runner
|
|
44
|
+
# ============================================
|
|
45
|
+
FROM node:20-alpine AS runner
|
|
46
|
+
WORKDIR /app
|
|
47
|
+
|
|
48
|
+
ENV NODE_ENV=production
|
|
49
|
+
ENV NEXT_TELEMETRY_DISABLED=1
|
|
50
|
+
|
|
51
|
+
RUN addgroup --system --gid 1001 nodejs
|
|
52
|
+
RUN adduser --system --uid 1001 nextjs
|
|
53
|
+
|
|
54
|
+
COPY --from=builder /app/apps/web/.next/standalone ./
|
|
55
|
+
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
|
|
56
|
+
COPY --from=builder /app/apps/web/public ./apps/web/public
|
|
57
|
+
|
|
58
|
+
USER nextjs
|
|
59
|
+
|
|
60
|
+
EXPOSE 3000
|
|
61
|
+
|
|
62
|
+
ENV PORT=3000
|
|
63
|
+
ENV HOSTNAME="0.0.0.0"
|
|
64
|
+
|
|
65
|
+
CMD ["node", "apps/web/server.js"]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Next.js 子应用模板 (Monorepo Sub-App)
|
|
2
|
+
|
|
3
|
+
用于 Turborepo monorepo 项目中的 Next.js 子应用模板。
|
|
4
|
+
|
|
5
|
+
## 使用方式
|
|
6
|
+
|
|
7
|
+
脚手架会将此模板复制到 monorepo 项目的 `apps/` 目录下:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
my-monorepo/
|
|
11
|
+
├── apps/
|
|
12
|
+
│ ├── web/ ← 已有应用
|
|
13
|
+
│ └── my-new-app/ ← 由此模板生成
|
|
14
|
+
├── packages/
|
|
15
|
+
│ ├── ui/
|
|
16
|
+
│ └── utils/
|
|
17
|
+
├── turbo.json
|
|
18
|
+
└── package.json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 模板结构
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
src/
|
|
25
|
+
├── app/ # App Router 页面
|
|
26
|
+
├── components/ # 应用级组件
|
|
27
|
+
├── config/ # 应用配置
|
|
28
|
+
├── hooks/ # 自定义 Hooks
|
|
29
|
+
├── lib/ # 工具函数
|
|
30
|
+
├── styles/ # 全局样式
|
|
31
|
+
├── test/ # 测试配置
|
|
32
|
+
├── types/ # 类型定义
|
|
33
|
+
├── env.js # 环境变量验证
|
|
34
|
+
├── middleware.ts # Next.js 中间件
|
|
35
|
+
└── routes.ts # 路由配置
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 技术栈
|
|
39
|
+
|
|
40
|
+
- Next.js 16 (App Router, Standalone Output, Turbopack)
|
|
41
|
+
- React 19
|
|
42
|
+
- TypeScript (Strict Mode)
|
|
43
|
+
- Tailwind CSS v4 + shadcn/ui
|
|
44
|
+
- Biome + ESLint (代码规范)
|
|
45
|
+
- Vitest + Testing Library (测试)
|
|
46
|
+
- @t3-oss/env-nextjs (环境变量验证)
|
|
47
|
+
- Docker (容器化部署)
|
|
48
|
+
|
|
49
|
+
## 依赖说明
|
|
50
|
+
|
|
51
|
+
此模板依赖 monorepo 中的共享包:
|
|
52
|
+
- `@repo/ui` — 共享 UI 组件库
|
|
53
|
+
- `@repo/utils` — 共享工具函数
|
|
54
|
+
|
|
55
|
+
脚手架会根据实际项目的包命名前缀自动替换 `@repo`。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"rsc": true,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "src/styles/globals.css",
|
|
9
|
+
"baseColor": "zinc",
|
|
10
|
+
"cssVariables": true,
|
|
11
|
+
"prefix": ""
|
|
12
|
+
},
|
|
13
|
+
"iconLibrary": "lucide",
|
|
14
|
+
"aliases": {
|
|
15
|
+
"components": "@/components",
|
|
16
|
+
"utils": "@/lib/utils",
|
|
17
|
+
"ui": "@/components/ui",
|
|
18
|
+
"lib": "@/lib",
|
|
19
|
+
"hooks": "@/hooks"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -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,38 @@
|
|
|
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
|
+
// 转译 workspace 包
|
|
15
|
+
transpilePackages: ['@repo/ui', '@repo/utils'],
|
|
16
|
+
|
|
17
|
+
experimental: {
|
|
18
|
+
// 优化大型依赖包的 tree-shaking
|
|
19
|
+
optimizePackageImports: [
|
|
20
|
+
'lucide-react',
|
|
21
|
+
'@radix-ui/react-icons',
|
|
22
|
+
'@repo/ui',
|
|
23
|
+
],
|
|
24
|
+
// 为 next dev 启用文件系统缓存
|
|
25
|
+
turbopackFileSystemCacheForDev: true,
|
|
26
|
+
// 为 next build 启用文件系统缓存
|
|
27
|
+
turbopackFileSystemCacheForBuild: true,
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
images: {
|
|
31
|
+
remotePatterns: [
|
|
32
|
+
// 添加允许的远程图片域名
|
|
33
|
+
// { protocol: 'https', hostname: 'example.com' },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default nextConfig;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@repo/web",
|
|
3
|
+
"version": "0.0.1",
|
|
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:next": "next lint",
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"test": "vitest --run",
|
|
13
|
+
"test:watch": "vitest",
|
|
14
|
+
"test:coverage": "vitest --run --coverage"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@repo/ui": "workspace:*",
|
|
18
|
+
"@repo/utils": "workspace:*",
|
|
19
|
+
"@t3-oss/env-nextjs": "^0.11.1",
|
|
20
|
+
"lucide-react": "^0.483.0",
|
|
21
|
+
"next": "16.1.6",
|
|
22
|
+
"next-themes": "^0.4.6",
|
|
23
|
+
"react": "19.2.4",
|
|
24
|
+
"react-dom": "19.2.4",
|
|
25
|
+
"zod": "^3.24.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@tailwindcss/postcss": "^4",
|
|
29
|
+
"@tailwindcss/typography": "^0.5.19",
|
|
30
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
31
|
+
"@testing-library/react": "^16.3.1",
|
|
32
|
+
"@types/node": "^22",
|
|
33
|
+
"@types/react": "19.2.14",
|
|
34
|
+
"@types/react-dom": "19.2.3",
|
|
35
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
36
|
+
"eslint": "^9",
|
|
37
|
+
"eslint-config-next": "16.1.6",
|
|
38
|
+
"happy-dom": "^20.3.1",
|
|
39
|
+
"tailwindcss": "^4",
|
|
40
|
+
"tw-animate-css": "^1",
|
|
41
|
+
"typescript": "^5.8.3",
|
|
42
|
+
"vitest": "^4.0.16"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Badge,
|
|
3
|
+
Button,
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardFooter,
|
|
8
|
+
CardHeader,
|
|
9
|
+
CardTitle,
|
|
10
|
+
} from '@repo/ui';
|
|
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 shared UI components from @repo/ui.
|
|
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
|
+
<Card>
|
|
86
|
+
<CardHeader>
|
|
87
|
+
<CardTitle className="flex items-center gap-2">
|
|
88
|
+
<Zap className="h-5 w-5 text-primary" />
|
|
89
|
+
Starter
|
|
90
|
+
</CardTitle>
|
|
91
|
+
<CardDescription>Perfect for side projects</CardDescription>
|
|
92
|
+
</CardHeader>
|
|
93
|
+
<CardContent>
|
|
94
|
+
<div className="text-3xl font-bold">$0</div>
|
|
95
|
+
<p className="text-sm text-muted-foreground">Free forever</p>
|
|
96
|
+
<ul className="mt-4 space-y-2 text-sm">
|
|
97
|
+
<li className="flex items-center gap-2">
|
|
98
|
+
<Check className="h-4 w-4 text-primary" /> 3 projects
|
|
99
|
+
</li>
|
|
100
|
+
<li className="flex items-center gap-2">
|
|
101
|
+
<Check className="h-4 w-4 text-primary" /> Basic analytics
|
|
102
|
+
</li>
|
|
103
|
+
<li className="flex items-center gap-2">
|
|
104
|
+
<Check className="h-4 w-4 text-primary" /> Community support
|
|
105
|
+
</li>
|
|
106
|
+
</ul>
|
|
107
|
+
</CardContent>
|
|
108
|
+
<CardFooter>
|
|
109
|
+
<Button className="w-full">Get Started</Button>
|
|
110
|
+
</CardFooter>
|
|
111
|
+
</Card>
|
|
112
|
+
|
|
113
|
+
<Card className="border-primary">
|
|
114
|
+
<CardHeader>
|
|
115
|
+
<div className="flex items-center justify-between">
|
|
116
|
+
<CardTitle className="flex items-center gap-2">
|
|
117
|
+
<Star className="h-5 w-5 text-primary" />
|
|
118
|
+
Pro
|
|
119
|
+
</CardTitle>
|
|
120
|
+
<Badge>Popular</Badge>
|
|
121
|
+
</div>
|
|
122
|
+
<CardDescription>For growing teams</CardDescription>
|
|
123
|
+
</CardHeader>
|
|
124
|
+
<CardContent>
|
|
125
|
+
<div className="text-3xl font-bold">$29</div>
|
|
126
|
+
<p className="text-sm text-muted-foreground">/month</p>
|
|
127
|
+
<ul className="mt-4 space-y-2 text-sm">
|
|
128
|
+
<li className="flex items-center gap-2">
|
|
129
|
+
<Check className="h-4 w-4 text-primary" /> Unlimited projects
|
|
130
|
+
</li>
|
|
131
|
+
<li className="flex items-center gap-2">
|
|
132
|
+
<Check className="h-4 w-4 text-primary" /> Advanced analytics
|
|
133
|
+
</li>
|
|
134
|
+
<li className="flex items-center gap-2">
|
|
135
|
+
<Check className="h-4 w-4 text-primary" /> Priority support
|
|
136
|
+
</li>
|
|
137
|
+
</ul>
|
|
138
|
+
</CardContent>
|
|
139
|
+
<CardFooter>
|
|
140
|
+
<Button className="w-full">
|
|
141
|
+
Upgrade <ArrowRight className="ml-2 h-4 w-4" />
|
|
142
|
+
</Button>
|
|
143
|
+
</CardFooter>
|
|
144
|
+
</Card>
|
|
145
|
+
|
|
146
|
+
<Card>
|
|
147
|
+
<CardHeader>
|
|
148
|
+
<CardTitle className="flex items-center gap-2">
|
|
149
|
+
<Shield className="h-5 w-5 text-primary" />
|
|
150
|
+
Enterprise
|
|
151
|
+
</CardTitle>
|
|
152
|
+
<CardDescription>For large organizations</CardDescription>
|
|
153
|
+
</CardHeader>
|
|
154
|
+
<CardContent>
|
|
155
|
+
<div className="text-3xl font-bold">Custom</div>
|
|
156
|
+
<p className="text-sm text-muted-foreground">Contact us</p>
|
|
157
|
+
<ul className="mt-4 space-y-2 text-sm">
|
|
158
|
+
<li className="flex items-center gap-2">
|
|
159
|
+
<Check className="h-4 w-4 text-primary" /> Everything in Pro
|
|
160
|
+
</li>
|
|
161
|
+
<li className="flex items-center gap-2">
|
|
162
|
+
<Check className="h-4 w-4 text-primary" /> SSO & SAML
|
|
163
|
+
</li>
|
|
164
|
+
<li className="flex items-center gap-2">
|
|
165
|
+
<Check className="h-4 w-4 text-primary" /> Dedicated support
|
|
166
|
+
</li>
|
|
167
|
+
</ul>
|
|
168
|
+
</CardContent>
|
|
169
|
+
<CardFooter>
|
|
170
|
+
<Button variant="outline" className="w-full">
|
|
171
|
+
Contact Sales
|
|
172
|
+
</Button>
|
|
173
|
+
</CardFooter>
|
|
174
|
+
</Card>
|
|
175
|
+
</div>
|
|
176
|
+
</section>
|
|
177
|
+
|
|
178
|
+
{/* Typography Section */}
|
|
179
|
+
<section className="space-y-4">
|
|
180
|
+
<h2 className="text-xl font-semibold">Typography</h2>
|
|
181
|
+
<Card>
|
|
182
|
+
<CardContent className="pt-6 space-y-4">
|
|
183
|
+
<h1 className="text-4xl font-bold tracking-tight">Heading 1</h1>
|
|
184
|
+
<h2 className="text-3xl font-semibold tracking-tight">Heading 2</h2>
|
|
185
|
+
<h3 className="text-2xl font-semibold tracking-tight">Heading 3</h3>
|
|
186
|
+
<h4 className="text-xl font-semibold tracking-tight">Heading 4</h4>
|
|
187
|
+
<p className="leading-7">
|
|
188
|
+
This is a paragraph with <strong>bold text</strong>,{' '}
|
|
189
|
+
<em>italic text</em>, and{' '}
|
|
190
|
+
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
|
191
|
+
inline code
|
|
192
|
+
</code>
|
|
193
|
+
.
|
|
194
|
+
</p>
|
|
195
|
+
<p className="text-sm text-muted-foreground">
|
|
196
|
+
This is muted text, commonly used for descriptions and secondary
|
|
197
|
+
information.
|
|
198
|
+
</p>
|
|
199
|
+
</CardContent>
|
|
200
|
+
</Card>
|
|
201
|
+
</section>
|
|
202
|
+
|
|
203
|
+
{/* Color Palette */}
|
|
204
|
+
<section className="space-y-4">
|
|
205
|
+
<h2 className="text-xl font-semibold">Color Palette</h2>
|
|
206
|
+
<div className="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 gap-3">
|
|
207
|
+
{[
|
|
208
|
+
{
|
|
209
|
+
name: 'Primary',
|
|
210
|
+
bg: 'bg-primary',
|
|
211
|
+
fg: 'text-primary-foreground',
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: 'Secondary',
|
|
215
|
+
bg: 'bg-secondary',
|
|
216
|
+
fg: 'text-secondary-foreground',
|
|
217
|
+
},
|
|
218
|
+
{ name: 'Accent', bg: 'bg-accent', fg: 'text-accent-foreground' },
|
|
219
|
+
{ name: 'Muted', bg: 'bg-muted', fg: 'text-muted-foreground' },
|
|
220
|
+
{
|
|
221
|
+
name: 'Destructive',
|
|
222
|
+
bg: 'bg-destructive',
|
|
223
|
+
fg: 'text-destructive-foreground',
|
|
224
|
+
},
|
|
225
|
+
{ name: 'Card', bg: 'bg-card', fg: 'text-card-foreground' },
|
|
226
|
+
].map((color) => (
|
|
227
|
+
<div
|
|
228
|
+
key={color.name}
|
|
229
|
+
className={`${color.bg} ${color.fg} rounded-lg p-4 text-center text-sm font-medium`}
|
|
230
|
+
>
|
|
231
|
+
{color.name}
|
|
232
|
+
</div>
|
|
233
|
+
))}
|
|
234
|
+
</div>
|
|
235
|
+
</section>
|
|
236
|
+
|
|
237
|
+
{/* Icons */}
|
|
238
|
+
<section className="space-y-4">
|
|
239
|
+
<h2 className="text-xl font-semibold">Icons (Lucide)</h2>
|
|
240
|
+
<div className="flex flex-wrap gap-4">
|
|
241
|
+
{[Heart, Star, Zap, Shield, Mail, Bell, Settings, Check].map(
|
|
242
|
+
(Icon, i) => (
|
|
243
|
+
<div
|
|
244
|
+
key={i}
|
|
245
|
+
className="flex h-12 w-12 items-center justify-center rounded-lg border bg-card"
|
|
246
|
+
>
|
|
247
|
+
<Icon className="h-5 w-5 text-muted-foreground" />
|
|
248
|
+
</div>
|
|
249
|
+
)
|
|
250
|
+
)}
|
|
251
|
+
</div>
|
|
252
|
+
</section>
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
@@ -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,102 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Badge,
|
|
3
|
+
Button,
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
} from '@repo/ui';
|
|
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 Monorepo 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 monorepo starter with Turborepo, shared
|
|
27
|
+
packages, Tailwind CSS, shadcn/ui, and dark mode.
|
|
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>Monorepo Architecture</CardTitle>
|
|
53
|
+
<CardDescription>
|
|
54
|
+
Turborepo + pnpm workspaces with shared packages for UI components
|
|
55
|
+
and utilities.
|
|
56
|
+
</CardDescription>
|
|
57
|
+
</CardHeader>
|
|
58
|
+
<CardContent>
|
|
59
|
+
<p className="text-sm text-muted-foreground">
|
|
60
|
+
@repo/ui and @repo/utils packages ready to use across multiple
|
|
61
|
+
apps.
|
|
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>Shared Components</CardTitle>
|
|
87
|
+
<CardDescription>
|
|
88
|
+
Pre-built Button, Card, Badge components in @repo/ui, easily
|
|
89
|
+
extensible.
|
|
90
|
+
</CardDescription>
|
|
91
|
+
</CardHeader>
|
|
92
|
+
<CardContent>
|
|
93
|
+
<p className="text-sm text-muted-foreground">
|
|
94
|
+
Biome for linting and formatting, TypeScript strict mode,
|
|
95
|
+
consistent code quality.
|
|
96
|
+
</p>
|
|
97
|
+
</CardContent>
|
|
98
|
+
</Card>
|
|
99
|
+
</section>
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
@@ -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
|
+
}
|