@getcoherent/core 0.5.13 → 0.5.15
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/LICENSE +21 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +281 -6
- package/package.json +8 -8
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sergei Kovtun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -2154,6 +2154,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
|
|
|
2154
2154
|
cssFramework: z.ZodDefault<z.ZodEnum<["tailwind", "css-modules"]>>;
|
|
2155
2155
|
deployTarget: z.ZodOptional<z.ZodEnum<["vercel", "netlify", "cloudflare", "self-hosted"]>>;
|
|
2156
2156
|
autoScaffold: z.ZodDefault<z.ZodBoolean>;
|
|
2157
|
+
homePagePlaceholder: z.ZodDefault<z.ZodBoolean>;
|
|
2157
2158
|
}, "strip", z.ZodTypeAny, {
|
|
2158
2159
|
initialized: boolean;
|
|
2159
2160
|
appType: "multi-page" | "spa";
|
|
@@ -2161,6 +2162,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
|
|
|
2161
2162
|
typescript: boolean;
|
|
2162
2163
|
cssFramework: "tailwind" | "css-modules";
|
|
2163
2164
|
autoScaffold: boolean;
|
|
2165
|
+
homePagePlaceholder: boolean;
|
|
2164
2166
|
router?: "react-router" | "tanstack-router" | undefined;
|
|
2165
2167
|
deployTarget?: "vercel" | "netlify" | "cloudflare" | "self-hosted" | undefined;
|
|
2166
2168
|
}, {
|
|
@@ -2172,6 +2174,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
|
|
|
2172
2174
|
cssFramework?: "tailwind" | "css-modules" | undefined;
|
|
2173
2175
|
deployTarget?: "vercel" | "netlify" | "cloudflare" | "self-hosted" | undefined;
|
|
2174
2176
|
autoScaffold?: boolean | undefined;
|
|
2177
|
+
homePagePlaceholder?: boolean | undefined;
|
|
2175
2178
|
}>;
|
|
2176
2179
|
createdAt: z.ZodString;
|
|
2177
2180
|
updatedAt: z.ZodString;
|
|
@@ -2365,6 +2368,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
|
|
|
2365
2368
|
typescript: boolean;
|
|
2366
2369
|
cssFramework: "tailwind" | "css-modules";
|
|
2367
2370
|
autoScaffold: boolean;
|
|
2371
|
+
homePagePlaceholder: boolean;
|
|
2368
2372
|
router?: "react-router" | "tanstack-router" | undefined;
|
|
2369
2373
|
deployTarget?: "vercel" | "netlify" | "cloudflare" | "self-hosted" | undefined;
|
|
2370
2374
|
};
|
|
@@ -2556,6 +2560,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
|
|
|
2556
2560
|
cssFramework?: "tailwind" | "css-modules" | undefined;
|
|
2557
2561
|
deployTarget?: "vercel" | "netlify" | "cloudflare" | "self-hosted" | undefined;
|
|
2558
2562
|
autoScaffold?: boolean | undefined;
|
|
2563
|
+
homePagePlaceholder?: boolean | undefined;
|
|
2559
2564
|
};
|
|
2560
2565
|
navigation?: {
|
|
2561
2566
|
items: NavigationItem[];
|
|
@@ -2746,6 +2751,8 @@ declare const SharedComponentEntrySchema: z.ZodObject<{
|
|
|
2746
2751
|
createdAt: z.ZodOptional<z.ZodString>;
|
|
2747
2752
|
/** Human-readable description */
|
|
2748
2753
|
description: z.ZodOptional<z.ZodString>;
|
|
2754
|
+
/** TypeScript props interface body, e.g. "{ icon: React.ReactNode; title: string }" */
|
|
2755
|
+
propsInterface: z.ZodOptional<z.ZodString>;
|
|
2749
2756
|
}, "strip", z.ZodTypeAny, {
|
|
2750
2757
|
type: "layout" | "section" | "widget";
|
|
2751
2758
|
name: string;
|
|
@@ -2754,6 +2761,7 @@ declare const SharedComponentEntrySchema: z.ZodObject<{
|
|
|
2754
2761
|
usedIn: string[];
|
|
2755
2762
|
description?: string | undefined;
|
|
2756
2763
|
createdAt?: string | undefined;
|
|
2764
|
+
propsInterface?: string | undefined;
|
|
2757
2765
|
}, {
|
|
2758
2766
|
type: "layout" | "section" | "widget";
|
|
2759
2767
|
name: string;
|
|
@@ -2762,6 +2770,7 @@ declare const SharedComponentEntrySchema: z.ZodObject<{
|
|
|
2762
2770
|
description?: string | undefined;
|
|
2763
2771
|
createdAt?: string | undefined;
|
|
2764
2772
|
usedIn?: string[] | undefined;
|
|
2773
|
+
propsInterface?: string | undefined;
|
|
2765
2774
|
}>;
|
|
2766
2775
|
type SharedComponentEntry = z.infer<typeof SharedComponentEntrySchema>;
|
|
2767
2776
|
/** Root schema for coherent.components.json */
|
|
@@ -2780,6 +2789,8 @@ declare const SharedComponentsManifestSchema: z.ZodObject<{
|
|
|
2780
2789
|
createdAt: z.ZodOptional<z.ZodString>;
|
|
2781
2790
|
/** Human-readable description */
|
|
2782
2791
|
description: z.ZodOptional<z.ZodString>;
|
|
2792
|
+
/** TypeScript props interface body, e.g. "{ icon: React.ReactNode; title: string }" */
|
|
2793
|
+
propsInterface: z.ZodOptional<z.ZodString>;
|
|
2783
2794
|
}, "strip", z.ZodTypeAny, {
|
|
2784
2795
|
type: "layout" | "section" | "widget";
|
|
2785
2796
|
name: string;
|
|
@@ -2788,6 +2799,7 @@ declare const SharedComponentsManifestSchema: z.ZodObject<{
|
|
|
2788
2799
|
usedIn: string[];
|
|
2789
2800
|
description?: string | undefined;
|
|
2790
2801
|
createdAt?: string | undefined;
|
|
2802
|
+
propsInterface?: string | undefined;
|
|
2791
2803
|
}, {
|
|
2792
2804
|
type: "layout" | "section" | "widget";
|
|
2793
2805
|
name: string;
|
|
@@ -2796,6 +2808,7 @@ declare const SharedComponentsManifestSchema: z.ZodObject<{
|
|
|
2796
2808
|
description?: string | undefined;
|
|
2797
2809
|
createdAt?: string | undefined;
|
|
2798
2810
|
usedIn?: string[] | undefined;
|
|
2811
|
+
propsInterface?: string | undefined;
|
|
2799
2812
|
}>, "many">>;
|
|
2800
2813
|
/** Next numeric id for new entries (CID-XXX → nextId = 4 for CID-004) */
|
|
2801
2814
|
nextId: z.ZodDefault<z.ZodNumber>;
|
|
@@ -2808,6 +2821,7 @@ declare const SharedComponentsManifestSchema: z.ZodObject<{
|
|
|
2808
2821
|
usedIn: string[];
|
|
2809
2822
|
description?: string | undefined;
|
|
2810
2823
|
createdAt?: string | undefined;
|
|
2824
|
+
propsInterface?: string | undefined;
|
|
2811
2825
|
}[];
|
|
2812
2826
|
nextId: number;
|
|
2813
2827
|
}, {
|
|
@@ -2819,6 +2833,7 @@ declare const SharedComponentsManifestSchema: z.ZodObject<{
|
|
|
2819
2833
|
description?: string | undefined;
|
|
2820
2834
|
createdAt?: string | undefined;
|
|
2821
2835
|
usedIn?: string[] | undefined;
|
|
2836
|
+
propsInterface?: string | undefined;
|
|
2822
2837
|
}[] | undefined;
|
|
2823
2838
|
nextId?: number | undefined;
|
|
2824
2839
|
}>;
|
|
@@ -3130,6 +3145,7 @@ interface CreateSharedComponentInput {
|
|
|
3130
3145
|
file: string;
|
|
3131
3146
|
usedIn?: string[];
|
|
3132
3147
|
description?: string;
|
|
3148
|
+
propsInterface?: string;
|
|
3133
3149
|
}
|
|
3134
3150
|
/**
|
|
3135
3151
|
* Add a new shared component: allocate CID, set createdAt, append to shared, increment nextId.
|
|
@@ -3539,6 +3555,8 @@ interface GenerateSharedComponentInput {
|
|
|
3539
3555
|
usedIn?: string[];
|
|
3540
3556
|
/** If true, overwrite an existing component with the same name instead of creating a uniquely-named copy. */
|
|
3541
3557
|
overwrite?: boolean;
|
|
3558
|
+
/** TypeScript props interface body, e.g. "{ title: string; icon: React.ReactNode }". */
|
|
3559
|
+
propsInterface?: string;
|
|
3542
3560
|
}
|
|
3543
3561
|
interface GenerateSharedComponentResult {
|
|
3544
3562
|
id: string;
|
|
@@ -3864,6 +3882,28 @@ interface LoginContent extends BasePageContent {
|
|
|
3864
3882
|
interface RegisterContent extends BasePageContent {
|
|
3865
3883
|
loginRoute?: string;
|
|
3866
3884
|
}
|
|
3885
|
+
interface TeamContent extends BasePageContent {
|
|
3886
|
+
members?: Array<{
|
|
3887
|
+
name: string;
|
|
3888
|
+
role: string;
|
|
3889
|
+
email?: string;
|
|
3890
|
+
avatar?: string;
|
|
3891
|
+
}>;
|
|
3892
|
+
}
|
|
3893
|
+
interface TasksContent extends BasePageContent {
|
|
3894
|
+
tasks?: Array<{
|
|
3895
|
+
title: string;
|
|
3896
|
+
status: string;
|
|
3897
|
+
assignee?: string;
|
|
3898
|
+
priority?: string;
|
|
3899
|
+
}>;
|
|
3900
|
+
}
|
|
3901
|
+
interface TaskDetailContent extends BasePageContent {
|
|
3902
|
+
taskId?: string;
|
|
3903
|
+
}
|
|
3904
|
+
interface ResetPasswordContent extends BasePageContent {
|
|
3905
|
+
loginRoute?: string;
|
|
3906
|
+
}
|
|
3867
3907
|
interface ChangelogContent extends BasePageContent {
|
|
3868
3908
|
versions: Array<{
|
|
3869
3909
|
version: string;
|
|
@@ -3921,6 +3961,18 @@ type PageContent = {
|
|
|
3921
3961
|
} | {
|
|
3922
3962
|
pageType: 'register';
|
|
3923
3963
|
content: RegisterContent;
|
|
3964
|
+
} | {
|
|
3965
|
+
pageType: 'team';
|
|
3966
|
+
content: TeamContent;
|
|
3967
|
+
} | {
|
|
3968
|
+
pageType: 'tasks';
|
|
3969
|
+
content: TasksContent;
|
|
3970
|
+
} | {
|
|
3971
|
+
pageType: 'task-detail';
|
|
3972
|
+
content: TaskDetailContent;
|
|
3973
|
+
} | {
|
|
3974
|
+
pageType: 'reset-password';
|
|
3975
|
+
content: ResetPasswordContent;
|
|
3924
3976
|
};
|
|
3925
3977
|
|
|
3926
3978
|
type TemplateFn = (content: any, options: TemplateOptions) => string;
|
package/dist/index.js
CHANGED
|
@@ -295,7 +295,9 @@ var DesignSystemConfigSchema = z.object({
|
|
|
295
295
|
// Deployment
|
|
296
296
|
deployTarget: z.enum(["vercel", "netlify", "cloudflare", "self-hosted"]).optional(),
|
|
297
297
|
// Auto-scaffold linked pages (e.g. login → signup, forgot-password)
|
|
298
|
-
autoScaffold: z.boolean().default(false)
|
|
298
|
+
autoScaffold: z.boolean().default(false),
|
|
299
|
+
// True when the home page is the init placeholder (not yet AI-generated)
|
|
300
|
+
homePagePlaceholder: z.boolean().default(false)
|
|
299
301
|
}),
|
|
300
302
|
// Timestamps
|
|
301
303
|
createdAt: z.string().datetime(),
|
|
@@ -421,7 +423,8 @@ var EXAMPLE_MULTIPAGE_CONFIG = {
|
|
|
421
423
|
framework: "next",
|
|
422
424
|
typescript: true,
|
|
423
425
|
cssFramework: "tailwind",
|
|
424
|
-
autoScaffold: false
|
|
426
|
+
autoScaffold: false,
|
|
427
|
+
homePagePlaceholder: false
|
|
425
428
|
},
|
|
426
429
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
427
430
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -437,7 +440,8 @@ var EXAMPLE_SPA_CONFIG = {
|
|
|
437
440
|
router: "react-router",
|
|
438
441
|
typescript: true,
|
|
439
442
|
cssFramework: "tailwind",
|
|
440
|
-
autoScaffold: false
|
|
443
|
+
autoScaffold: false,
|
|
444
|
+
homePagePlaceholder: false
|
|
441
445
|
},
|
|
442
446
|
features: {
|
|
443
447
|
...EXAMPLE_MULTIPAGE_CONFIG.features,
|
|
@@ -464,7 +468,9 @@ var SharedComponentEntrySchema = z2.object({
|
|
|
464
468
|
usedIn: z2.array(z2.string()).default([]),
|
|
465
469
|
createdAt: z2.string().datetime().optional(),
|
|
466
470
|
/** Human-readable description */
|
|
467
|
-
description: z2.string().optional()
|
|
471
|
+
description: z2.string().optional(),
|
|
472
|
+
/** TypeScript props interface body, e.g. "{ icon: React.ReactNode; title: string }" */
|
|
473
|
+
propsInterface: z2.string().optional()
|
|
468
474
|
});
|
|
469
475
|
var SharedComponentsManifestSchema = z2.object({
|
|
470
476
|
shared: z2.array(SharedComponentEntrySchema).default([]),
|
|
@@ -1970,6 +1976,7 @@ function createEntry(manifest, input) {
|
|
|
1970
1976
|
file: input.file,
|
|
1971
1977
|
usedIn: input.usedIn ?? [],
|
|
1972
1978
|
description: input.description,
|
|
1979
|
+
propsInterface: input.propsInterface,
|
|
1973
1980
|
createdAt: now
|
|
1974
1981
|
};
|
|
1975
1982
|
const nextManifest = {
|
|
@@ -6818,7 +6825,8 @@ async function generateSharedComponent(projectRoot, input) {
|
|
|
6818
6825
|
type: input.type,
|
|
6819
6826
|
file: filePath,
|
|
6820
6827
|
usedIn: input.usedIn ?? [],
|
|
6821
|
-
description: input.description
|
|
6828
|
+
description: input.description,
|
|
6829
|
+
propsInterface: input.propsInterface
|
|
6822
6830
|
});
|
|
6823
6831
|
await saveManifest(projectRoot, nextManifest);
|
|
6824
6832
|
return { id: entry.id, name: entry.name, file: entry.file };
|
|
@@ -8928,6 +8936,269 @@ export default function ${pageName}() {
|
|
|
8928
8936
|
`;
|
|
8929
8937
|
}
|
|
8930
8938
|
|
|
8939
|
+
// src/generators/templates/pages/team.ts
|
|
8940
|
+
function teamTemplate(content, options) {
|
|
8941
|
+
const { title, description, members } = content;
|
|
8942
|
+
const { pageName } = options;
|
|
8943
|
+
const memberList = (members && members.length > 0 ? members : [
|
|
8944
|
+
{ name: "Sarah Chen", role: "CEO & Founder", email: "sarah@example.com" },
|
|
8945
|
+
{ name: "Marcus Kim", role: "CTO", email: "marcus@example.com" },
|
|
8946
|
+
{ name: "Elena Rodriguez", role: "Head of Design", email: "elena@example.com" },
|
|
8947
|
+
{ name: "James Park", role: "Lead Engineer", email: "james@example.com" }
|
|
8948
|
+
]).map(
|
|
8949
|
+
(m) => ` <div key="${m.name}" className="${D.card} p-6">
|
|
8950
|
+
<div className="flex items-center gap-4">
|
|
8951
|
+
<div className="flex size-12 items-center justify-center rounded-full bg-muted ${D.cardTitle}">
|
|
8952
|
+
${m.name.split(" ").map((n) => n[0]).join("")}
|
|
8953
|
+
</div>
|
|
8954
|
+
<div className="space-y-1">
|
|
8955
|
+
<h3 className="${D.cardTitle}">${m.name}</h3>
|
|
8956
|
+
<p className="${D.cardDesc}">${m.role}</p>
|
|
8957
|
+
</div>
|
|
8958
|
+
</div>
|
|
8959
|
+
</div>`
|
|
8960
|
+
).join("\n");
|
|
8961
|
+
return `import { Metadata } from 'next'
|
|
8962
|
+
|
|
8963
|
+
export const metadata: Metadata = {
|
|
8964
|
+
title: '${title}',
|
|
8965
|
+
description: '${description}',
|
|
8966
|
+
}
|
|
8967
|
+
|
|
8968
|
+
export default function ${pageName}() {
|
|
8969
|
+
return (
|
|
8970
|
+
<main className="${D.pageWrapper}">
|
|
8971
|
+
<div>
|
|
8972
|
+
<h1 className="${D.pageTitle}">${title}</h1>
|
|
8973
|
+
<p className="${D.muted}">${description}</p>
|
|
8974
|
+
</div>
|
|
8975
|
+
<div className="${D.statsGrid}">
|
|
8976
|
+
${memberList}
|
|
8977
|
+
</div>
|
|
8978
|
+
</main>
|
|
8979
|
+
)
|
|
8980
|
+
}
|
|
8981
|
+
`;
|
|
8982
|
+
}
|
|
8983
|
+
|
|
8984
|
+
// src/generators/templates/pages/tasks.ts
|
|
8985
|
+
function tasksTemplate(content, options) {
|
|
8986
|
+
const { title, description, tasks } = content;
|
|
8987
|
+
const { pageName } = options;
|
|
8988
|
+
const taskList = tasks && tasks.length > 0 ? tasks : [
|
|
8989
|
+
{ title: "Design landing page", status: "In Progress", assignee: "Sarah", priority: "High" },
|
|
8990
|
+
{ title: "Set up CI/CD pipeline", status: "Done", assignee: "Marcus", priority: "Medium" },
|
|
8991
|
+
{ title: "Write API documentation", status: "To Do", assignee: "Elena", priority: "Low" },
|
|
8992
|
+
{ title: "Fix login redirect bug", status: "In Progress", assignee: "James", priority: "High" },
|
|
8993
|
+
{ title: "Update dependencies", status: "To Do", assignee: "Marcus", priority: "Medium" }
|
|
8994
|
+
];
|
|
8995
|
+
const statusColor = {
|
|
8996
|
+
Done: "bg-emerald-500/10 text-emerald-500",
|
|
8997
|
+
"In Progress": "bg-blue-500/10 text-blue-500",
|
|
8998
|
+
"To Do": "bg-zinc-500/10 text-zinc-400"
|
|
8999
|
+
};
|
|
9000
|
+
const priorityColor = {
|
|
9001
|
+
High: "bg-red-500/10 text-red-500",
|
|
9002
|
+
Medium: "bg-yellow-500/10 text-yellow-500",
|
|
9003
|
+
Low: "bg-zinc-500/10 text-zinc-400"
|
|
9004
|
+
};
|
|
9005
|
+
const rows = taskList.map(
|
|
9006
|
+
(t) => ` <div className="${D.listItem}">
|
|
9007
|
+
<div className="flex items-center gap-3">
|
|
9008
|
+
<span className="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${statusColor[t.status] || statusColor["To Do"]}">${t.status}</span>
|
|
9009
|
+
<span className="${D.body} font-medium">${t.title}</span>
|
|
9010
|
+
</div>
|
|
9011
|
+
<div className="flex items-center gap-3">
|
|
9012
|
+
${t.priority ? `<span className="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${priorityColor[t.priority] || priorityColor["Medium"]}">${t.priority}</span>` : ""}
|
|
9013
|
+
${t.assignee ? `<span className="${D.mutedXs}">${t.assignee}</span>` : ""}
|
|
9014
|
+
</div>
|
|
9015
|
+
</div>`
|
|
9016
|
+
).join("\n");
|
|
9017
|
+
return `"use client"
|
|
9018
|
+
|
|
9019
|
+
import { useState } from 'react'
|
|
9020
|
+
import { Search } from 'lucide-react'
|
|
9021
|
+
import { Input } from '@/components/ui/input'
|
|
9022
|
+
|
|
9023
|
+
export default function ${pageName}() {
|
|
9024
|
+
const [search, setSearch] = useState('')
|
|
9025
|
+
|
|
9026
|
+
return (
|
|
9027
|
+
<main className="${D.pageWrapper}">
|
|
9028
|
+
<div className="flex items-center justify-between">
|
|
9029
|
+
<div>
|
|
9030
|
+
<h1 className="${D.pageTitle}">${title}</h1>
|
|
9031
|
+
<p className="${D.muted}">${description}</p>
|
|
9032
|
+
</div>
|
|
9033
|
+
</div>
|
|
9034
|
+
|
|
9035
|
+
<div className="relative max-w-sm">
|
|
9036
|
+
<Search className="absolute left-3 top-1/2 ${D.icon} -translate-y-1/2" />
|
|
9037
|
+
<Input
|
|
9038
|
+
placeholder="Search tasks..."
|
|
9039
|
+
value={search}
|
|
9040
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
9041
|
+
className="pl-9"
|
|
9042
|
+
/>
|
|
9043
|
+
</div>
|
|
9044
|
+
|
|
9045
|
+
<div className="${D.card} divide-y">
|
|
9046
|
+
${rows}
|
|
9047
|
+
</div>
|
|
9048
|
+
</main>
|
|
9049
|
+
)
|
|
9050
|
+
}
|
|
9051
|
+
`;
|
|
9052
|
+
}
|
|
9053
|
+
|
|
9054
|
+
// src/generators/templates/pages/task-detail.ts
|
|
9055
|
+
function taskDetailTemplate(content, options) {
|
|
9056
|
+
const { title, description } = content;
|
|
9057
|
+
const { pageName } = options;
|
|
9058
|
+
return `"use client"
|
|
9059
|
+
|
|
9060
|
+
import { useState } from 'react'
|
|
9061
|
+
import { Button } from '@/components/ui/button'
|
|
9062
|
+
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
|
9063
|
+
import { ArrowLeft } from 'lucide-react'
|
|
9064
|
+
import Link from 'next/link'
|
|
9065
|
+
|
|
9066
|
+
export default function ${pageName}() {
|
|
9067
|
+
const [status, setStatus] = useState('In Progress')
|
|
9068
|
+
|
|
9069
|
+
return (
|
|
9070
|
+
<main className="${D.pageWrapper}">
|
|
9071
|
+
<div className="flex items-center gap-2">
|
|
9072
|
+
<Link href="/tasks">
|
|
9073
|
+
<Button variant="ghost" size="icon">
|
|
9074
|
+
<ArrowLeft className="${D.icon}" />
|
|
9075
|
+
</Button>
|
|
9076
|
+
</Link>
|
|
9077
|
+
<div>
|
|
9078
|
+
<h1 className="${D.pageTitle}">${title}</h1>
|
|
9079
|
+
<p className="${D.muted}">${description}</p>
|
|
9080
|
+
</div>
|
|
9081
|
+
</div>
|
|
9082
|
+
|
|
9083
|
+
<div className="${D.grid2}">
|
|
9084
|
+
<Card>
|
|
9085
|
+
<CardHeader>
|
|
9086
|
+
<CardTitle className="${D.cardTitle}">Details</CardTitle>
|
|
9087
|
+
</CardHeader>
|
|
9088
|
+
<CardContent className="${D.formGap}">
|
|
9089
|
+
<div className="${D.fieldGroup}">
|
|
9090
|
+
<span className="${D.mutedXs}">Status</span>
|
|
9091
|
+
<span className="inline-flex items-center rounded-full bg-blue-500/10 px-2 py-0.5 text-xs font-medium text-blue-500">{status}</span>
|
|
9092
|
+
</div>
|
|
9093
|
+
<div className="${D.fieldGroup}">
|
|
9094
|
+
<span className="${D.mutedXs}">Priority</span>
|
|
9095
|
+
<span className="inline-flex items-center rounded-full bg-red-500/10 px-2 py-0.5 text-xs font-medium text-red-500">High</span>
|
|
9096
|
+
</div>
|
|
9097
|
+
<div className="${D.fieldGroup}">
|
|
9098
|
+
<span className="${D.mutedXs}">Assignee</span>
|
|
9099
|
+
<span className="${D.body}">Sarah Chen</span>
|
|
9100
|
+
</div>
|
|
9101
|
+
<div className="${D.fieldGroup}">
|
|
9102
|
+
<span className="${D.mutedXs}">Due Date</span>
|
|
9103
|
+
<span className="${D.body}">Jan 15, 2025</span>
|
|
9104
|
+
</div>
|
|
9105
|
+
</CardContent>
|
|
9106
|
+
</Card>
|
|
9107
|
+
|
|
9108
|
+
<Card>
|
|
9109
|
+
<CardHeader>
|
|
9110
|
+
<CardTitle className="${D.cardTitle}">Activity</CardTitle>
|
|
9111
|
+
</CardHeader>
|
|
9112
|
+
<CardContent>
|
|
9113
|
+
<div className="space-y-3">
|
|
9114
|
+
<div className="${D.listItem}">
|
|
9115
|
+
<span className="${D.body}">Task created</span>
|
|
9116
|
+
<span className="${D.mutedXs}">2 days ago</span>
|
|
9117
|
+
</div>
|
|
9118
|
+
<div className="${D.listItem}">
|
|
9119
|
+
<span className="${D.body}">Status changed to In Progress</span>
|
|
9120
|
+
<span className="${D.mutedXs}">1 day ago</span>
|
|
9121
|
+
</div>
|
|
9122
|
+
</div>
|
|
9123
|
+
</CardContent>
|
|
9124
|
+
</Card>
|
|
9125
|
+
</div>
|
|
9126
|
+
</main>
|
|
9127
|
+
)
|
|
9128
|
+
}
|
|
9129
|
+
`;
|
|
9130
|
+
}
|
|
9131
|
+
|
|
9132
|
+
// src/generators/templates/pages/reset-password.ts
|
|
9133
|
+
function resetPasswordTemplate(content, options) {
|
|
9134
|
+
const { title, description, loginRoute } = content;
|
|
9135
|
+
const { pageName } = options;
|
|
9136
|
+
return `"use client"
|
|
9137
|
+
|
|
9138
|
+
import { useState } from 'react'
|
|
9139
|
+
import Link from 'next/link'
|
|
9140
|
+
import { Button } from '@/components/ui/button'
|
|
9141
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
|
9142
|
+
import { Input } from '@/components/ui/input'
|
|
9143
|
+
import { Label } from '@/components/ui/label'
|
|
9144
|
+
|
|
9145
|
+
export default function ${pageName}() {
|
|
9146
|
+
const [password, setPassword] = useState('')
|
|
9147
|
+
const [confirmPassword, setConfirmPassword] = useState('')
|
|
9148
|
+
|
|
9149
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
9150
|
+
e.preventDefault()
|
|
9151
|
+
}
|
|
9152
|
+
|
|
9153
|
+
return (
|
|
9154
|
+
<div className="${D.centeredForm}">
|
|
9155
|
+
<div className="${D.formContainer}">
|
|
9156
|
+
<Card>
|
|
9157
|
+
<CardHeader className="text-center">
|
|
9158
|
+
<CardTitle className="text-xl">${title}</CardTitle>
|
|
9159
|
+
<CardDescription>${description}</CardDescription>
|
|
9160
|
+
</CardHeader>
|
|
9161
|
+
<CardContent>
|
|
9162
|
+
<form onSubmit={handleSubmit} className="${D.formGap}">
|
|
9163
|
+
<div className="${D.fieldGroup}">
|
|
9164
|
+
<Label htmlFor="password">New Password</Label>
|
|
9165
|
+
<Input
|
|
9166
|
+
id="password"
|
|
9167
|
+
type="password"
|
|
9168
|
+
placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
9169
|
+
value={password}
|
|
9170
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
9171
|
+
required
|
|
9172
|
+
/>
|
|
9173
|
+
</div>
|
|
9174
|
+
<div className="${D.fieldGroup}">
|
|
9175
|
+
<Label htmlFor="confirmPassword">Confirm Password</Label>
|
|
9176
|
+
<Input
|
|
9177
|
+
id="confirmPassword"
|
|
9178
|
+
type="password"
|
|
9179
|
+
placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
9180
|
+
value={confirmPassword}
|
|
9181
|
+
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
9182
|
+
required
|
|
9183
|
+
/>
|
|
9184
|
+
</div>
|
|
9185
|
+
<Button type="submit" className="w-full">Reset password</Button>
|
|
9186
|
+
</form>
|
|
9187
|
+
<p className="mt-4 text-center text-sm text-muted-foreground">
|
|
9188
|
+
Remember your password?{' '}
|
|
9189
|
+
<Link href="${loginRoute || "/login"}" className="text-foreground underline underline-offset-4 hover:text-foreground/80 transition-colors">
|
|
9190
|
+
Sign in
|
|
9191
|
+
</Link>
|
|
9192
|
+
</p>
|
|
9193
|
+
</CardContent>
|
|
9194
|
+
</Card>
|
|
9195
|
+
</div>
|
|
9196
|
+
</div>
|
|
9197
|
+
)
|
|
9198
|
+
}
|
|
9199
|
+
`;
|
|
9200
|
+
}
|
|
9201
|
+
|
|
8931
9202
|
// src/generators/templates/pages/index.ts
|
|
8932
9203
|
var TEMPLATE_REGISTRY = {
|
|
8933
9204
|
dashboard: dashboardTemplate,
|
|
@@ -8943,7 +9214,11 @@ var TEMPLATE_REGISTRY = {
|
|
|
8943
9214
|
faq: faqTemplate,
|
|
8944
9215
|
changelog: changelogTemplate,
|
|
8945
9216
|
login: loginTemplate,
|
|
8946
|
-
register: registerTemplate
|
|
9217
|
+
register: registerTemplate,
|
|
9218
|
+
team: teamTemplate,
|
|
9219
|
+
tasks: tasksTemplate,
|
|
9220
|
+
"task-detail": taskDetailTemplate,
|
|
9221
|
+
"reset-password": resetPasswordTemplate
|
|
8947
9222
|
};
|
|
8948
9223
|
function getTemplateForPageType(pageType) {
|
|
8949
9224
|
return TEMPLATE_REGISTRY[pageType] ?? null;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.5.
|
|
6
|
+
"version": "0.5.15",
|
|
7
7
|
"description": "Core design system engine for Coherent",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./dist/index.js",
|
|
@@ -32,12 +32,6 @@
|
|
|
32
32
|
],
|
|
33
33
|
"author": "Coherent Design Method",
|
|
34
34
|
"license": "MIT",
|
|
35
|
-
"scripts": {
|
|
36
|
-
"dev": "tsup --watch",
|
|
37
|
-
"build": "tsup",
|
|
38
|
-
"typecheck": "tsc --noEmit",
|
|
39
|
-
"test": "vitest"
|
|
40
|
-
},
|
|
41
35
|
"dependencies": {
|
|
42
36
|
"handlebars": "^4.7.8",
|
|
43
37
|
"zod": "^3.22.4"
|
|
@@ -47,5 +41,11 @@
|
|
|
47
41
|
"tsup": "^8.0.1",
|
|
48
42
|
"typescript": "^5.3.3",
|
|
49
43
|
"vitest": "^1.2.1"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"dev": "tsup --watch",
|
|
47
|
+
"build": "tsup",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "vitest"
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|