blocks-dusted 0.1.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/LICENSE +21 -0
- package/README.md +68 -0
- package/bin/index.js +8 -0
- package/package.json +40 -0
- package/src/cli.js +79 -0
- package/src/commands/add.js +327 -0
- package/src/commands/doctor.js +21 -0
- package/src/commands/list.js +18 -0
- package/src/installers/checkRequirements.js +101 -0
- package/src/installers/copyTemplateFiles.js +79 -0
- package/src/installers/installDependencies.js +69 -0
- package/src/installers/patchPayloadBlocksArray.js +122 -0
- package/src/installers/patchRenderBlocks.js +110 -0
- package/src/installers/runGenerators.js +3 -0
- package/src/installers/writeInstalledBlockReadme.js +117 -0
- package/src/registry/listTemplates.js +17 -0
- package/src/registry/loadTemplateManifest.js +20 -0
- package/src/registry/validateTemplateManifest.js +69 -0
- package/src/utils/logger.js +8 -0
- package/src/utils/packageManager.js +42 -0
- package/src/utils/paths.js +7 -0
- package/src/utils/project.js +122 -0
- package/src/utils/strings.js +7 -0
- package/templates/blocks/DD-BookCall/Component.tsx +573 -0
- package/templates/blocks/DD-BookCall/config.ts +239 -0
- package/templates/blocks/DD-BookCall/manifest.json +112 -0
- package/templates/blocks/DD-CardTemplate01/Component.tsx +144 -0
- package/templates/blocks/DD-CardTemplate01/config.ts +106 -0
- package/templates/blocks/DD-CardTemplate01/manifest.json +84 -0
- package/templates/blocks/DD-Carousel-A/Component.tsx +266 -0
- package/templates/blocks/DD-Carousel-A/config.ts +163 -0
- package/templates/blocks/DD-Carousel-A/manifest.json +86 -0
- package/templates/blocks/DD-Carousel-B/Component.tsx +432 -0
- package/templates/blocks/DD-Carousel-B/config.ts +176 -0
- package/templates/blocks/DD-Carousel-B/manifest.json +86 -0
- package/templates/blocks/DD-ComparisonTable/Component.tsx +272 -0
- package/templates/blocks/DD-ComparisonTable/config.ts +105 -0
- package/templates/blocks/DD-ComparisonTable/manifest.json +78 -0
- package/templates/blocks/DD-Contact/Component.tsx +439 -0
- package/templates/blocks/DD-Contact/config.ts +217 -0
- package/templates/blocks/DD-Contact/manifest.json +107 -0
- package/templates/blocks/DD-FeatCat/Component.tsx +361 -0
- package/templates/blocks/DD-FeatCat/config.ts +204 -0
- package/templates/blocks/DD-FeatCat/manifest.json +87 -0
- package/templates/blocks/DD-FeatStrip/Component.tsx +615 -0
- package/templates/blocks/DD-FeatStrip/config.ts +134 -0
- package/templates/blocks/DD-FeatStrip/manifest.json +82 -0
- package/templates/blocks/DD-Hero/Component.tsx +317 -0
- package/templates/blocks/DD-Hero/config.ts +267 -0
- package/templates/blocks/DD-Hero/manifest.json +92 -0
- package/templates/blocks/DD-HorizontalScroll/Component.tsx +995 -0
- package/templates/blocks/DD-HorizontalScroll/config.ts +231 -0
- package/templates/blocks/DD-HorizontalScroll/manifest.json +85 -0
- package/templates/blocks/DD-MasonaryMedia/Component.tsx +571 -0
- package/templates/blocks/DD-MasonaryMedia/config.ts +390 -0
- package/templates/blocks/DD-MasonaryMedia/manifest.json +101 -0
- package/templates/blocks/DD-MasonaryMedia/vendor.d.ts +2 -0
- package/templates/blocks/DD-Pricing/Component.tsx +380 -0
- package/templates/blocks/DD-Pricing/config.ts +215 -0
- package/templates/blocks/DD-Pricing/manifest.json +78 -0
- package/templates/blocks/DD-Process/Component.tsx +155 -0
- package/templates/blocks/DD-Process/config.ts +150 -0
- package/templates/blocks/DD-Process/manifest.json +82 -0
- package/templates/blocks/DD-Section/Component.tsx +327 -0
- package/templates/blocks/DD-Section/config.ts +214 -0
- package/templates/blocks/DD-Section/manifest.json +85 -0
- package/templates/blocks/DD-Services/Component.tsx +188 -0
- package/templates/blocks/DD-Services/config.ts +149 -0
- package/templates/blocks/DD-Services/manifest.json +95 -0
- package/templates/blocks/DD-ShowcaseGrid/Component.tsx +317 -0
- package/templates/blocks/DD-ShowcaseGrid/config.ts +197 -0
- package/templates/blocks/DD-ShowcaseGrid/manifest.json +80 -0
- package/templates/blocks/DD-Slider-A/Component.tsx +252 -0
- package/templates/blocks/DD-Slider-A/config.ts +118 -0
- package/templates/blocks/DD-Slider-A/manifest.json +86 -0
- package/templates/blocks/DD-StackCards/Component.tsx +496 -0
- package/templates/blocks/DD-StackCards/config.ts +399 -0
- package/templates/blocks/DD-StackCards/manifest.json +87 -0
- package/templates/blocks/DD-Team/Component.tsx +265 -0
- package/templates/blocks/DD-Team/config.ts +173 -0
- package/templates/blocks/DD-Team/manifest.json +82 -0
- package/templates/blocks/DD-TechStack/Component.tsx +189 -0
- package/templates/blocks/DD-TechStack/config.ts +153 -0
- package/templates/blocks/DD-TechStack/manifest.json +118 -0
- package/templates/blocks/DD-Testimonials/Component.tsx +147 -0
- package/templates/blocks/DD-Testimonials/config.ts +120 -0
- package/templates/blocks/DD-Testimonials/manifest.json +87 -0
- package/templates/blocks/DD-Work/Component.tsx +328 -0
- package/templates/blocks/DD-Work/config.ts +165 -0
- package/templates/blocks/DD-Work/manifest.json +87 -0
- package/templates/blocks/DD-Work-B/Component.tsx +320 -0
- package/templates/blocks/DD-Work-B/config.ts +165 -0
- package/templates/blocks/DD-Work-B/manifest.json +75 -0
- package/templates/shared/components/ui/anims/fade.tsx +83 -0
- package/templates/shared/components/ui/button.tsx +233 -0
- package/templates/shared/components/ui/input.tsx +41 -0
- package/templates/shared/fields/lucide-icon-picker/Cell.tsx +24 -0
- package/templates/shared/fields/lucide-icon-picker/README.md +160 -0
- package/templates/shared/fields/lucide-icon-picker/field.ts +40 -0
- package/templates/shared/fields/lucide-icon-picker/index.tsx +203 -0
- package/templates/shared/utilities/canUseDOM.ts +1 -0
- package/templates/shared/utilities/getURL.ts +31 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useState } from "react";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import { Check, X } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
export type BillingCycle = "monthly" | "annual";
|
|
8
|
+
|
|
9
|
+
interface PricingFeature {
|
|
10
|
+
id?: string | null;
|
|
11
|
+
label?: string | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface PricingTier {
|
|
15
|
+
id?: string | null;
|
|
16
|
+
name?: string | null;
|
|
17
|
+
tagline?: string | null;
|
|
18
|
+
monthlyPrice?: number | null;
|
|
19
|
+
annualPrice?: number | null;
|
|
20
|
+
cta?: string | null;
|
|
21
|
+
ctaLink?: string | null;
|
|
22
|
+
highlight?: boolean | null;
|
|
23
|
+
badge?: string | null;
|
|
24
|
+
features?: PricingFeature[] | null;
|
|
25
|
+
missing?: PricingFeature[] | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface StudioPricingBlockProps {
|
|
29
|
+
eyebrow?: string | null;
|
|
30
|
+
heading?: string | null;
|
|
31
|
+
description?: string | null;
|
|
32
|
+
defaultBilling?: BillingCycle | null;
|
|
33
|
+
annualDiscountLabel?: string | null;
|
|
34
|
+
monthlyLabel?: string | null;
|
|
35
|
+
annualLabel?: string | null;
|
|
36
|
+
tiers?: PricingTier[] | null;
|
|
37
|
+
guaranteeText?: string | null;
|
|
38
|
+
guaranteeHighlight?: string | null;
|
|
39
|
+
sectionId?: string | null;
|
|
40
|
+
customCSS?: string | null;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const DEFAULT_TIERS: PricingTier[] = [
|
|
45
|
+
{
|
|
46
|
+
id: "free",
|
|
47
|
+
name: "Free",
|
|
48
|
+
tagline: "Start building today",
|
|
49
|
+
monthlyPrice: 0,
|
|
50
|
+
annualPrice: 0,
|
|
51
|
+
cta: "Get Started Free",
|
|
52
|
+
ctaLink: "/account",
|
|
53
|
+
highlight: false,
|
|
54
|
+
badge: null,
|
|
55
|
+
features: [
|
|
56
|
+
{ label: "Access to all free components" },
|
|
57
|
+
{ label: "Access to free templates" },
|
|
58
|
+
{ label: "Community Discord access" },
|
|
59
|
+
{ label: "MIT license for personal use" },
|
|
60
|
+
{ label: "Basic documentation" },
|
|
61
|
+
{ label: "Copy JSX code" },
|
|
62
|
+
],
|
|
63
|
+
missing: [
|
|
64
|
+
{ label: "Pro components & templates" },
|
|
65
|
+
{ label: "Source files (Figma, PSD)" },
|
|
66
|
+
{ label: "Payload CMS blocks" },
|
|
67
|
+
{ label: "Priority support" },
|
|
68
|
+
{ label: "Commercial license" },
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "pro",
|
|
73
|
+
name: "Pro",
|
|
74
|
+
tagline: "For individual developers",
|
|
75
|
+
monthlyPrice: 49,
|
|
76
|
+
annualPrice: 39,
|
|
77
|
+
cta: "Get Pro Access",
|
|
78
|
+
ctaLink: "/account",
|
|
79
|
+
highlight: true,
|
|
80
|
+
badge: "Most Popular",
|
|
81
|
+
features: [
|
|
82
|
+
{ label: "Everything in Free" },
|
|
83
|
+
{ label: "120+ premium components" },
|
|
84
|
+
{ label: "24+ full website templates" },
|
|
85
|
+
{ label: "Payload CMS v3 blocks" },
|
|
86
|
+
{ label: "Figma source files" },
|
|
87
|
+
{ label: "Commercial license (1 project)" },
|
|
88
|
+
{ label: "Priority email support" },
|
|
89
|
+
{ label: "Lifetime updates" },
|
|
90
|
+
{ label: "Early access to new releases" },
|
|
91
|
+
],
|
|
92
|
+
missing: [
|
|
93
|
+
{ label: "Unlimited commercial projects" },
|
|
94
|
+
{ label: "Team seats" },
|
|
95
|
+
{ label: "White-label license" },
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "team",
|
|
100
|
+
name: "Team",
|
|
101
|
+
tagline: "For studios & agencies",
|
|
102
|
+
monthlyPrice: 129,
|
|
103
|
+
annualPrice: 99,
|
|
104
|
+
cta: "Get Team Access",
|
|
105
|
+
ctaLink: "/account",
|
|
106
|
+
highlight: false,
|
|
107
|
+
badge: null,
|
|
108
|
+
features: [
|
|
109
|
+
{ label: "Everything in Pro" },
|
|
110
|
+
{ label: "Unlimited commercial projects" },
|
|
111
|
+
{ label: "Up to 10 team seats" },
|
|
112
|
+
{ label: "White-label license" },
|
|
113
|
+
{ label: "Custom Payload CMS schemas" },
|
|
114
|
+
{ label: "Dedicated Slack channel" },
|
|
115
|
+
{ label: "1-on-1 onboarding call" },
|
|
116
|
+
{ label: "Invoice & billing management" },
|
|
117
|
+
{ label: "SLA support guarantee" },
|
|
118
|
+
],
|
|
119
|
+
missing: [],
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
export function DDPricing({
|
|
124
|
+
eyebrow,
|
|
125
|
+
heading,
|
|
126
|
+
description,
|
|
127
|
+
defaultBilling = "monthly",
|
|
128
|
+
annualDiscountLabel = "-20%",
|
|
129
|
+
monthlyLabel = "Pay Monthly",
|
|
130
|
+
annualLabel = "Pay Annually",
|
|
131
|
+
tiers,
|
|
132
|
+
guaranteeText = "All paid plans include a",
|
|
133
|
+
guaranteeHighlight = "14-day money-back guarantee",
|
|
134
|
+
sectionId,
|
|
135
|
+
}: StudioPricingBlockProps) {
|
|
136
|
+
const [billing, setBilling] = useState<BillingCycle>(
|
|
137
|
+
defaultBilling === "annual" ? "annual" : "monthly",
|
|
138
|
+
);
|
|
139
|
+
const pricingTiers = tiers && tiers.length > 0 ? tiers : DEFAULT_TIERS;
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<section
|
|
143
|
+
id={sectionId ?? undefined}
|
|
144
|
+
className="studio-pricing-block px-6 pb-20 pt-32 text-stone-700 dark:text-stone-50"
|
|
145
|
+
>
|
|
146
|
+
<div className="mx-auto max-w-3xl text-center">
|
|
147
|
+
{eyebrow && (
|
|
148
|
+
<p className="mb-4 text-xs font-semibold uppercase tracking-[0.28em] text-stone-700 dark:text-stone-500">
|
|
149
|
+
{eyebrow}
|
|
150
|
+
</p>
|
|
151
|
+
)}
|
|
152
|
+
|
|
153
|
+
{heading && (
|
|
154
|
+
<h2 className="mx-auto mb-4 max-w-3xl text-4xl font-black tracking-tight text-stone-700 dark:text-stone-50 md:text-5xl">
|
|
155
|
+
{heading}
|
|
156
|
+
</h2>
|
|
157
|
+
)}
|
|
158
|
+
|
|
159
|
+
{description && (
|
|
160
|
+
<p className="mx-auto mb-10 max-w-2xl text-sm leading-relaxed text-stone-500 md:text-base">
|
|
161
|
+
{description}
|
|
162
|
+
</p>
|
|
163
|
+
)}
|
|
164
|
+
|
|
165
|
+
<div className="inline-flex items-center gap-1 rounded-xl border border-stone-100 dark:border-stone-800 bg-stone-200 dark:bg-stone-900 p-1">
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
onClick={() => setBilling("monthly")}
|
|
169
|
+
className={`cursor-pointer whitespace-nowrap rounded-lg px-5 py-2 text-sm font-medium transition-all ${
|
|
170
|
+
billing === "monthly"
|
|
171
|
+
? "bg-stone-50 text-stone-900"
|
|
172
|
+
: "text-stone-500 "
|
|
173
|
+
}`}
|
|
174
|
+
>
|
|
175
|
+
{monthlyLabel}
|
|
176
|
+
</button>
|
|
177
|
+
|
|
178
|
+
<button
|
|
179
|
+
type="button"
|
|
180
|
+
onClick={() => setBilling("annual")}
|
|
181
|
+
className={`flex cursor-pointer items-center gap-2 whitespace-nowrap rounded-lg px-5 py-2 text-sm font-medium transition-all ${
|
|
182
|
+
billing === "annual"
|
|
183
|
+
? "bg-stone-50 text-stone-900"
|
|
184
|
+
: "text-stone-500 hover:text-stone-700"
|
|
185
|
+
}`}
|
|
186
|
+
>
|
|
187
|
+
{annualLabel}
|
|
188
|
+
{annualDiscountLabel && (
|
|
189
|
+
<span
|
|
190
|
+
className={`rounded-full px-1.5 py-0.5 text-[10px] font-bold ${
|
|
191
|
+
billing === "annual"
|
|
192
|
+
? "bg-lime-500 text-stone-50"
|
|
193
|
+
: "bg-lime-900/60 text-lime-400"
|
|
194
|
+
}`}
|
|
195
|
+
>
|
|
196
|
+
{annualDiscountLabel}
|
|
197
|
+
</span>
|
|
198
|
+
)}
|
|
199
|
+
</button>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<div className="mx-auto mt-16 max-w-6xl">
|
|
204
|
+
<div className="grid grid-cols-1 items-start gap-5 md:grid-cols-3">
|
|
205
|
+
{pricingTiers.map((tier, index) => {
|
|
206
|
+
const isHighlighted = tier.highlight === true;
|
|
207
|
+
const monthlyPrice =
|
|
208
|
+
typeof tier.monthlyPrice === "number" ? tier.monthlyPrice : 0;
|
|
209
|
+
const annualPrice =
|
|
210
|
+
typeof tier.annualPrice === "number"
|
|
211
|
+
? tier.annualPrice
|
|
212
|
+
: monthlyPrice;
|
|
213
|
+
const price = billing === "annual" ? annualPrice : monthlyPrice;
|
|
214
|
+
const tierId = tier.id ?? tier.name ?? String(index);
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<div
|
|
218
|
+
key={tierId}
|
|
219
|
+
className={`relative flex flex-col rounded-2xl border p-7 ${
|
|
220
|
+
isHighlighted
|
|
221
|
+
? "dark:border-white dark:bg-stone-50/50"
|
|
222
|
+
: "border-stone-200 dark:border-stone-800 bg-stone-50/50 dark:bg-stone-900/50"
|
|
223
|
+
}`}
|
|
224
|
+
style={{ cornerShape: "squircle" } as React.CSSProperties}
|
|
225
|
+
>
|
|
226
|
+
{tier.badge && (
|
|
227
|
+
<div className="absolute -top-3 left-1/2 -translate-x-1/2">
|
|
228
|
+
<span className="whitespace-nowrap rounded-full border border-indigo-400 bg-indigo-900/90 px-3 py-1 text-[10px] font-bold uppercase tracking-widest text-stone-300 shadow-md">
|
|
229
|
+
{tier.badge}
|
|
230
|
+
</span>
|
|
231
|
+
</div>
|
|
232
|
+
)}
|
|
233
|
+
|
|
234
|
+
<div className="mb-6">
|
|
235
|
+
{tier.name && (
|
|
236
|
+
<p className="mb-1 text-base font-semibold uppercase tracking-widest text-stone-500">
|
|
237
|
+
{tier.name}
|
|
238
|
+
</p>
|
|
239
|
+
)}
|
|
240
|
+
|
|
241
|
+
{tier.tagline && (
|
|
242
|
+
<p className="mb-5 text-[11.5px] text-stone-500">
|
|
243
|
+
{tier.tagline}
|
|
244
|
+
</p>
|
|
245
|
+
)}
|
|
246
|
+
|
|
247
|
+
<div className="flex items-end gap-1">
|
|
248
|
+
<span
|
|
249
|
+
className={`text-5xl text-stone-900 dark:text-stone-50 font-bold tracking-tight ${
|
|
250
|
+
isHighlighted
|
|
251
|
+
? "text-stone-900 dark:text-stone-50"
|
|
252
|
+
: "text-stone-50 dark:text-stone-50"
|
|
253
|
+
}`}
|
|
254
|
+
>
|
|
255
|
+
{price === 0 ? "Free" : `$${price}`}
|
|
256
|
+
</span>
|
|
257
|
+
|
|
258
|
+
{price > 0 && (
|
|
259
|
+
<span className="mb-2 text-sm text-stone-500">
|
|
260
|
+
/{billing === "annual" ? "mo, billed annually" : "mo"}
|
|
261
|
+
</span>
|
|
262
|
+
)}
|
|
263
|
+
</div>
|
|
264
|
+
|
|
265
|
+
{billing === "annual" && price > 0 && (
|
|
266
|
+
<p
|
|
267
|
+
className={`mt-1 text-xs ${isHighlighted ? "text-stone-800 dark:text-stone-500" : "text-stone-800 dark:text-stone-600"}`}
|
|
268
|
+
>
|
|
269
|
+
${monthlyPrice}/mo if billed monthly
|
|
270
|
+
</p>
|
|
271
|
+
)}
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
<Link
|
|
275
|
+
href={tier.ctaLink ?? "#"}
|
|
276
|
+
className={`mb-7 flex w-full cursor-pointer items-center justify-center rounded-xl py-3 text-sm font-semibold transition-all hover:shadow-2xl ${
|
|
277
|
+
isHighlighted
|
|
278
|
+
? "bg-indigo-900 text-stone-50 hover:bg-indigo-800"
|
|
279
|
+
: tierId === "free"
|
|
280
|
+
? "border border-indigo-700 bg-indigo-800 text-stone-200 hover:bg-indigo-700"
|
|
281
|
+
: "bg-indigo-50 text-indigo-900 hover:bg-indigo-100"
|
|
282
|
+
}`}
|
|
283
|
+
style={{ cornerShape: "squircle" } as React.CSSProperties}
|
|
284
|
+
>
|
|
285
|
+
{tier.cta ?? "Get Started"}
|
|
286
|
+
</Link>
|
|
287
|
+
|
|
288
|
+
<div
|
|
289
|
+
className={`mb-6 h-px ${isHighlighted ? "bg-stone-800 dark:bg-stone-200" : "bg-stone-200 dark:bg-stone-800"}`}
|
|
290
|
+
/>
|
|
291
|
+
|
|
292
|
+
<ul className="flex-1 space-y-3">
|
|
293
|
+
{(tier.features ?? []).map((feature, featureIndex) => {
|
|
294
|
+
const label = feature.label;
|
|
295
|
+
if (!label) return null;
|
|
296
|
+
|
|
297
|
+
return (
|
|
298
|
+
<li
|
|
299
|
+
key={feature.id ?? `${label}-${featureIndex}`}
|
|
300
|
+
className="flex items-start gap-2.5"
|
|
301
|
+
>
|
|
302
|
+
<div
|
|
303
|
+
className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full ${
|
|
304
|
+
isHighlighted
|
|
305
|
+
? "bg-stone-800 dark:bg-stone-200"
|
|
306
|
+
: "bg-stone-200 dark:bg-stone-800"
|
|
307
|
+
}`}
|
|
308
|
+
>
|
|
309
|
+
<Check
|
|
310
|
+
className={`h-2.5 w-2.5 ${
|
|
311
|
+
isHighlighted
|
|
312
|
+
? "text-stone-700 dark:text-stone-200"
|
|
313
|
+
: "text-stone-800 dark:text-stone-300"
|
|
314
|
+
}`}
|
|
315
|
+
/>
|
|
316
|
+
</div>
|
|
317
|
+
<span
|
|
318
|
+
className={`text-sm leading-snug ${
|
|
319
|
+
isHighlighted
|
|
320
|
+
? "text-stone-700 dark:text-stone-200"
|
|
321
|
+
: "text-stone-800 dark:text-stone-300"
|
|
322
|
+
}`}
|
|
323
|
+
>
|
|
324
|
+
{label}
|
|
325
|
+
</span>
|
|
326
|
+
</li>
|
|
327
|
+
);
|
|
328
|
+
})}
|
|
329
|
+
|
|
330
|
+
{(tier.missing ?? []).map((feature, featureIndex) => {
|
|
331
|
+
const label = feature.label;
|
|
332
|
+
if (!label) return null;
|
|
333
|
+
|
|
334
|
+
return (
|
|
335
|
+
<li
|
|
336
|
+
key={feature.id ?? `${label}-${featureIndex}`}
|
|
337
|
+
className="flex items-start gap-2.5 opacity-40"
|
|
338
|
+
>
|
|
339
|
+
<div
|
|
340
|
+
className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full ${
|
|
341
|
+
isHighlighted
|
|
342
|
+
? "bg-stone-800 dark:bg-stone-200"
|
|
343
|
+
: "bg-stone-200 dark:bg-stone-800"
|
|
344
|
+
}`}
|
|
345
|
+
>
|
|
346
|
+
<X className="h-2.5 w-2.5 text-stone-700 dark:text-stone-400" />
|
|
347
|
+
</div>
|
|
348
|
+
<span
|
|
349
|
+
className={`text-sm leading-snug ${
|
|
350
|
+
isHighlighted
|
|
351
|
+
? "text-stone-700 dark:text-stone-200"
|
|
352
|
+
: "text-stone-800 dark:text-stone-300"
|
|
353
|
+
}`}
|
|
354
|
+
>
|
|
355
|
+
{label}
|
|
356
|
+
</span>
|
|
357
|
+
</li>
|
|
358
|
+
);
|
|
359
|
+
})}
|
|
360
|
+
</ul>
|
|
361
|
+
</div>
|
|
362
|
+
);
|
|
363
|
+
})}
|
|
364
|
+
</div>
|
|
365
|
+
|
|
366
|
+
{(guaranteeText || guaranteeHighlight) && (
|
|
367
|
+
<p className="mt-16 text-center text-xs text-stone-500 dark:text-stone-600">
|
|
368
|
+
{guaranteeText}{" "}
|
|
369
|
+
{guaranteeHighlight && (
|
|
370
|
+
<strong className="text-stone-500">{guaranteeHighlight}</strong>
|
|
371
|
+
)}
|
|
372
|
+
. No questions asked.
|
|
373
|
+
</p>
|
|
374
|
+
)}
|
|
375
|
+
</div>
|
|
376
|
+
</section>
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export default DDPricing;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import type { Block } from 'payload'
|
|
2
|
+
|
|
3
|
+
export const DDPricing: Block = {
|
|
4
|
+
slug: 'DD-Pricing',
|
|
5
|
+
interfaceName: 'DDPricing',
|
|
6
|
+
labels: {
|
|
7
|
+
singular: 'Studio Pricing Block',
|
|
8
|
+
plural: 'Studio Pricing Blocks',
|
|
9
|
+
},
|
|
10
|
+
fields: [
|
|
11
|
+
{
|
|
12
|
+
type: 'tabs',
|
|
13
|
+
tabs: [
|
|
14
|
+
{
|
|
15
|
+
label: 'Content',
|
|
16
|
+
fields: [
|
|
17
|
+
{
|
|
18
|
+
name: 'eyebrow',
|
|
19
|
+
type: 'text',
|
|
20
|
+
defaultValue: 'Pricing',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'heading',
|
|
24
|
+
type: 'text',
|
|
25
|
+
defaultValue: 'Simple pricing for modern digital teams',
|
|
26
|
+
required: true,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'description',
|
|
30
|
+
type: 'textarea',
|
|
31
|
+
defaultValue:
|
|
32
|
+
'Choose the plan that fits your workflow. Scale from solo creators to full production teams.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: 'row',
|
|
36
|
+
fields: [
|
|
37
|
+
{
|
|
38
|
+
name: 'monthlyLabel',
|
|
39
|
+
type: 'text',
|
|
40
|
+
defaultValue: 'Pay Monthly',
|
|
41
|
+
admin: {
|
|
42
|
+
width: '50%',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'annualLabel',
|
|
47
|
+
type: 'text',
|
|
48
|
+
defaultValue: 'Pay Annually',
|
|
49
|
+
admin: {
|
|
50
|
+
width: '50%',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: 'row',
|
|
57
|
+
fields: [
|
|
58
|
+
{
|
|
59
|
+
name: 'annualDiscountLabel',
|
|
60
|
+
type: 'text',
|
|
61
|
+
defaultValue: '-20%',
|
|
62
|
+
admin: {
|
|
63
|
+
width: '50%',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'defaultBilling',
|
|
68
|
+
type: 'select',
|
|
69
|
+
defaultValue: 'monthly',
|
|
70
|
+
admin: {
|
|
71
|
+
width: '50%',
|
|
72
|
+
},
|
|
73
|
+
options: [
|
|
74
|
+
{
|
|
75
|
+
label: 'Monthly',
|
|
76
|
+
value: 'monthly',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
label: 'Annual',
|
|
80
|
+
value: 'annual',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
label: 'Pricing Tiers',
|
|
90
|
+
fields: [
|
|
91
|
+
{
|
|
92
|
+
name: 'tiers',
|
|
93
|
+
type: 'array',
|
|
94
|
+
minRows: 1,
|
|
95
|
+
fields: [
|
|
96
|
+
{
|
|
97
|
+
type: 'row',
|
|
98
|
+
fields: [
|
|
99
|
+
{
|
|
100
|
+
name: 'name',
|
|
101
|
+
type: 'text',
|
|
102
|
+
required: true,
|
|
103
|
+
admin: {
|
|
104
|
+
width: '33%',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'badge',
|
|
109
|
+
type: 'text',
|
|
110
|
+
admin: {
|
|
111
|
+
width: '33%',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'highlight',
|
|
116
|
+
type: 'checkbox',
|
|
117
|
+
defaultValue: false,
|
|
118
|
+
admin: {
|
|
119
|
+
width: '33%',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'tagline',
|
|
126
|
+
type: 'text',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
type: 'row',
|
|
130
|
+
fields: [
|
|
131
|
+
{
|
|
132
|
+
name: 'monthlyPrice',
|
|
133
|
+
type: 'number',
|
|
134
|
+
defaultValue: 0,
|
|
135
|
+
admin: {
|
|
136
|
+
width: '50%',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'annualPrice',
|
|
141
|
+
type: 'number',
|
|
142
|
+
defaultValue: 0,
|
|
143
|
+
admin: {
|
|
144
|
+
width: '50%',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'row',
|
|
151
|
+
fields: [
|
|
152
|
+
{
|
|
153
|
+
name: 'cta',
|
|
154
|
+
type: 'text',
|
|
155
|
+
defaultValue: 'Get Started',
|
|
156
|
+
admin: {
|
|
157
|
+
width: '50%',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: 'ctaLink',
|
|
162
|
+
type: 'text',
|
|
163
|
+
defaultValue: '#',
|
|
164
|
+
admin: {
|
|
165
|
+
width: '50%',
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'features',
|
|
172
|
+
type: 'array',
|
|
173
|
+
label: 'Included Features',
|
|
174
|
+
fields: [
|
|
175
|
+
{
|
|
176
|
+
name: 'label',
|
|
177
|
+
type: 'text',
|
|
178
|
+
required: true,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'missing',
|
|
184
|
+
type: 'array',
|
|
185
|
+
label: 'Missing Features',
|
|
186
|
+
fields: [
|
|
187
|
+
{
|
|
188
|
+
name: 'label',
|
|
189
|
+
type: 'text',
|
|
190
|
+
required: true,
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: 'guaranteeText',
|
|
202
|
+
type: 'text',
|
|
203
|
+
defaultValue: 'All paid plans include a',
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'guaranteeHighlight',
|
|
207
|
+
type: 'text',
|
|
208
|
+
defaultValue: '14-day money-back guarantee',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: 'sectionId',
|
|
212
|
+
type: 'text',
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "block",
|
|
3
|
+
"name": "DD-Pricing",
|
|
4
|
+
"label": "Studio Pricing Block",
|
|
5
|
+
"sourceName": "StudioPricingBlock",
|
|
6
|
+
"portableName": "DD-Pricing",
|
|
7
|
+
"slug": "DD-Pricing",
|
|
8
|
+
"version": "0.0.1",
|
|
9
|
+
"source": {
|
|
10
|
+
"repo": "Hadizainal/DesignsDustedv3",
|
|
11
|
+
"originalPath": "src/blocks/StudioPricingBlock",
|
|
12
|
+
"originalSlug": "studioPricingBlock",
|
|
13
|
+
"originalConfigExport": "StudioPricingBlock",
|
|
14
|
+
"originalComponentExport": "StudioPricingBlock",
|
|
15
|
+
"originalInterfaceName": "StudioPricingBlock"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
{
|
|
19
|
+
"from": "Component.tsx",
|
|
20
|
+
"to": "src/blocks/DD-Pricing/Component.tsx"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"from": "config.ts",
|
|
24
|
+
"to": "src/blocks/DD-Pricing/config.ts"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"dependencies": [
|
|
28
|
+
{
|
|
29
|
+
"name": "lucide-react"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"sharedFiles": [],
|
|
33
|
+
"requiredProjectFiles": [],
|
|
34
|
+
"optionalProjectFiles": [],
|
|
35
|
+
"collectionRegistration": {
|
|
36
|
+
"enabled": true,
|
|
37
|
+
"collections": [
|
|
38
|
+
"Pages",
|
|
39
|
+
"Posts"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"renderBlocksRegistration": {
|
|
43
|
+
"enabled": true
|
|
44
|
+
},
|
|
45
|
+
"renderBlocksBehavior": {
|
|
46
|
+
"wrapperless": false
|
|
47
|
+
},
|
|
48
|
+
"pageRouteIntegration": {
|
|
49
|
+
"required": false,
|
|
50
|
+
"manualSteps": []
|
|
51
|
+
},
|
|
52
|
+
"manual": [
|
|
53
|
+
"Register DDPricing in Pages/Posts blocks arrays if automatic registration was skipped.",
|
|
54
|
+
"Register DD-Pricing in RenderBlocks if automatic registration was skipped.",
|
|
55
|
+
"Run payload generate:types after schema changes.",
|
|
56
|
+
"Run payload generate:importmap if admin/component imports changed."
|
|
57
|
+
],
|
|
58
|
+
"manualSteps": [
|
|
59
|
+
"Register DDPricing in Pages/Posts blocks arrays if automatic registration was skipped.",
|
|
60
|
+
"Register DD-Pricing in RenderBlocks if automatic registration was skipped.",
|
|
61
|
+
"Run payload generate:types after schema changes.",
|
|
62
|
+
"Run payload generate:importmap if admin/component imports changed."
|
|
63
|
+
],
|
|
64
|
+
"patchTargets": {
|
|
65
|
+
"blockConfigRegistration": {
|
|
66
|
+
"description": "Installer can add import { DDPricing } from '@/blocks/DD-Pricing/config' and add DDPricing to clear Pages/Posts blocks arrays."
|
|
67
|
+
},
|
|
68
|
+
"renderBlocksRegistration": {
|
|
69
|
+
"description": "Installer can register DD-Pricing in src/blocks/**/RenderBlocks.tsx when the blockComponents map is clear."
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"notes": [
|
|
73
|
+
"Converted from DesignsDustedv3 StudioPricingBlock.",
|
|
74
|
+
"Installer must not overwrite existing target files."
|
|
75
|
+
],
|
|
76
|
+
"exportName": "DDPricing",
|
|
77
|
+
"interfaceName": "DDPricing"
|
|
78
|
+
}
|