create-rykira-app 1.0.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/README.md +50 -0
- package/bin/cli.js +149 -0
- package/deployment.md +168 -0
- package/how-to-deploy-package.md +132 -0
- package/package.json +23 -0
- package/starter-usage.md +132 -0
- package/template/.dockerignore +11 -0
- package/template/.env.example +20 -0
- package/template/.eslintrc.js +13 -0
- package/template/.github/workflows/ci.yml +60 -0
- package/template/.prettierignore +7 -0
- package/template/.prettierrc +11 -0
- package/template/README.md +21 -0
- package/template/apps/admin/app/favicon.ico +0 -0
- package/template/apps/admin/app/layout.tsx +30 -0
- package/template/apps/admin/app/page.tsx +19 -0
- package/template/apps/admin/components/.gitkeep +0 -0
- package/template/apps/admin/components/theme-provider.tsx +71 -0
- package/template/apps/admin/components.json +23 -0
- package/template/apps/admin/eslint.config.js +4 -0
- package/template/apps/admin/hooks/.gitkeep +0 -0
- package/template/apps/admin/lib/.gitkeep +0 -0
- package/template/apps/admin/next-env.d.ts +6 -0
- package/template/apps/admin/next.config.mjs +6 -0
- package/template/apps/admin/nixpacks.toml +8 -0
- package/template/apps/admin/package.json +32 -0
- package/template/apps/admin/postcss.config.mjs +1 -0
- package/template/apps/admin/tsconfig.json +23 -0
- package/template/apps/api/nixpacks.toml +8 -0
- package/template/apps/api/package.json +32 -0
- package/template/apps/api/src/index.ts +11 -0
- package/template/apps/api/src/server.ts +21 -0
- package/template/apps/api/tsconfig.json +18 -0
- package/template/apps/web/app/favicon.ico +0 -0
- package/template/apps/web/app/layout.tsx +30 -0
- package/template/apps/web/app/page.tsx +19 -0
- package/template/apps/web/components/.gitkeep +0 -0
- package/template/apps/web/components/theme-provider.tsx +71 -0
- package/template/apps/web/components.json +23 -0
- package/template/apps/web/eslint.config.js +4 -0
- package/template/apps/web/hooks/.gitkeep +0 -0
- package/template/apps/web/lib/.gitkeep +0 -0
- package/template/apps/web/next-env.d.ts +6 -0
- package/template/apps/web/next.config.mjs +6 -0
- package/template/apps/web/nixpacks.toml +8 -0
- package/template/apps/web/package.json +32 -0
- package/template/apps/web/postcss.config.mjs +1 -0
- package/template/apps/web/tsconfig.json +23 -0
- package/template/infrastructure/docker/Dockerfile.admin +36 -0
- package/template/infrastructure/docker/Dockerfile.api +36 -0
- package/template/infrastructure/docker/Dockerfile.web +48 -0
- package/template/infrastructure/docker/compose.dev.yml +50 -0
- package/template/infrastructure/docker/compose.prod.yml +119 -0
- package/template/infrastructure/scripts/deploy.sh +3 -0
- package/template/infrastructure/scripts/dev.sh +5 -0
- package/template/infrastructure/scripts/init-traefik.sh +10 -0
- package/template/infrastructure/scripts/setup-server.sh +25 -0
- package/template/infrastructure/scripts/update.sh +7 -0
- package/template/infrastructure/traefik/acme.json +0 -0
- package/template/infrastructure/traefik/dynamic.yml +23 -0
- package/template/infrastructure/traefik/traefik.yml +26 -0
- package/template/package.json +25 -0
- package/template/packages/eslint-config/README.md +3 -0
- package/template/packages/eslint-config/base.js +32 -0
- package/template/packages/eslint-config/next.js +51 -0
- package/template/packages/eslint-config/package.json +26 -0
- package/template/packages/eslint-config/react-internal.js +41 -0
- package/template/packages/typescript-config/README.md +3 -0
- package/template/packages/typescript-config/base.json +20 -0
- package/template/packages/typescript-config/nextjs.json +13 -0
- package/template/packages/typescript-config/package.json +9 -0
- package/template/packages/typescript-config/react-library.json +8 -0
- package/template/packages/ui/components.json +23 -0
- package/template/packages/ui/eslint.config.js +4 -0
- package/template/packages/ui/package.json +52 -0
- package/template/packages/ui/postcss.config.mjs +6 -0
- package/template/packages/ui/src/components/.gitkeep +0 -0
- package/template/packages/ui/src/components/accordion.tsx +74 -0
- package/template/packages/ui/src/components/alert-dialog.tsx +187 -0
- package/template/packages/ui/src/components/alert.tsx +76 -0
- package/template/packages/ui/src/components/aspect-ratio.tsx +22 -0
- package/template/packages/ui/src/components/avatar.tsx +109 -0
- package/template/packages/ui/src/components/badge.tsx +52 -0
- package/template/packages/ui/src/components/breadcrumb.tsx +125 -0
- package/template/packages/ui/src/components/button-group.tsx +87 -0
- package/template/packages/ui/src/components/button.tsx +60 -0
- package/template/packages/ui/src/components/calendar.tsx +221 -0
- package/template/packages/ui/src/components/card.tsx +103 -0
- package/template/packages/ui/src/components/carousel.tsx +242 -0
- package/template/packages/ui/src/components/chart.tsx +356 -0
- package/template/packages/ui/src/components/checkbox.tsx +29 -0
- package/template/packages/ui/src/components/collapsible.tsx +21 -0
- package/template/packages/ui/src/components/combobox.tsx +297 -0
- package/template/packages/ui/src/components/command.tsx +196 -0
- package/template/packages/ui/src/components/context-menu.tsx +271 -0
- package/template/packages/ui/src/components/dialog.tsx +157 -0
- package/template/packages/ui/src/components/direction.tsx +6 -0
- package/template/packages/ui/src/components/drawer.tsx +131 -0
- package/template/packages/ui/src/components/dropdown-menu.tsx +268 -0
- package/template/packages/ui/src/components/empty.tsx +101 -0
- package/template/packages/ui/src/components/field.tsx +238 -0
- package/template/packages/ui/src/components/hover-card.tsx +51 -0
- package/template/packages/ui/src/components/input-group.tsx +158 -0
- package/template/packages/ui/src/components/input-otp.tsx +87 -0
- package/template/packages/ui/src/components/input.tsx +20 -0
- package/template/packages/ui/src/components/item.tsx +201 -0
- package/template/packages/ui/src/components/kbd.tsx +26 -0
- package/template/packages/ui/src/components/label.tsx +20 -0
- package/template/packages/ui/src/components/menubar.tsx +280 -0
- package/template/packages/ui/src/components/native-select.tsx +52 -0
- package/template/packages/ui/src/components/navigation-menu.tsx +168 -0
- package/template/packages/ui/src/components/pagination.tsx +130 -0
- package/template/packages/ui/src/components/popover.tsx +90 -0
- package/template/packages/ui/src/components/progress.tsx +83 -0
- package/template/packages/ui/src/components/radio-group.tsx +38 -0
- package/template/packages/ui/src/components/resizable.tsx +50 -0
- package/template/packages/ui/src/components/scroll-area.tsx +55 -0
- package/template/packages/ui/src/components/select.tsx +201 -0
- package/template/packages/ui/src/components/separator.tsx +25 -0
- package/template/packages/ui/src/components/sheet.tsx +135 -0
- package/template/packages/ui/src/components/sidebar.tsx +723 -0
- package/template/packages/ui/src/components/skeleton.tsx +13 -0
- package/template/packages/ui/src/components/slider.tsx +59 -0
- package/template/packages/ui/src/components/sonner.tsx +49 -0
- package/template/packages/ui/src/components/spinner.tsx +10 -0
- package/template/packages/ui/src/components/switch.tsx +32 -0
- package/template/packages/ui/src/components/table.tsx +116 -0
- package/template/packages/ui/src/components/tabs.tsx +82 -0
- package/template/packages/ui/src/components/textarea.tsx +18 -0
- package/template/packages/ui/src/components/toggle-group.tsx +89 -0
- package/template/packages/ui/src/components/toggle.tsx +44 -0
- package/template/packages/ui/src/components/tooltip.tsx +66 -0
- package/template/packages/ui/src/hooks/.gitkeep +0 -0
- package/template/packages/ui/src/hooks/use-mobile.ts +19 -0
- package/template/packages/ui/src/lib/.gitkeep +0 -0
- package/template/packages/ui/src/lib/utils.ts +6 -0
- package/template/packages/ui/src/styles/globals.css +128 -0
- package/template/packages/ui/tsconfig.json +11 -0
- package/template/packages/ui/tsconfig.lint.json +8 -0
- package/template/pnpm-lock.yaml +9103 -0
- package/template/pnpm-workspace.yaml +3 -0
- package/template/tsconfig.json +4 -0
- package/template/turbo.json +24 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
types: [opened, synchronize]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
name: Build and Test
|
|
12
|
+
timeout-minutes: 15
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
# To use Remote Caching, uncomment the next lines
|
|
15
|
+
# env:
|
|
16
|
+
# TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
17
|
+
# TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Check out code
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
with:
|
|
23
|
+
fetch-depth: 2
|
|
24
|
+
|
|
25
|
+
- name: Setup Node.js environment
|
|
26
|
+
uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: 20
|
|
29
|
+
cache: 'pnpm'
|
|
30
|
+
|
|
31
|
+
- uses: pnpm/action-setup@v3
|
|
32
|
+
name: Install pnpm
|
|
33
|
+
with:
|
|
34
|
+
version: 9
|
|
35
|
+
run_install: false
|
|
36
|
+
|
|
37
|
+
- name: Get pnpm store directory
|
|
38
|
+
shell: bash
|
|
39
|
+
run: |
|
|
40
|
+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
|
41
|
+
|
|
42
|
+
- uses: actions/cache@v4
|
|
43
|
+
name: Setup pnpm cache
|
|
44
|
+
with:
|
|
45
|
+
path: ${{ env.STORE_PATH }}
|
|
46
|
+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
47
|
+
restore-keys: |
|
|
48
|
+
${{ runner.os }}-pnpm-store-
|
|
49
|
+
|
|
50
|
+
- name: Install dependencies
|
|
51
|
+
run: pnpm install
|
|
52
|
+
|
|
53
|
+
- name: Build
|
|
54
|
+
run: pnpm build
|
|
55
|
+
|
|
56
|
+
- name: Lint
|
|
57
|
+
run: pnpm lint
|
|
58
|
+
|
|
59
|
+
- name: Typecheck
|
|
60
|
+
run: pnpm typecheck
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"endOfLine": "lf",
|
|
3
|
+
"semi": false,
|
|
4
|
+
"singleQuote": false,
|
|
5
|
+
"tabWidth": 2,
|
|
6
|
+
"trailingComma": "es5",
|
|
7
|
+
"printWidth": 80,
|
|
8
|
+
"plugins": ["prettier-plugin-tailwindcss"],
|
|
9
|
+
"tailwindStylesheet": "packages/ui/src/styles/globals.css",
|
|
10
|
+
"tailwindFunctions": ["cn", "cva"]
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# shadcn/ui monorepo template
|
|
2
|
+
|
|
3
|
+
This is a Next.js monorepo template with shadcn/ui.
|
|
4
|
+
|
|
5
|
+
## Adding components
|
|
6
|
+
|
|
7
|
+
To add components to your app, run the following command at the root of your `web` app:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm dlx shadcn@latest add button -c apps/web
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This will place the ui components in the `packages/ui/src/components` directory.
|
|
14
|
+
|
|
15
|
+
## Using components
|
|
16
|
+
|
|
17
|
+
To use the components in your app, import them from the `ui` package.
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { Button } from "@workspace/ui/components/button";
|
|
21
|
+
```
|
|
Binary file
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Geist, Geist_Mono, Inter } from "next/font/google"
|
|
2
|
+
|
|
3
|
+
import "@workspace/ui/globals.css"
|
|
4
|
+
import { ThemeProvider } from "@/components/theme-provider"
|
|
5
|
+
import { cn } from "@workspace/ui/lib/utils";
|
|
6
|
+
|
|
7
|
+
const inter = Inter({subsets:['latin'],variable:'--font-sans'})
|
|
8
|
+
|
|
9
|
+
const fontMono = Geist_Mono({
|
|
10
|
+
subsets: ["latin"],
|
|
11
|
+
variable: "--font-mono",
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export default function RootLayout({
|
|
15
|
+
children,
|
|
16
|
+
}: Readonly<{
|
|
17
|
+
children: React.ReactNode
|
|
18
|
+
}>) {
|
|
19
|
+
return (
|
|
20
|
+
<html
|
|
21
|
+
lang="en"
|
|
22
|
+
suppressHydrationWarning
|
|
23
|
+
className={cn("antialiased", fontMono.variable, "font-sans", inter.variable)}
|
|
24
|
+
>
|
|
25
|
+
<body>
|
|
26
|
+
<ThemeProvider>{children}</ThemeProvider>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Button } from "@workspace/ui/components/button"
|
|
2
|
+
|
|
3
|
+
export default function Page() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="flex min-h-svh p-6">
|
|
6
|
+
<div className="flex max-w-md min-w-0 flex-col gap-4 text-sm leading-loose">
|
|
7
|
+
<div>
|
|
8
|
+
<h1 className="font-medium">Project ready!</h1>
|
|
9
|
+
<p>You may now add components and start building.</p>
|
|
10
|
+
<p>We've already added the button component for you.</p>
|
|
11
|
+
<Button className="mt-2">Button</Button>
|
|
12
|
+
</div>
|
|
13
|
+
<div className="text-muted-foreground font-mono text-xs">
|
|
14
|
+
(Press <kbd>d</kbd> to toggle dark mode)
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes"
|
|
5
|
+
|
|
6
|
+
function ThemeProvider({
|
|
7
|
+
children,
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof NextThemesProvider>) {
|
|
10
|
+
return (
|
|
11
|
+
<NextThemesProvider
|
|
12
|
+
attribute="class"
|
|
13
|
+
defaultTheme="system"
|
|
14
|
+
enableSystem
|
|
15
|
+
disableTransitionOnChange
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<ThemeHotkey />
|
|
19
|
+
{children}
|
|
20
|
+
</NextThemesProvider>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isTypingTarget(target: EventTarget | null) {
|
|
25
|
+
if (!(target instanceof HTMLElement)) {
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
target.isContentEditable ||
|
|
31
|
+
target.tagName === "INPUT" ||
|
|
32
|
+
target.tagName === "TEXTAREA" ||
|
|
33
|
+
target.tagName === "SELECT"
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ThemeHotkey() {
|
|
38
|
+
const { resolvedTheme, setTheme } = useTheme()
|
|
39
|
+
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
42
|
+
if (event.defaultPrevented || event.repeat) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (event.metaKey || event.ctrlKey || event.altKey) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (event.key.toLowerCase() !== "d") {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (isTypingTarget(event.target)) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setTheme(resolvedTheme === "dark" ? "light" : "dark")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
window.addEventListener("keydown", onKeyDown)
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
window.removeEventListener("keydown", onKeyDown)
|
|
65
|
+
}
|
|
66
|
+
}, [resolvedTheme, setTheme])
|
|
67
|
+
|
|
68
|
+
return null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { ThemeProvider }
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "base-vega",
|
|
4
|
+
"rsc": true,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "../../packages/ui/src/styles/globals.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"iconLibrary": "lucide",
|
|
13
|
+
"aliases": {
|
|
14
|
+
"components": "@/components",
|
|
15
|
+
"hooks": "@/hooks",
|
|
16
|
+
"lib": "@/lib",
|
|
17
|
+
"utils": "@workspace/ui/lib/utils",
|
|
18
|
+
"ui": "@workspace/ui/components"
|
|
19
|
+
},
|
|
20
|
+
"rtl": false,
|
|
21
|
+
"menuColor": "default",
|
|
22
|
+
"menuAccent": "subtle"
|
|
23
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "admin",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "next dev --turbopack",
|
|
8
|
+
"build": "next build",
|
|
9
|
+
"start": "next start",
|
|
10
|
+
"lint": "eslint",
|
|
11
|
+
"format": "prettier --write \"**/*.{ts,tsx}\"",
|
|
12
|
+
"typecheck": "tsc --noEmit"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@workspace/ui": "workspace:*",
|
|
16
|
+
"lucide-react": "^0.577.0",
|
|
17
|
+
"next": "16.1.6",
|
|
18
|
+
"next-themes": "^0.4.6",
|
|
19
|
+
"react": "^19.2.4",
|
|
20
|
+
"react-dom": "^19.2.4"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
24
|
+
"@types/node": "^25.1.0",
|
|
25
|
+
"@types/react": "^19.2.10",
|
|
26
|
+
"@types/react-dom": "^19.2.3",
|
|
27
|
+
"@workspace/eslint-config": "workspace:^",
|
|
28
|
+
"@workspace/typescript-config": "workspace:*",
|
|
29
|
+
"eslint": "^9.39.2",
|
|
30
|
+
"typescript": "^5.9.3"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "@workspace/ui/postcss.config";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@workspace/typescript-config/nextjs.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": ".",
|
|
5
|
+
"paths": {
|
|
6
|
+
"@/*": ["./*"],
|
|
7
|
+
"@workspace/ui/*": ["../../packages/ui/src/*"]
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "next"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"include": [
|
|
16
|
+
"next-env.d.ts",
|
|
17
|
+
"next.config.ts",
|
|
18
|
+
"**/*.ts",
|
|
19
|
+
"**/*.tsx",
|
|
20
|
+
".next/types/**/*.ts"
|
|
21
|
+
],
|
|
22
|
+
"exclude": ["node_modules"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "tsx watch ./src/index.ts",
|
|
7
|
+
"build": "tsup",
|
|
8
|
+
"start": "node dist/index.js",
|
|
9
|
+
"lint": "eslint . --ext .ts,.tsx",
|
|
10
|
+
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"seed:permissions": "tsx src/scripts/seed-permissions.ts"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/cors": "^2.8.19",
|
|
16
|
+
"@types/express": "^5.0.6",
|
|
17
|
+
"@types/multer": "^2.1.0",
|
|
18
|
+
"@types/node": "^25.1.0",
|
|
19
|
+
"@workspace/eslint-config": "workspace:^",
|
|
20
|
+
"@workspace/typescript-config": "workspace:*",
|
|
21
|
+
"tsup": "^8.5.1",
|
|
22
|
+
"typescript": "^5.9.3"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"cors": "^2.8.6",
|
|
26
|
+
"dotenv": "^17.3.1",
|
|
27
|
+
"express": "^5.2.1",
|
|
28
|
+
"multer": "^2.1.1",
|
|
29
|
+
"pino": "^10.3.1",
|
|
30
|
+
"zod": "^3.25.76"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import express, { type Express, type Request, type Response } from "express"
|
|
2
|
+
import cors from "cors"
|
|
3
|
+
|
|
4
|
+
export const createServer = (): Express => {
|
|
5
|
+
const app = express()
|
|
6
|
+
|
|
7
|
+
app.use(express.json())
|
|
8
|
+
app.use(express.urlencoded({ extended: true }))
|
|
9
|
+
app.use(cors())
|
|
10
|
+
|
|
11
|
+
app.get("/health", (req: Request, res: Response) => {
|
|
12
|
+
res.status(200).json({
|
|
13
|
+
status: "ok",
|
|
14
|
+
service: "api",
|
|
15
|
+
uptime: process.uptime(),
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
return app
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@workspace/typescript-config/base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"target": "ES2020",
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"baseUrl": ".",
|
|
12
|
+
"paths": {
|
|
13
|
+
"@/*": ["./src/*"]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Geist, Geist_Mono, Inter } from "next/font/google"
|
|
2
|
+
|
|
3
|
+
import "@workspace/ui/globals.css"
|
|
4
|
+
import { ThemeProvider } from "@/components/theme-provider"
|
|
5
|
+
import { cn } from "@workspace/ui/lib/utils";
|
|
6
|
+
|
|
7
|
+
const inter = Inter({subsets:['latin'],variable:'--font-sans'})
|
|
8
|
+
|
|
9
|
+
const fontMono = Geist_Mono({
|
|
10
|
+
subsets: ["latin"],
|
|
11
|
+
variable: "--font-mono",
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export default function RootLayout({
|
|
15
|
+
children,
|
|
16
|
+
}: Readonly<{
|
|
17
|
+
children: React.ReactNode
|
|
18
|
+
}>) {
|
|
19
|
+
return (
|
|
20
|
+
<html
|
|
21
|
+
lang="en"
|
|
22
|
+
suppressHydrationWarning
|
|
23
|
+
className={cn("antialiased", fontMono.variable, "font-sans", inter.variable)}
|
|
24
|
+
>
|
|
25
|
+
<body>
|
|
26
|
+
<ThemeProvider>{children}</ThemeProvider>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Button } from "@workspace/ui/components/button"
|
|
2
|
+
|
|
3
|
+
export default function Page() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="flex min-h-svh p-6">
|
|
6
|
+
<div className="flex max-w-md min-w-0 flex-col gap-4 text-sm leading-loose">
|
|
7
|
+
<div>
|
|
8
|
+
<h1 className="font-medium">Project ready!</h1>
|
|
9
|
+
<p>You may now add components and start building.</p>
|
|
10
|
+
<p>We've already added the button component for you.</p>
|
|
11
|
+
<Button className="mt-2">Button</Button>
|
|
12
|
+
</div>
|
|
13
|
+
<div className="text-muted-foreground font-mono text-xs">
|
|
14
|
+
(Press <kbd>d</kbd> to toggle dark mode)
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes"
|
|
5
|
+
|
|
6
|
+
function ThemeProvider({
|
|
7
|
+
children,
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof NextThemesProvider>) {
|
|
10
|
+
return (
|
|
11
|
+
<NextThemesProvider
|
|
12
|
+
attribute="class"
|
|
13
|
+
defaultTheme="system"
|
|
14
|
+
enableSystem
|
|
15
|
+
disableTransitionOnChange
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<ThemeHotkey />
|
|
19
|
+
{children}
|
|
20
|
+
</NextThemesProvider>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isTypingTarget(target: EventTarget | null) {
|
|
25
|
+
if (!(target instanceof HTMLElement)) {
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
target.isContentEditable ||
|
|
31
|
+
target.tagName === "INPUT" ||
|
|
32
|
+
target.tagName === "TEXTAREA" ||
|
|
33
|
+
target.tagName === "SELECT"
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ThemeHotkey() {
|
|
38
|
+
const { resolvedTheme, setTheme } = useTheme()
|
|
39
|
+
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
42
|
+
if (event.defaultPrevented || event.repeat) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (event.metaKey || event.ctrlKey || event.altKey) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (event.key.toLowerCase() !== "d") {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (isTypingTarget(event.target)) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setTheme(resolvedTheme === "dark" ? "light" : "dark")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
window.addEventListener("keydown", onKeyDown)
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
window.removeEventListener("keydown", onKeyDown)
|
|
65
|
+
}
|
|
66
|
+
}, [resolvedTheme, setTheme])
|
|
67
|
+
|
|
68
|
+
return null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { ThemeProvider }
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "base-vega",
|
|
4
|
+
"rsc": true,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "../../packages/ui/src/styles/globals.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"iconLibrary": "lucide",
|
|
13
|
+
"aliases": {
|
|
14
|
+
"components": "@/components",
|
|
15
|
+
"hooks": "@/hooks",
|
|
16
|
+
"lib": "@/lib",
|
|
17
|
+
"utils": "@workspace/ui/lib/utils",
|
|
18
|
+
"ui": "@workspace/ui/components"
|
|
19
|
+
},
|
|
20
|
+
"rtl": false,
|
|
21
|
+
"menuColor": "default",
|
|
22
|
+
"menuAccent": "subtle"
|
|
23
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "web",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "next dev --turbopack",
|
|
8
|
+
"build": "next build",
|
|
9
|
+
"start": "next start",
|
|
10
|
+
"lint": "eslint",
|
|
11
|
+
"format": "prettier --write \"**/*.{ts,tsx}\"",
|
|
12
|
+
"typecheck": "tsc --noEmit"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@workspace/ui": "workspace:*",
|
|
16
|
+
"lucide-react": "^0.577.0",
|
|
17
|
+
"next": "16.1.6",
|
|
18
|
+
"next-themes": "^0.4.6",
|
|
19
|
+
"react": "^19.2.4",
|
|
20
|
+
"react-dom": "^19.2.4"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
24
|
+
"@types/node": "^25.1.0",
|
|
25
|
+
"@types/react": "^19.2.10",
|
|
26
|
+
"@types/react-dom": "^19.2.3",
|
|
27
|
+
"@workspace/eslint-config": "workspace:^",
|
|
28
|
+
"@workspace/typescript-config": "workspace:*",
|
|
29
|
+
"eslint": "^9.39.2",
|
|
30
|
+
"typescript": "^5.9.3"
|
|
31
|
+
}
|
|
32
|
+
}
|