@cogito.ai/cli 0.3.5 → 0.4.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 +20 -1
- package/dist/templates/web-nextjs/apps/docs/.source/browser.ts +1 -1
- package/dist/templates/web-nextjs/apps/docs/.source/server.ts +3 -2
- package/dist/templates/web-nextjs/apps/docs/content/docs/decisions/meta.json +1 -1
- package/dist/templates/web-nextjs/apps/docs/content/docs/decisions/turbo-package-manager.mdx +70 -0
- package/dist/templates/web-nextjs/apps/docs/package.json +1 -1
- package/dist/templates/web-nextjs/apps/web/messages/en.json +5 -1
- package/dist/templates/web-nextjs/apps/web/messages/zh.json +5 -1
- package/dist/templates/web-nextjs/apps/web/package.json +27 -0
- package/dist/templates/web-nextjs/apps/web/postcss.config.mjs +8 -0
- package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/login/page.tsx +87 -93
- package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/signup/page.tsx +116 -98
- package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/dashboard/page.tsx +38 -29
- package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/layout.tsx +2 -5
- package/dist/templates/web-nextjs/apps/web/src/app/[locale]/layout.tsx +4 -7
- package/dist/templates/web-nextjs/apps/web/src/app/[locale]/privacy/page.tsx +23 -0
- package/dist/templates/web-nextjs/apps/web/src/app/[locale]/terms/page.tsx +23 -0
- package/dist/templates/web-nextjs/apps/web/src/app/route.ts +13 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/app-sidebar.tsx +188 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/chart-area-interactive.tsx +291 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/data-table.tsx +807 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/data.json +614 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-documents.tsx +92 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-main.tsx +58 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-secondary.tsx +42 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-user.tsx +118 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/page.tsx +40 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/section-cards.tsx +102 -0
- package/dist/templates/web-nextjs/apps/web/src/components/dashboard/site-header.tsx +30 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/alert-dialog.tsx +196 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/avatar.tsx +109 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/badge.tsx +48 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/breadcrumb.tsx +109 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/button.tsx +14 -2
- package/dist/templates/web-nextjs/apps/web/src/components/ui/card.tsx +92 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/chart.tsx +374 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/checkbox.tsx +32 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/collapsible.tsx +33 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/command.tsx +184 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/dialog.tsx +158 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/drawer.tsx +135 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/dropdown-menu.tsx +257 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/field.tsx +248 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/input-otp.tsx +77 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/pagination.tsx +127 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/popover.tsx +89 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/progress.tsx +31 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/radio-group.tsx +45 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/scroll-area.tsx +58 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/select.tsx +190 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/separator.tsx +29 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/sheet.tsx +143 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/sidebar.tsx +726 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/skeleton.tsx +13 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/slider.tsx +63 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/sonner.tsx +11 -25
- package/dist/templates/web-nextjs/apps/web/src/components/ui/switch.tsx +35 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/table.tsx +116 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/tabs.tsx +91 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/textarea.tsx +18 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle-group.tsx +83 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle.tsx +47 -0
- package/dist/templates/web-nextjs/apps/web/src/components/ui/tooltip.tsx +57 -0
- package/dist/templates/web-nextjs/apps/web/src/features/auth/server.ts +15 -0
- package/dist/templates/web-nextjs/apps/web/src/hooks/use-mobile.ts +21 -0
- package/dist/templates/web-nextjs/package.json +10 -0
- package/dist/templates/web-nextjs/packages/openspec-docs-sync/package.json +0 -3
- package/dist/templates/web-nextjs/pnpm-lock.yaml +1561 -96
- package/dist/templates/web-nextjs/pnpm-workspace.yaml +15 -0
- package/dist/templates/web-nextjs/turbo.json +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -868,7 +868,7 @@ var package_default;
|
|
|
868
868
|
var init_package = __esm(() => {
|
|
869
869
|
package_default = {
|
|
870
870
|
name: "@cogito.ai/cli",
|
|
871
|
-
version: "0.
|
|
871
|
+
version: "0.4.1",
|
|
872
872
|
type: "module",
|
|
873
873
|
description: "AgentDock CLI – scaffold projects for humans and AI agents",
|
|
874
874
|
publishConfig: {
|
|
@@ -923,6 +923,7 @@ import {
|
|
|
923
923
|
} from "fs";
|
|
924
924
|
import { join as join2, dirname as dirname2 } from "path";
|
|
925
925
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
926
|
+
import { execSync } from "child_process";
|
|
926
927
|
function getTemplateSourceDir(templateSource) {
|
|
927
928
|
const runtimeDir = dirname2(fileURLToPath2(import.meta.url));
|
|
928
929
|
const candidates = [
|
|
@@ -957,6 +958,23 @@ function rewritePackageJson(pkgJsonPath, name, resolvedDependencies) {
|
|
|
957
958
|
writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + `
|
|
958
959
|
`, "utf-8");
|
|
959
960
|
}
|
|
961
|
+
function injectPackageManager(pkgJsonPath) {
|
|
962
|
+
if (!existsSync2(pkgJsonPath))
|
|
963
|
+
return;
|
|
964
|
+
try {
|
|
965
|
+
const pnpmVersion = execSync("pnpm --version", {
|
|
966
|
+
encoding: "utf-8",
|
|
967
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
968
|
+
}).trim();
|
|
969
|
+
if (!pnpmVersion)
|
|
970
|
+
return;
|
|
971
|
+
const raw = readFileSync2(pkgJsonPath, "utf-8");
|
|
972
|
+
const pkg = JSON.parse(raw);
|
|
973
|
+
pkg["packageManager"] = `pnpm@${pnpmVersion}`;
|
|
974
|
+
writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + `
|
|
975
|
+
`, "utf-8");
|
|
976
|
+
} catch {}
|
|
977
|
+
}
|
|
960
978
|
function scaffoldProject(options) {
|
|
961
979
|
const { targetDir, name, template, packageManager: _pm } = options;
|
|
962
980
|
try {
|
|
@@ -983,6 +1001,7 @@ function scaffoldProject(options) {
|
|
|
983
1001
|
if (existsSync2(pkgJsonPath)) {
|
|
984
1002
|
rewritePackageJson(pkgJsonPath, name, template.resolvedDependencies);
|
|
985
1003
|
}
|
|
1004
|
+
injectPackageManager(pkgJsonPath);
|
|
986
1005
|
return {
|
|
987
1006
|
ok: true,
|
|
988
1007
|
targetDir,
|
|
@@ -7,6 +7,6 @@ const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").Inter
|
|
|
7
7
|
}
|
|
8
8
|
}>();
|
|
9
9
|
const browserCollections = {
|
|
10
|
-
docs: create.doc("docs", {"index.mdx": () => import("../content/docs/index.mdx?collection=docs"), "changelog/index.mdx": () => import("../content/docs/changelog/index.mdx?collection=docs"), "
|
|
10
|
+
docs: create.doc("docs", {"index.mdx": () => import("../content/docs/index.mdx?collection=docs"), "changelog/index.mdx": () => import("../content/docs/changelog/index.mdx?collection=docs"), "decisions/turbo-package-manager.mdx": () => import("../content/docs/decisions/turbo-package-manager.mdx?collection=docs"), "features/auth.mdx": () => import("../content/docs/features/auth.mdx?collection=docs"), "features/hello.mdx": () => import("../content/docs/features/hello.mdx?collection=docs"), "roadmap/index.mdx": () => import("../content/docs/roadmap/index.mdx?collection=docs"), }),
|
|
11
11
|
};
|
|
12
12
|
export default browserCollections;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
+
import * as __fd_glob_10 from "../content/docs/roadmap/index.mdx?collection=docs"
|
|
2
3
|
import * as __fd_glob_9 from "../content/docs/features/hello.mdx?collection=docs"
|
|
3
4
|
import * as __fd_glob_8 from "../content/docs/features/auth.mdx?collection=docs"
|
|
4
|
-
import * as __fd_glob_7 from "../content/docs/
|
|
5
|
+
import * as __fd_glob_7 from "../content/docs/decisions/turbo-package-manager.mdx?collection=docs"
|
|
5
6
|
import * as __fd_glob_6 from "../content/docs/changelog/index.mdx?collection=docs"
|
|
6
7
|
import * as __fd_glob_5 from "../content/docs/index.mdx?collection=docs"
|
|
7
8
|
import { default as __fd_glob_4 } from "../content/docs/roadmap/meta.json?collection=docs"
|
|
@@ -17,4 +18,4 @@ const create = server<typeof Config, import("fumadocs-mdx/runtime/types").Intern
|
|
|
17
18
|
}
|
|
18
19
|
}>({"doc":{"passthroughs":["extractedReferences"]}});
|
|
19
20
|
|
|
20
|
-
export const docs = await create.docs("docs", "content/docs", {"meta.json": __fd_glob_0, "changelog/meta.json": __fd_glob_1, "decisions/meta.json": __fd_glob_2, "features/meta.json": __fd_glob_3, "roadmap/meta.json": __fd_glob_4, }, {"index.mdx": __fd_glob_5, "changelog/index.mdx": __fd_glob_6, "
|
|
21
|
+
export const docs = await create.docs("docs", "content/docs", {"meta.json": __fd_glob_0, "changelog/meta.json": __fd_glob_1, "decisions/meta.json": __fd_glob_2, "features/meta.json": __fd_glob_3, "roadmap/meta.json": __fd_glob_4, }, {"index.mdx": __fd_glob_5, "changelog/index.mdx": __fd_glob_6, "decisions/turbo-package-manager.mdx": __fd_glob_7, "features/auth.mdx": __fd_glob_8, "features/hello.mdx": __fd_glob_9, "roadmap/index.mdx": __fd_glob_10, });
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Turbo & Package Manager"
|
|
3
|
+
description: "Why dangerouslyDisablePackageManagerCheck exists, its tradeoffs, and how to properly configure packageManager for your team."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Turborepo & Package Manager Configuration
|
|
7
|
+
|
|
8
|
+
## Why `dangerouslyDisablePackageManagerCheck` is enabled
|
|
9
|
+
|
|
10
|
+
This template ships with `dangerouslyDisablePackageManagerCheck: true` in `turbo.json` to avoid an out-of-the-box failure:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
// turbo.json
|
|
14
|
+
{
|
|
15
|
+
"dangerouslyDisablePackageManagerCheck": true
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Root cause:** Turborepo 2.0+ requires the `packageManager` field in `package.json` to identify your package manager and version. Without it, Turbo refuses to run:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
× Could not resolve workspaces.
|
|
23
|
+
╰─▶ Missing `packageManager` field in package.json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Since users may have different pnpm versions installed, the template cannot hard-code a specific version without risking the same `Corepack PATH` error that plagues a pinned `packageManager` field. `dangerouslyDisablePackageManagerCheck` lets Turbo skip this validation so the template works on first `pnpm dev`.
|
|
27
|
+
|
|
28
|
+
## What `dangerouslyDisablePackageManagerCheck` actually disables
|
|
29
|
+
|
|
30
|
+
| What Turbo normally does | What is skipped |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| Reads `packageManager` to identify which lockfile to hash | Cache hashing falls back to a less-precise strategy |
|
|
33
|
+
| Validates that the running package manager matches the declared one | No mismatch detection (could build with wrong PM) |
|
|
34
|
+
| Optimizes workspace discovery per package manager | Slightly slower workspace graph resolution |
|
|
35
|
+
|
|
36
|
+
**In practice:** for most single-developer or small team projects, the only noticeable difference is that Turbo cache keys are slightly less precise — you might get a cache miss that would otherwise be a hit. This is a minor inconvenience, not a correctness issue.
|
|
37
|
+
|
|
38
|
+
## How to remove the flag (recommended for team projects)
|
|
39
|
+
|
|
40
|
+
**Step 1 — Find your installed pnpm version:**
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pnpm --version
|
|
44
|
+
# e.g. 11.5.1
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Step 2 — Add `packageManager` to your root `package.json`:**
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"packageManager": "pnpm@11.5.1"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Step 3 — Remove `dangerouslyDisablePackageManagerCheck` from `turbo.json`:**
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"$schema": "https://turbo.build/schema.json",
|
|
60
|
+
"tasks": {
|
|
61
|
+
...
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Step 4 — Commit both files.** All developers cloning the repo will now use the same pnpm version enforced by Corepack, and Turbo's cache hashing is fully accurate.
|
|
67
|
+
|
|
68
|
+
## Automatic injection (CLI 0.3.6+)
|
|
69
|
+
|
|
70
|
+
Starting with `@cogito.ai/cli@0.3.6`, the `agentdock init` command automatically detects your installed pnpm version and injects `packageManager: "pnpm@X.Y.Z"` into the scaffolded project's root `package.json`. This means new projects are created with the correct field pre-filled, and you can immediately remove `dangerouslyDisablePackageManagerCheck` from `turbo.json` after scaffolding.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"start": "next start",
|
|
9
9
|
"lint": "eslint .",
|
|
10
10
|
"check-types": "tsc --noEmit",
|
|
11
|
-
"docs:sync": "openspec-docs-sync",
|
|
11
|
+
"docs:sync": "pnpm --filter @cogito.ai/openspec-docs-sync run build && node ../../packages/openspec-docs-sync/dist/index.js",
|
|
12
12
|
"postinstall": "fumadocs-mdx"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"dashboardTitle": "Dashboard",
|
|
30
30
|
"dashboardWelcome": "Welcome, {email}",
|
|
31
31
|
"errorInvalidCredentials": "Invalid email or password.",
|
|
32
|
-
"errorGeneric": "Something went wrong. Please try again."
|
|
32
|
+
"errorGeneric": "Something went wrong. Please try again.",
|
|
33
|
+
"termsText": "By clicking continue, you agree to our",
|
|
34
|
+
"termsLink": "Terms of Service",
|
|
35
|
+
"andText": "and",
|
|
36
|
+
"privacyLink": "Privacy Policy"
|
|
33
37
|
}
|
|
34
38
|
}
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"dashboardTitle": "控制台",
|
|
30
30
|
"dashboardWelcome": "欢迎,{email}",
|
|
31
31
|
"errorInvalidCredentials": "邮箱或密码错误。",
|
|
32
|
-
"errorGeneric": "出现错误,请稍后重试。"
|
|
32
|
+
"errorGeneric": "出现错误,请稍后重试。",
|
|
33
|
+
"termsText": "点击继续即表示您同意我们的",
|
|
34
|
+
"termsLink": "服务条款",
|
|
35
|
+
"andText": "和",
|
|
36
|
+
"privacyLink": "隐私政策"
|
|
33
37
|
}
|
|
34
38
|
}
|
|
@@ -12,21 +12,48 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@base-ui/react": "^1.5.0",
|
|
15
|
+
"@dnd-kit/core": "^6.3.1",
|
|
16
|
+
"@dnd-kit/modifiers": "^9.0.0",
|
|
17
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
18
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
15
19
|
"@hookform/resolvers": "^5.4.0",
|
|
20
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
21
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
22
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
23
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
24
|
+
"@radix-ui/react-progress": "^1.1.8",
|
|
25
|
+
"@radix-ui/react-radio-group": "^1.3.8",
|
|
26
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
27
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
28
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
29
|
+
"@radix-ui/react-slider": "^1.3.6",
|
|
30
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
31
|
+
"@radix-ui/react-switch": "^1.2.6",
|
|
32
|
+
"@radix-ui/react-tabs": "^1.1.13",
|
|
33
|
+
"@radix-ui/react-toggle": "^1.1.10",
|
|
34
|
+
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
16
35
|
"@supabase/ssr": "^0.10.3",
|
|
36
|
+
"@tabler/icons-react": "^3.44.0",
|
|
37
|
+
"@tailwindcss/postcss": "^4.3.0",
|
|
38
|
+
"@tanstack/react-table": "^8.21.3",
|
|
17
39
|
"class-variance-authority": "^0.7.1",
|
|
18
40
|
"clsx": "^2.1.1",
|
|
41
|
+
"cmdk": "^1.1.1",
|
|
42
|
+
"input-otp": "^1.4.2",
|
|
19
43
|
"lucide-react": "^1.17.0",
|
|
20
44
|
"next": "16",
|
|
21
45
|
"next-intl": "^4.13.0",
|
|
22
46
|
"next-themes": "^0.4.6",
|
|
47
|
+
"radix-ui": "^1.4.3",
|
|
23
48
|
"react": "19",
|
|
24
49
|
"react-dom": "19",
|
|
25
50
|
"react-hook-form": "^7.77.0",
|
|
51
|
+
"recharts": "^3.8.1",
|
|
26
52
|
"shadcn": "^4.10.0",
|
|
27
53
|
"sonner": "^2.0.7",
|
|
28
54
|
"tailwind-merge": "^3.6.0",
|
|
29
55
|
"tw-animate-css": "^1.4.0",
|
|
56
|
+
"vaul": "^1.1.2",
|
|
30
57
|
"zod": "^4.4.3"
|
|
31
58
|
},
|
|
32
59
|
"devDependencies": {
|
|
@@ -6,18 +6,18 @@ import Link from 'next/link'
|
|
|
6
6
|
import { useTranslations } from 'next-intl'
|
|
7
7
|
import { useForm } from 'react-hook-form'
|
|
8
8
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
9
|
-
import {
|
|
9
|
+
import { GalleryVerticalEnd } from 'lucide-react'
|
|
10
10
|
import { toast } from 'sonner'
|
|
11
11
|
import { Button } from '@/components/ui/button'
|
|
12
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
|
12
13
|
import { Input } from '@/components/ui/input'
|
|
13
14
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from '@/components/ui/form'
|
|
15
|
+
Field,
|
|
16
|
+
FieldDescription,
|
|
17
|
+
FieldGroup,
|
|
18
|
+
FieldLabel,
|
|
19
|
+
FieldSeparator,
|
|
20
|
+
} from '@/components/ui/field'
|
|
21
21
|
import { signIn, signInWithGithubForLocale } from '@/features/auth'
|
|
22
22
|
import { signInSchema, type SignInInput } from '@/lib/validations/auth'
|
|
23
23
|
import type { ActionResult } from '@/core/types/auth'
|
|
@@ -28,114 +28,108 @@ export default function LoginPage() {
|
|
|
28
28
|
const routeParams = useParams<{ locale: string }>()
|
|
29
29
|
const locale = routeParams.locale ?? 'en'
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
const { register, formState: { errors } } = useForm<SignInInput>({
|
|
32
32
|
resolver: zodResolver(signInSchema),
|
|
33
33
|
defaultValues: { email: '', password: '' },
|
|
34
34
|
})
|
|
35
35
|
|
|
36
|
-
const [state, formAction, isPending] = useActionState<ActionResult | null, FormData>(
|
|
37
|
-
signIn,
|
|
38
|
-
null,
|
|
39
|
-
)
|
|
36
|
+
const [state, formAction, isPending] = useActionState<ActionResult | null, FormData>(signIn, null)
|
|
40
37
|
|
|
41
38
|
useEffect(() => {
|
|
42
|
-
if (state?.error)
|
|
43
|
-
toast.error(state.error)
|
|
44
|
-
}
|
|
39
|
+
if (state?.error) toast.error(state.error)
|
|
45
40
|
}, [state])
|
|
46
41
|
|
|
47
42
|
async function handleGithub() {
|
|
48
43
|
const result = await signInWithGithubForLocale(locale)
|
|
49
|
-
if (result.error) {
|
|
50
|
-
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
if (result.data?.url) {
|
|
54
|
-
router.push(result.data.url)
|
|
55
|
-
}
|
|
44
|
+
if (result.error) { toast.error(result.error); return }
|
|
45
|
+
if (result.data?.url) router.push(result.data.url)
|
|
56
46
|
}
|
|
57
47
|
|
|
58
48
|
return (
|
|
59
|
-
<div className="flex min-h-
|
|
60
|
-
<div className="w-full max-w-sm
|
|
61
|
-
<
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
<Button
|
|
67
|
-
type="button"
|
|
68
|
-
variant="outline"
|
|
69
|
-
className="w-full"
|
|
70
|
-
onClick={handleGithub}
|
|
71
|
-
>
|
|
72
|
-
<GitBranch className="mr-2 h-4 w-4" />
|
|
73
|
-
{t('githubButton')}
|
|
74
|
-
</Button>
|
|
75
|
-
|
|
76
|
-
<div className="relative">
|
|
77
|
-
<div className="absolute inset-0 flex items-center">
|
|
78
|
-
<span className="w-full border-t" />
|
|
79
|
-
</div>
|
|
80
|
-
<div className="relative flex justify-center text-xs uppercase">
|
|
81
|
-
<span className="bg-background px-2 text-muted-foreground">{t('orContinueWith')}</span>
|
|
49
|
+
<div className="flex min-h-svh flex-col items-center justify-center gap-6 bg-muted p-6 md:p-10">
|
|
50
|
+
<div className="flex w-full max-w-sm flex-col gap-6">
|
|
51
|
+
<Link href={`/${locale}`} className="flex items-center gap-2 self-center font-medium">
|
|
52
|
+
<div className="flex size-6 items-center justify-center rounded-md bg-primary text-primary-foreground">
|
|
53
|
+
<GalleryVerticalEnd className="size-4" />
|
|
82
54
|
</div>
|
|
83
|
-
|
|
55
|
+
AgentDock
|
|
56
|
+
</Link>
|
|
84
57
|
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
58
|
+
<div className="flex flex-col gap-6">
|
|
59
|
+
<Card>
|
|
60
|
+
<CardHeader className="text-center">
|
|
61
|
+
<CardTitle className="text-xl">{t('loginTitle')}</CardTitle>
|
|
62
|
+
<CardDescription>{t('loginSubtitle')}</CardDescription>
|
|
63
|
+
</CardHeader>
|
|
64
|
+
<CardContent>
|
|
65
|
+
<form action={formAction}>
|
|
66
|
+
<input type="hidden" name="locale" value={locale} />
|
|
67
|
+
<FieldGroup>
|
|
68
|
+
<Field>
|
|
69
|
+
<Button
|
|
70
|
+
type="button"
|
|
71
|
+
variant="outline"
|
|
72
|
+
className="w-full"
|
|
73
|
+
onClick={handleGithub}
|
|
74
|
+
>
|
|
75
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" className="size-4">
|
|
76
|
+
<path
|
|
77
|
+
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
|
|
78
|
+
fill="currentColor"
|
|
79
|
+
/>
|
|
80
|
+
</svg>
|
|
81
|
+
{t('githubButton')}
|
|
82
|
+
</Button>
|
|
83
|
+
</Field>
|
|
84
|
+
<FieldSeparator>{t('orContinueWith')}</FieldSeparator>
|
|
85
|
+
<Field>
|
|
86
|
+
<FieldLabel htmlFor="email">{t('emailLabel')}</FieldLabel>
|
|
95
87
|
<Input
|
|
88
|
+
id="email"
|
|
96
89
|
type="email"
|
|
97
90
|
placeholder={t('emailPlaceholder')}
|
|
98
|
-
|
|
91
|
+
autoComplete="email"
|
|
92
|
+
{...register('email')}
|
|
99
93
|
/>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<FormItem>
|
|
111
|
-
<FormLabel>{t('passwordLabel')}</FormLabel>
|
|
112
|
-
<FormControl>
|
|
94
|
+
{errors.email && (
|
|
95
|
+
<FieldDescription className="text-destructive">
|
|
96
|
+
{errors.email.message}
|
|
97
|
+
</FieldDescription>
|
|
98
|
+
)}
|
|
99
|
+
</Field>
|
|
100
|
+
<Field>
|
|
101
|
+
<div className="flex items-center">
|
|
102
|
+
<FieldLabel htmlFor="password">{t('passwordLabel')}</FieldLabel>
|
|
103
|
+
</div>
|
|
113
104
|
<Input
|
|
105
|
+
id="password"
|
|
114
106
|
type="password"
|
|
115
107
|
placeholder={t('passwordPlaceholder')}
|
|
116
|
-
|
|
108
|
+
autoComplete="current-password"
|
|
109
|
+
{...register('password')}
|
|
117
110
|
/>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
111
|
+
{errors.password && (
|
|
112
|
+
<FieldDescription className="text-destructive">
|
|
113
|
+
{errors.password.message}
|
|
114
|
+
</FieldDescription>
|
|
115
|
+
)}
|
|
116
|
+
</Field>
|
|
117
|
+
<Field>
|
|
118
|
+
<Button type="submit" className="w-full" disabled={isPending}>
|
|
119
|
+
{isPending ? '\u2026' : t('signInButton')}
|
|
120
|
+
</Button>
|
|
121
|
+
<FieldDescription className="text-center">
|
|
122
|
+
{t('noAccountText')}{' '}
|
|
123
|
+
<Link href={`/${locale}/signup`} className="underline underline-offset-4">
|
|
124
|
+
{t('signUpLink')}
|
|
125
|
+
</Link>
|
|
126
|
+
</FieldDescription>
|
|
127
|
+
</Field>
|
|
128
|
+
</FieldGroup>
|
|
129
|
+
</form>
|
|
130
|
+
</CardContent>
|
|
131
|
+
</Card>
|
|
132
|
+
</div>
|
|
139
133
|
</div>
|
|
140
134
|
</div>
|
|
141
135
|
)
|