@donotdev/cli 0.0.18 → 0.0.20
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/dependencies-matrix.json +42 -55
- package/dist/bin/commands/bump.js +5 -2
- package/dist/bin/commands/coach.js +8177 -0
- package/dist/bin/commands/create-app.js +6 -6
- package/dist/bin/commands/create-project.js +23 -9
- package/dist/bin/commands/deploy.js +99 -59
- package/dist/bin/commands/doctor.js +243 -698
- package/dist/bin/commands/emu.js +2 -2
- package/dist/bin/commands/format.js +4 -1
- package/dist/bin/commands/get-demo.js +8351 -0
- package/dist/bin/commands/make-admin.js +773 -152
- package/dist/bin/commands/setup.js +524 -1713
- package/dist/bin/commands/staging.js +17870 -0
- package/dist/bin/commands/sync-secrets.js +2 -11
- package/dist/bin/commands/type-check.js +7738 -1712
- package/dist/bin/dndev.js +868 -199
- package/dist/bin/donotdev.js +868 -199
- package/dist/index.js +127 -67
- package/package.json +1 -1
- package/templates/app-demo/index.html.example +147 -10
- package/templates/app-demo/public/apple-touch-icon.png.example +0 -0
- package/templates/app-demo/public/favicon.svg.example +1 -0
- package/templates/app-demo/public/icon-192x192.png.example +0 -0
- package/templates/app-demo/public/icon-512x512.png.example +0 -0
- package/templates/app-demo/src/App.tsx.example +7 -11
- package/templates/app-demo/src/config/app.ts.example +13 -48
- package/templates/app-demo/src/entities/booking.ts.example +75 -0
- package/templates/app-demo/src/entities/onboarding.ts.example +160 -0
- package/templates/app-demo/src/entities/product.ts.example +50 -0
- package/templates/app-demo/src/entities/quote.ts.example +70 -0
- package/templates/app-demo/src/globals.css.example +5 -1
- package/templates/app-demo/src/main.tsx.example +13 -7
- package/templates/app-demo/src/pages/ChangelogPage.tsx.example +41 -0
- package/templates/app-demo/src/pages/ConditionalFormPage.tsx.example +88 -0
- package/templates/app-demo/src/pages/DashboardPage.tsx.example +17 -0
- package/templates/app-demo/src/pages/HomePage.tsx.example +339 -60
- package/templates/app-demo/src/pages/OnboardingPage.tsx.example +47 -0
- package/templates/app-demo/src/pages/PricingPage.tsx.example +41 -0
- package/templates/app-demo/src/pages/ProductsPage.tsx.example +19 -0
- package/templates/app-demo/src/pages/ProfilePage.tsx.example +18 -0
- package/templates/app-demo/src/pages/SettingsPage.tsx.example +17 -0
- package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +118 -0
- package/templates/app-demo/src/pages/ShowcasePage.tsx.example +93 -0
- package/templates/app-demo/src/pages/components/ComponentRenderer.tsx.example +147 -51
- package/templates/app-demo/src/pages/components/ComponentsData.tsx.example +103 -21
- package/templates/app-demo/src/pages/components/componentConfig.ts.example +139 -59
- package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +25 -0
- package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +23 -0
- package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +23 -0
- package/templates/app-demo/src/themes.css.example +289 -77
- package/templates/app-demo/stats.html.example +4949 -0
- package/templates/app-demo/tsconfig.json.example +1 -1
- package/templates/app-demo/vite.config.ts.example +23 -48
- package/templates/app-expo/README.md.example +1 -1
- package/templates/app-expo/app/index.tsx.example +1 -1
- package/templates/app-next/src/locales/home_en.json.example +6 -6
- package/templates/app-vite/src/locales/home_en.json.example +6 -6
- package/templates/app-vite/src/pages/HomePage.tsx.example +8 -10
- package/templates/overlay-firebase/env.fragment.example +1 -1
- package/templates/overlay-firebase/env.fragment.expo.example +1 -1
- package/templates/overlay-firebase/env.fragment.nextjs.example +1 -1
- package/templates/overlay-supabase/env.fragment.example +1 -1
- package/templates/overlay-supabase/env.fragment.expo.example +1 -1
- package/templates/overlay-supabase/env.fragment.nextjs.example +1 -1
- package/templates/overlay-vercel/env.fragment.example +1 -1
- package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
- package/templates/root-consumer/AI.md.example +4 -3
- package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +21 -6
- package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +16 -179
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +19 -21
- package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +14 -3
- package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
- package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
- package/templates/root-consumer/guides/dndev/SETUP_BLOG.md.example +19 -2
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +35 -1
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +17 -12
- package/templates/root-consumer/guides/dndev/SETUP_LAYOUTS.md.example +32 -0
- package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +1 -1
- package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +19 -15
- package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +2 -2
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +17 -12
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +37 -16
- package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +18 -18
- package/templates/root-consumer/guides/dndev/advanced/COOKIE_REFERENCE.md.example +252 -252
- package/templates/root-consumer/guides/dndev/advanced/VERSION_CONTROL.md.example +174 -174
- package/templates/root-consumer/guides/dndev/essences_reference.css.example +119 -2
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +14 -0
- package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +6 -0
- package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +14 -0
- package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +4 -5
- package/templates/root-consumer/guides/wai-way/page_patterns.md.example +2 -2
- package/dist/bin/commands/agent-setup.d.ts +0 -6
- package/dist/bin/commands/agent-setup.d.ts.map +0 -1
- package/dist/bin/commands/agent-setup.js.map +0 -1
- package/dist/bin/commands/build.d.ts +0 -11
- package/dist/bin/commands/build.d.ts.map +0 -1
- package/dist/bin/commands/build.js.map +0 -1
- package/dist/bin/commands/bump.d.ts +0 -11
- package/dist/bin/commands/bump.d.ts.map +0 -1
- package/dist/bin/commands/bump.js.map +0 -1
- package/dist/bin/commands/cacheout.d.ts +0 -11
- package/dist/bin/commands/cacheout.d.ts.map +0 -1
- package/dist/bin/commands/cacheout.js.map +0 -1
- package/dist/bin/commands/create-app.d.ts +0 -11
- package/dist/bin/commands/create-app.d.ts.map +0 -1
- package/dist/bin/commands/create-app.js.map +0 -1
- package/dist/bin/commands/create-project.d.ts +0 -11
- package/dist/bin/commands/create-project.d.ts.map +0 -1
- package/dist/bin/commands/create-project.js.map +0 -1
- package/dist/bin/commands/deploy.d.ts +0 -11
- package/dist/bin/commands/deploy.d.ts.map +0 -1
- package/dist/bin/commands/deploy.js.map +0 -1
- package/dist/bin/commands/dev.d.ts +0 -11
- package/dist/bin/commands/dev.d.ts.map +0 -1
- package/dist/bin/commands/dev.js.map +0 -1
- package/dist/bin/commands/doctor.d.ts +0 -6
- package/dist/bin/commands/doctor.d.ts.map +0 -1
- package/dist/bin/commands/doctor.js.map +0 -1
- package/dist/bin/commands/emu.d.ts +0 -11
- package/dist/bin/commands/emu.d.ts.map +0 -1
- package/dist/bin/commands/emu.js.map +0 -1
- package/dist/bin/commands/format.d.ts +0 -11
- package/dist/bin/commands/format.d.ts.map +0 -1
- package/dist/bin/commands/format.js.map +0 -1
- package/dist/bin/commands/make-admin.d.ts +0 -11
- package/dist/bin/commands/make-admin.d.ts.map +0 -1
- package/dist/bin/commands/make-admin.js.map +0 -1
- package/dist/bin/commands/preview.d.ts +0 -11
- package/dist/bin/commands/preview.d.ts.map +0 -1
- package/dist/bin/commands/preview.js.map +0 -1
- package/dist/bin/commands/setup.d.ts +0 -6
- package/dist/bin/commands/setup.d.ts.map +0 -1
- package/dist/bin/commands/setup.js.map +0 -1
- package/dist/bin/commands/sync-secrets.d.ts +0 -11
- package/dist/bin/commands/sync-secrets.d.ts.map +0 -1
- package/dist/bin/commands/sync-secrets.js.map +0 -1
- package/dist/bin/commands/type-check.d.ts +0 -14
- package/dist/bin/commands/type-check.d.ts.map +0 -1
- package/dist/bin/commands/type-check.js.map +0 -1
- package/dist/bin/commands/wai.d.ts +0 -11
- package/dist/bin/commands/wai.d.ts.map +0 -1
- package/dist/bin/commands/wai.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/templates/app-demo/src/components/ThemeToggle.tsx.example +0 -48
- package/templates/app-demo/src/pages/DetailPage.tsx.example +0 -103
- package/templates/app-demo/src/pages/FullPage.tsx.example +0 -142
- package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +0 -266
- package/templates/app-demo/src/pages/components/LayoutRoute.tsx.example +0 -20
|
@@ -1,79 +1,358 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
// apps/demo/src/pages/HomePage.tsx
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
4
|
+
import {
|
|
5
|
+
Zap,
|
|
6
|
+
Shield,
|
|
7
|
+
Rocket,
|
|
8
|
+
UserPlus,
|
|
9
|
+
Settings,
|
|
10
|
+
Play,
|
|
11
|
+
Quote,
|
|
12
|
+
} from 'lucide-react';
|
|
5
13
|
|
|
6
14
|
import {
|
|
7
15
|
Badge,
|
|
16
|
+
BADGE_VARIANT,
|
|
17
|
+
Button,
|
|
18
|
+
BUTTON_VARIANT,
|
|
19
|
+
CallToAction,
|
|
8
20
|
Card,
|
|
9
|
-
|
|
21
|
+
CARD_VARIANT,
|
|
22
|
+
Carousel,
|
|
23
|
+
HeroSection,
|
|
24
|
+
Marquee,
|
|
25
|
+
Roadmap,
|
|
10
26
|
Section,
|
|
27
|
+
SplitReveal,
|
|
11
28
|
Stack,
|
|
29
|
+
Text,
|
|
12
30
|
} from '@donotdev/components';
|
|
31
|
+
import { useTranslation } from '@donotdev/core';
|
|
32
|
+
import { FeatureCard, PageContainer } from '@donotdev/ui';
|
|
13
33
|
|
|
14
|
-
import {
|
|
15
|
-
COMPONENT_CONFIGS,
|
|
16
|
-
getCSSFamilies,
|
|
17
|
-
} from './components/componentConfig';
|
|
18
|
-
import type { CSSFamily } from './components/ComponentsData';
|
|
34
|
+
import type { RoadmapStep } from '@donotdev/components';
|
|
19
35
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
36
|
+
// -- Fake testimonials for Marquee showcase --
|
|
37
|
+
const testimonials = [
|
|
38
|
+
{
|
|
39
|
+
name: 'Sarah K.',
|
|
40
|
+
role: 'CTO @ Fintech',
|
|
41
|
+
text: 'Shipped our MVP in 3 weeks. CRUD, auth, billing — all wired.',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'Marco R.',
|
|
45
|
+
role: 'Solo Founder',
|
|
46
|
+
text: 'I replaced 6 libraries with one framework. No regrets.',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'Priya N.',
|
|
50
|
+
role: 'Lead Dev',
|
|
51
|
+
text: 'The type safety alone saved us from 2 production bugs on day one.',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'James L.',
|
|
55
|
+
role: 'Agency Owner',
|
|
56
|
+
text: 'We spin up client projects in hours now, not weeks.',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'Yuki T.',
|
|
60
|
+
role: 'Indie Hacker',
|
|
61
|
+
text: 'Dark mode, RTL, i18n — all free. I just write features.',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'Elena M.',
|
|
65
|
+
role: 'Staff Engineer',
|
|
66
|
+
text: 'Best DX I have seen in a React meta-framework. Period.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'David C.',
|
|
70
|
+
role: 'Freelancer',
|
|
71
|
+
text: 'Entity definitions + auto CRUD cut my project setup time by 80%.',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'Lisa W.',
|
|
75
|
+
role: 'Tech Lead',
|
|
76
|
+
text: 'Finally a framework where the components actually respect the theme system.',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'Tom H.',
|
|
80
|
+
role: 'Product Engineer',
|
|
81
|
+
text: 'Billing integration took 20 minutes. Stripe webhooks just work.',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'Aisha B.',
|
|
85
|
+
role: 'Startup CTO',
|
|
86
|
+
text: 'We went from zero to production in 2 weeks. Not a joke.',
|
|
87
|
+
},
|
|
88
|
+
];
|
|
24
89
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
90
|
+
// -- Carousel items: showcase different component types --
|
|
91
|
+
const showcaseItems = [
|
|
92
|
+
{
|
|
93
|
+
title: 'Reveal Animations',
|
|
94
|
+
description:
|
|
95
|
+
'Staggered, directional entrance animations with viewport detection.',
|
|
96
|
+
variant: CARD_VARIANT.ACCENT,
|
|
97
|
+
icon: Zap,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
title: 'Smart Forms',
|
|
101
|
+
description:
|
|
102
|
+
'Conditional fields, draft validation, multi-step wizards — all from entity definitions.',
|
|
103
|
+
variant: CARD_VARIANT.DEFAULT,
|
|
104
|
+
icon: Settings,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
title: 'Carousel & Marquee',
|
|
108
|
+
description:
|
|
109
|
+
'Autoplay, swipe, infinite loop, momentum physics. This very section.',
|
|
110
|
+
variant: CARD_VARIANT.DEFAULT,
|
|
111
|
+
icon: Play,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
title: 'Theme System',
|
|
115
|
+
description:
|
|
116
|
+
'5 themes with full design token coverage. Switch live, no flash.',
|
|
117
|
+
variant: CARD_VARIANT.DEFAULT,
|
|
118
|
+
icon: Shield,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
title: 'StackedCards & Bento',
|
|
122
|
+
description:
|
|
123
|
+
'Scroll-reveal stacked layouts and asymmetric grids for landing pages.',
|
|
124
|
+
variant: CARD_VARIANT.DEFAULT,
|
|
125
|
+
icon: Rocket,
|
|
126
|
+
},
|
|
127
|
+
];
|
|
31
128
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (selectedTab !== 'all' && config.cssFamily !== selectedTab)
|
|
35
|
-
return false;
|
|
129
|
+
export default function HomePage() {
|
|
130
|
+
const { t } = useTranslation('dndev');
|
|
36
131
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
132
|
+
// -- Feature cards (rich content for FeatureCard) --
|
|
133
|
+
const featureCards = [
|
|
134
|
+
{
|
|
135
|
+
icon: Zap,
|
|
136
|
+
title: t('templates.home.features.feature1.title'),
|
|
137
|
+
subtitle: 'Entity-first architecture',
|
|
138
|
+
content: [
|
|
139
|
+
'Define once with defineEntity()',
|
|
140
|
+
'Auto-generated CRUD operations',
|
|
141
|
+
'Type-safe forms and validation',
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
icon: Shield,
|
|
146
|
+
title: t('templates.home.features.feature2.title'),
|
|
147
|
+
subtitle: 'Security built in, not bolted on',
|
|
148
|
+
content: [
|
|
149
|
+
'Role-based access control',
|
|
150
|
+
'PII encryption at rest',
|
|
151
|
+
'Rate limiting and anomaly detection',
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
icon: Rocket,
|
|
156
|
+
title: t('templates.home.features.feature3.title'),
|
|
157
|
+
subtitle: 'Ship fast, stay consistent',
|
|
158
|
+
content: [
|
|
159
|
+
'5 themes with design tokens',
|
|
160
|
+
'30+ production components',
|
|
161
|
+
'Lazy-loaded advanced components',
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
];
|
|
40
165
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
166
|
+
// -- Roadmap steps --
|
|
167
|
+
const steps: RoadmapStep[] = [
|
|
168
|
+
{
|
|
169
|
+
phase: t('templates.home.howItWorks.step1.title'),
|
|
170
|
+
icon: UserPlus,
|
|
171
|
+
title: t('templates.home.howItWorks.step1.title'),
|
|
172
|
+
subtitle: t('templates.home.howItWorks.step1.description'),
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
phase: t('templates.home.howItWorks.step2.title'),
|
|
176
|
+
icon: Settings,
|
|
177
|
+
title: t('templates.home.howItWorks.step2.title'),
|
|
178
|
+
subtitle: t('templates.home.howItWorks.step2.description'),
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
phase: t('templates.home.howItWorks.step3.title'),
|
|
182
|
+
icon: Play,
|
|
183
|
+
title: t('templates.home.howItWorks.step3.title'),
|
|
184
|
+
subtitle: t('templates.home.howItWorks.step3.description'),
|
|
185
|
+
},
|
|
186
|
+
];
|
|
44
187
|
|
|
45
|
-
|
|
188
|
+
// -- SplitReveal stat cards --
|
|
189
|
+
const statCards = [
|
|
190
|
+
{
|
|
191
|
+
title: '12+ Components',
|
|
192
|
+
description: 'Atomic, advanced, and layout components ready to compose',
|
|
193
|
+
},
|
|
194
|
+
{ title: '4 Essences', description: 'SaaS - Brutalist - Luxury - Retro' },
|
|
195
|
+
{
|
|
196
|
+
title: '100% Typed',
|
|
197
|
+
description: 'Full TypeScript coverage with strict mode',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
title: 'Design System',
|
|
201
|
+
description:
|
|
202
|
+
'Full Design System with tokens and components when you can personalize anything',
|
|
203
|
+
},
|
|
204
|
+
];
|
|
46
205
|
|
|
47
206
|
return (
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
'
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
207
|
+
<PageContainer>
|
|
208
|
+
{/* 1. Hero — clean, no buttons */}
|
|
209
|
+
<HeroSection
|
|
210
|
+
badge={t('templates.home.hero.badge')}
|
|
211
|
+
title={t('templates.home.hero.title')}
|
|
212
|
+
subtitle={t('templates.home.hero.subtitle')}
|
|
213
|
+
/>
|
|
214
|
+
|
|
215
|
+
{/* 2. Features — above the fold, FeatureCard with rich content */}
|
|
216
|
+
<Section
|
|
217
|
+
title={t('templates.home.features.title')}
|
|
218
|
+
gridCols={[1, 1, 3, 3]}
|
|
219
|
+
collapsible
|
|
220
|
+
defaultOpen
|
|
221
|
+
>
|
|
222
|
+
{featureCards.map((f, i) => (
|
|
223
|
+
<FeatureCard
|
|
224
|
+
key={f.title}
|
|
225
|
+
variant={CARD_VARIANT.GLASS}
|
|
226
|
+
icon={f.icon}
|
|
227
|
+
title={f.title}
|
|
228
|
+
subtitle={f.subtitle}
|
|
229
|
+
content={f.content}
|
|
230
|
+
/>
|
|
231
|
+
))}
|
|
232
|
+
</Section>
|
|
233
|
+
|
|
234
|
+
{/* 3. SplitReveal — slow, deliberate entrance */}
|
|
235
|
+
<Section title="Framework at a Glance" tone="muted">
|
|
236
|
+
<SplitReveal
|
|
237
|
+
left={
|
|
238
|
+
<Stack gap="medium">
|
|
239
|
+
<Badge variant={BADGE_VARIANT.ACCENT}>Why DoNotDev?</Badge>
|
|
240
|
+
<Text level="h2">Built for Real Products</Text>
|
|
241
|
+
<Text level="body" variant="muted">
|
|
242
|
+
Production-grade CRUD, auth, billing, and UI — all type-safe,
|
|
243
|
+
theme-aware, and ready to ship. Stop rebuilding the same
|
|
244
|
+
plumbing.
|
|
245
|
+
</Text>
|
|
246
|
+
</Stack>
|
|
247
|
+
}
|
|
248
|
+
right={statCards}
|
|
249
|
+
useStatCards
|
|
250
|
+
stagger={400}
|
|
251
|
+
duration={1000}
|
|
252
|
+
distance={12}
|
|
253
|
+
/>
|
|
254
|
+
</Section>
|
|
255
|
+
|
|
256
|
+
{/* 4. Roadmap — ghost tone */}
|
|
257
|
+
<Section title={t('templates.home.howItWorks.title')} tone="ghost">
|
|
258
|
+
<Roadmap steps={steps} />
|
|
259
|
+
</Section>
|
|
260
|
+
|
|
261
|
+
{/* 5. Testimonials Marquee — muted tone, showcases Marquee component */}
|
|
262
|
+
<Section title="What Developers Say" tone="muted">
|
|
263
|
+
<Badge
|
|
264
|
+
variant={BADGE_VARIANT.MUTED}
|
|
265
|
+
style={{ marginBottom: 'var(--gap-md)', display: 'inline-block' }}
|
|
266
|
+
>
|
|
267
|
+
Fictional testimonials — this is a demo showcase
|
|
268
|
+
</Badge>
|
|
269
|
+
<Marquee
|
|
270
|
+
items={testimonials}
|
|
271
|
+
renderItem={(_item) => {
|
|
272
|
+
const t = _item as (typeof testimonials)[number];
|
|
273
|
+
return (
|
|
274
|
+
<Card style={{ minWidth: 280, maxWidth: 320 }}>
|
|
275
|
+
<Stack gap="tight" style={{ padding: 'var(--gap-md)' }}>
|
|
276
|
+
<Quote
|
|
277
|
+
style={{
|
|
278
|
+
width: 'var(--icon-sm)',
|
|
279
|
+
height: 'var(--icon-sm)',
|
|
280
|
+
color: 'var(--muted-foreground)',
|
|
281
|
+
opacity: 0.5,
|
|
282
|
+
}}
|
|
283
|
+
/>
|
|
284
|
+
<Text level="small" italic>
|
|
285
|
+
“{t.text}”
|
|
286
|
+
</Text>
|
|
287
|
+
<Stack gap="none">
|
|
288
|
+
<Text level="small" weight="semibold">
|
|
289
|
+
{t.name}
|
|
290
|
+
</Text>
|
|
291
|
+
<Text level="caption" variant="muted">
|
|
292
|
+
{t.role}
|
|
293
|
+
</Text>
|
|
294
|
+
</Stack>
|
|
295
|
+
</Stack>
|
|
296
|
+
</Card>
|
|
297
|
+
);
|
|
298
|
+
}}
|
|
299
|
+
speed={300}
|
|
300
|
+
pauseOnHover
|
|
301
|
+
gap="medium"
|
|
302
|
+
behavior="infinite"
|
|
303
|
+
ariaLabel="Developer testimonials"
|
|
304
|
+
/>
|
|
305
|
+
</Section>
|
|
306
|
+
|
|
307
|
+
{/* 6. Component Showcase Carousel — ghost tone */}
|
|
308
|
+
<Section title="Component Showcase" tone="ghost">
|
|
309
|
+
<Badge
|
|
310
|
+
variant={BADGE_VARIANT.MUTED}
|
|
311
|
+
style={{ marginBottom: 'var(--gap-md)', display: 'inline-block' }}
|
|
312
|
+
>
|
|
313
|
+
Swipe or use arrows — this Carousel is a framework component
|
|
314
|
+
</Badge>
|
|
315
|
+
<Carousel
|
|
316
|
+
gap="medium"
|
|
317
|
+
items={showcaseItems}
|
|
318
|
+
renderItem={(_item, _index, isActive) => {
|
|
319
|
+
const item = _item as (typeof showcaseItems)[number];
|
|
320
|
+
return (
|
|
321
|
+
<Card
|
|
322
|
+
variant={item.variant}
|
|
323
|
+
icon={item.icon}
|
|
324
|
+
title={item.title}
|
|
325
|
+
content={item.description}
|
|
326
|
+
style={{
|
|
327
|
+
opacity: isActive ? 1 : 0.6,
|
|
328
|
+
transition: 'opacity var(--dur-normal)',
|
|
329
|
+
}}
|
|
330
|
+
/>
|
|
331
|
+
);
|
|
332
|
+
}}
|
|
333
|
+
slidesToShow={[1, 2, 3, 4]}
|
|
334
|
+
showArrows
|
|
335
|
+
infinite
|
|
336
|
+
aria-label="Component showcase carousel"
|
|
337
|
+
/>
|
|
338
|
+
</Section>
|
|
339
|
+
|
|
340
|
+
{/* 7. CTA — accent tone */}
|
|
341
|
+
<CallToAction
|
|
342
|
+
tone="accent"
|
|
343
|
+
title={t('templates.home.cta.title')}
|
|
344
|
+
subtitle={t('templates.home.cta.subtitle')}
|
|
345
|
+
primaryAction={
|
|
346
|
+
<Button variant={BUTTON_VARIANT.PRIMARY}>
|
|
347
|
+
{t('templates.home.cta.primaryAction')}
|
|
348
|
+
</Button>
|
|
349
|
+
}
|
|
350
|
+
secondaryAction={
|
|
351
|
+
<Button variant={BUTTON_VARIANT.OUTLINE}>
|
|
352
|
+
{t('templates.home.cta.secondaryAction')}
|
|
353
|
+
</Button>
|
|
354
|
+
}
|
|
355
|
+
/>
|
|
356
|
+
</PageContainer>
|
|
78
357
|
);
|
|
79
|
-
}
|
|
358
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// apps/demo/src/pages/OnboardingPage.tsx
|
|
2
|
+
|
|
3
|
+
import { UserPlus } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
import { EntityWorkflow } from '@donotdev/ui';
|
|
6
|
+
|
|
7
|
+
import { onboardingWorkflow } from '../entities/onboarding';
|
|
8
|
+
|
|
9
|
+
import type { PageMeta } from '@donotdev/core';
|
|
10
|
+
|
|
11
|
+
export const meta: PageMeta = {
|
|
12
|
+
icon: <UserPlus />,
|
|
13
|
+
title: 'Onboarding Wizard',
|
|
14
|
+
preset: 'admin',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Onboarding Wizard Demo — shows multi-step workflow with:
|
|
19
|
+
* - Step navigation via Stepper
|
|
20
|
+
* - Per-step entity forms
|
|
21
|
+
* - Skippable steps (Preferences)
|
|
22
|
+
* - Conditional steps (Billing only if company size > 10)
|
|
23
|
+
* - Auto-persistence to localStorage
|
|
24
|
+
*/
|
|
25
|
+
export default function OnboardingPage() {
|
|
26
|
+
return (
|
|
27
|
+
<div style={{ maxWidth: 640, margin: '0 auto' }}>
|
|
28
|
+
<h1>Customer Onboarding</h1>
|
|
29
|
+
<p
|
|
30
|
+
style={{
|
|
31
|
+
color: 'var(--foreground-muted)',
|
|
32
|
+
marginBottom: 'var(--gap-lg)',
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
Multi-step workflow with conditional steps and auto-save. Try setting
|
|
36
|
+
company size > 10 to see the Billing step appear.
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<EntityWorkflow
|
|
40
|
+
workflow={onboardingWorkflow}
|
|
41
|
+
onComplete={async (data) => {
|
|
42
|
+
alert(`Onboarding complete!\n\n${JSON.stringify(data, null, 2)}`);
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// apps/demo/src/pages/PricingPage.tsx
|
|
2
|
+
|
|
3
|
+
import { CreditCard } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
import { SubscriptionTemplate } from '@donotdev/templates';
|
|
6
|
+
|
|
7
|
+
import type { PageMeta } from '@donotdev/core';
|
|
8
|
+
|
|
9
|
+
export const meta: PageMeta = {
|
|
10
|
+
icon: <CreditCard />,
|
|
11
|
+
hideFromMenu: true,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default function PricingPage() {
|
|
15
|
+
return (
|
|
16
|
+
<SubscriptionTemplate
|
|
17
|
+
namespace="demo"
|
|
18
|
+
plans={[
|
|
19
|
+
{
|
|
20
|
+
id: 'free',
|
|
21
|
+
name: 'Free',
|
|
22
|
+
price: '0€',
|
|
23
|
+
currency: 'eur',
|
|
24
|
+
priceId: 'price_free',
|
|
25
|
+
interval: 'month',
|
|
26
|
+
features: ['1 project', 'Community support'],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'pro',
|
|
30
|
+
name: 'Pro',
|
|
31
|
+
price: '29€',
|
|
32
|
+
currency: 'eur',
|
|
33
|
+
priceId: 'price_pro',
|
|
34
|
+
interval: 'month',
|
|
35
|
+
popular: true,
|
|
36
|
+
features: ['Unlimited projects', 'Priority support', 'Custom domain'],
|
|
37
|
+
},
|
|
38
|
+
]}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// apps/demo/src/pages/ProductsPage.tsx
|
|
2
|
+
|
|
3
|
+
import { Package } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
import { ProductCardListTemplate } from '@donotdev/templates';
|
|
6
|
+
|
|
7
|
+
import { productEntity } from '../entities/product';
|
|
8
|
+
|
|
9
|
+
import type { PageMeta } from '@donotdev/core';
|
|
10
|
+
|
|
11
|
+
export const meta: PageMeta = {
|
|
12
|
+
icon: <Package />,
|
|
13
|
+
auth: true,
|
|
14
|
+
preset: 'admin',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default function ProductsPage() {
|
|
18
|
+
return <ProductCardListTemplate entity={productEntity} />;
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// apps/demo/src/pages/ProfilePage.tsx
|
|
2
|
+
|
|
3
|
+
import { User } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
import { ProfileTemplate } from '@donotdev/templates';
|
|
6
|
+
|
|
7
|
+
import type { PageMeta } from '@donotdev/core';
|
|
8
|
+
|
|
9
|
+
export const meta: PageMeta = {
|
|
10
|
+
icon: <User />,
|
|
11
|
+
auth: true,
|
|
12
|
+
preset: 'admin',
|
|
13
|
+
hideFromMenu: true,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default function ProfilePage() {
|
|
17
|
+
return <ProfileTemplate billingPath="/pricing" />;
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// apps/demo/src/pages/SettingsPage.tsx
|
|
2
|
+
|
|
3
|
+
import { Settings } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
import { SettingsTemplate } from '@donotdev/templates';
|
|
6
|
+
|
|
7
|
+
import type { PageMeta } from '@donotdev/core';
|
|
8
|
+
|
|
9
|
+
export const meta: PageMeta = {
|
|
10
|
+
icon: <Settings />,
|
|
11
|
+
auth: true,
|
|
12
|
+
preset: 'admin',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default function SettingsPage() {
|
|
16
|
+
return <SettingsTemplate />;
|
|
17
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// apps/demo/src/pages/ShowcaseDetailPage.tsx
|
|
2
|
+
|
|
3
|
+
import { useEffect, useMemo } from 'react';
|
|
4
|
+
|
|
5
|
+
import { Badge, Grid, Stack, Text } from '@donotdev/components';
|
|
6
|
+
import { PageContainer, useNavigate, useParams } from '@donotdev/ui';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
COMPONENT_CONFIGS,
|
|
10
|
+
getCSSFamilies,
|
|
11
|
+
} from './components/componentConfig';
|
|
12
|
+
import { ComponentRenderer } from './components/ComponentRenderer';
|
|
13
|
+
|
|
14
|
+
import type { PageMeta } from '@donotdev/core';
|
|
15
|
+
import type { ComponentConfig } from './components/componentConfig';
|
|
16
|
+
|
|
17
|
+
export const meta: PageMeta = {
|
|
18
|
+
route: '/showcase/:id',
|
|
19
|
+
hideFromMenu: true,
|
|
20
|
+
preset: 'admin',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default function ShowcaseDetailPage() {
|
|
24
|
+
const { id } = useParams();
|
|
25
|
+
const navigate = useNavigate();
|
|
26
|
+
|
|
27
|
+
const config = useMemo(() => {
|
|
28
|
+
return COMPONENT_CONFIGS.find((c) => c.id === id);
|
|
29
|
+
}, [id]);
|
|
30
|
+
|
|
31
|
+
const cssFamilies = getCSSFamilies();
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!config) navigate('/showcase');
|
|
35
|
+
}, [config, navigate]);
|
|
36
|
+
|
|
37
|
+
if (!config) return null;
|
|
38
|
+
|
|
39
|
+
const generateVariants = (
|
|
40
|
+
config: ComponentConfig
|
|
41
|
+
): Array<Record<string, any>> => {
|
|
42
|
+
const variants: Array<Record<string, any>> = [{}];
|
|
43
|
+
|
|
44
|
+
const dimensions = [
|
|
45
|
+
'variant',
|
|
46
|
+
'size',
|
|
47
|
+
'tone',
|
|
48
|
+
'type',
|
|
49
|
+
'side',
|
|
50
|
+
'mode',
|
|
51
|
+
] as const;
|
|
52
|
+
|
|
53
|
+
dimensions.forEach((dim) => {
|
|
54
|
+
const values = config.variants[dim];
|
|
55
|
+
if (values?.length) {
|
|
56
|
+
const newVariants: Array<Record<string, any>> = [];
|
|
57
|
+
variants.forEach((base) => {
|
|
58
|
+
values.forEach((value) => {
|
|
59
|
+
newVariants.push({ ...base, [dim]: value });
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
variants.length = 0;
|
|
63
|
+
variants.push(...newVariants);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return variants.length > 0 ? variants : [{}];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const allVariants = generateVariants(config);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<PageContainer>
|
|
74
|
+
<Stack gap="large" align="center">
|
|
75
|
+
<Stack gap="tight" align="center">
|
|
76
|
+
<Text level="h2">{config.name}</Text>
|
|
77
|
+
<Badge variant="outline">
|
|
78
|
+
{cssFamilies.find((f) => f.id === config.cssFamily)?.label ||
|
|
79
|
+
config.cssFamily}
|
|
80
|
+
</Badge>
|
|
81
|
+
</Stack>
|
|
82
|
+
|
|
83
|
+
<Grid cols={[1, 1, 2, 3]} gap="large">
|
|
84
|
+
{allVariants.map((variantProps, idx) => {
|
|
85
|
+
const variantLabels = Object.entries(variantProps)
|
|
86
|
+
.filter(([_, v]) => v)
|
|
87
|
+
.map(([k, v]) => `${k}: ${v}`);
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<Stack key={idx} align="center">
|
|
91
|
+
{variantLabels.length > 0 && (
|
|
92
|
+
<Stack
|
|
93
|
+
direction="row"
|
|
94
|
+
gap="tight"
|
|
95
|
+
wrap="wrap"
|
|
96
|
+
justify="center"
|
|
97
|
+
>
|
|
98
|
+
{variantLabels.map((label) => (
|
|
99
|
+
<Badge key={label} variant="secondary">
|
|
100
|
+
{label}
|
|
101
|
+
</Badge>
|
|
102
|
+
))}
|
|
103
|
+
</Stack>
|
|
104
|
+
)}
|
|
105
|
+
<Stack align="center" justify="center">
|
|
106
|
+
<ComponentRenderer
|
|
107
|
+
config={config}
|
|
108
|
+
variantProps={variantProps}
|
|
109
|
+
/>
|
|
110
|
+
</Stack>
|
|
111
|
+
</Stack>
|
|
112
|
+
);
|
|
113
|
+
})}
|
|
114
|
+
</Grid>
|
|
115
|
+
</Stack>
|
|
116
|
+
</PageContainer>
|
|
117
|
+
);
|
|
118
|
+
}
|