create-lacspace-app 1.10.0 → 1.11.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/dist/index.js +134 -33
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1463,6 +1463,7 @@ function buildFiles(ctx) {
|
|
|
1463
1463
|
for (const page of stubPages(ctx)) {
|
|
1464
1464
|
files[`app${page.path}/page.tsx`] = isDash ? dashboardStubPage(page) : underDevPage(page);
|
|
1465
1465
|
}
|
|
1466
|
+
Object.assign(files, uiKitFiles());
|
|
1466
1467
|
Object.assign(files, realPageFiles(ctx));
|
|
1467
1468
|
if (isBlog) {
|
|
1468
1469
|
files["lib/posts.ts"] = postsLib();
|
|
@@ -1901,16 +1902,21 @@ export default function Home() {
|
|
|
1901
1902
|
);
|
|
1902
1903
|
}
|
|
1903
1904
|
`;
|
|
1905
|
+
var ctaBandJsx = (c2) => ` <CTABand title=${JSON.stringify(c2.title)}${c2.subtitle ? ` subtitle=${JSON.stringify(c2.subtitle)}` : ""}${c2.label ? ` ctaLabel=${JSON.stringify(c2.label)}` : ""}${c2.href ? ` ctaHref=${JSON.stringify(c2.href)}` : ""} />`;
|
|
1904
1906
|
var pageFile = (o) => `import type { Metadata } from "next";
|
|
1905
1907
|
import Link from "next/link";
|
|
1906
1908
|
import { site } from "@/lib/site";
|
|
1909
|
+
import { Aurora } from "@/components/aurora";
|
|
1910
|
+
import { Section, Pill, StatCard, FeatureCard, Testimonial, Steps, CTABand } from "@/components/ui";
|
|
1907
1911
|
|
|
1908
1912
|
export const metadata: Metadata = site.meta({ title: ${JSON.stringify(o.title)}, path: ${JSON.stringify(o.path)}, description: ${JSON.stringify(o.description)} });
|
|
1909
1913
|
|
|
1910
1914
|
export default function Page() {
|
|
1911
1915
|
return (
|
|
1912
|
-
<main className="min-h-screen">
|
|
1916
|
+
<main className="relative min-h-screen overflow-hidden">
|
|
1917
|
+
<Aurora />
|
|
1913
1918
|
${o.body}
|
|
1919
|
+
${o.cta ? ctaBandJsx(o.cta) : ""}
|
|
1914
1920
|
</main>
|
|
1915
1921
|
);
|
|
1916
1922
|
}
|
|
@@ -1919,9 +1925,10 @@ var pricingPage = (ctx) => pageFile({
|
|
|
1919
1925
|
title: "Pricing",
|
|
1920
1926
|
path: "/pricing",
|
|
1921
1927
|
description: `Simple, transparent pricing for ${ctx.template.siteName}. Start free and upgrade anytime.`,
|
|
1928
|
+
cta: { title: "Still deciding?", subtitle: "Talk to us and we'll help you pick the right plan.", label: "Contact sales", href: "/contact" },
|
|
1922
1929
|
body: ` <section className="mx-auto max-w-3xl px-6 py-24 text-center">
|
|
1923
|
-
<
|
|
1924
|
-
<h1 className="mt-
|
|
1930
|
+
<Pill>Pricing</Pill>
|
|
1931
|
+
<h1 className="mt-4 text-4xl font-bold sm:text-5xl">Simple, transparent <span className="gradient-text">pricing</span></h1>
|
|
1925
1932
|
<p className="mx-auto mt-4 max-w-xl text-lg text-muted">Start free. Upgrade when you're ready. Cancel anytime.</p>
|
|
1926
1933
|
</section>
|
|
1927
1934
|
<section className="mx-auto max-w-6xl px-6 pb-24">
|
|
@@ -1949,15 +1956,19 @@ var pricingPage = (ctx) => pageFile({
|
|
|
1949
1956
|
))}
|
|
1950
1957
|
</div>
|
|
1951
1958
|
<p className="mt-10 text-center text-sm text-faint">All plans include SSL, unlimited bandwidth and a 14-day money-back guarantee.</p>
|
|
1959
|
+
</section>
|
|
1960
|
+
<section className="px-6 pb-8">
|
|
1961
|
+
<Testimonial quote="We switched in an afternoon and never looked back. Worth every penny." author="Sam Rivera" role="CTO, Globex" />
|
|
1952
1962
|
</section>`
|
|
1953
1963
|
});
|
|
1954
1964
|
var servicesPage = (ctx) => pageFile({
|
|
1955
1965
|
title: "Services",
|
|
1956
1966
|
path: "/services",
|
|
1957
1967
|
description: `What ${ctx.template.siteName} can do for you \u2014 from strategy to launch.`,
|
|
1968
|
+
cta: { title: "Have a project in mind?", subtitle: "Tell us what you're building and we'll take it from there.", label: "Start a conversation", href: "/contact" },
|
|
1958
1969
|
body: ` <section className="mx-auto max-w-3xl px-6 py-24 text-center">
|
|
1959
|
-
<
|
|
1960
|
-
<h1 className="mt-
|
|
1970
|
+
<Pill>Services</Pill>
|
|
1971
|
+
<h1 className="mt-4 text-4xl font-bold sm:text-5xl">What we <span className="gradient-text">do</span></h1>
|
|
1961
1972
|
<p className="mx-auto mt-4 max-w-xl text-lg text-muted">End-to-end help \u2014 from the first sketch to a product your customers love.</p>
|
|
1962
1973
|
</section>
|
|
1963
1974
|
<section className="mx-auto max-w-6xl px-6 pb-16">
|
|
@@ -1970,29 +1981,25 @@ var servicesPage = (ctx) => pageFile({
|
|
|
1970
1981
|
{ icon: "\u{1F4C8}", title: "Growth", desc: "Experiments and optimization that move the numbers." },
|
|
1971
1982
|
{ icon: "\u{1F91D}", title: "Support", desc: "Ongoing care so your product keeps getting better." },
|
|
1972
1983
|
].map((s) => (
|
|
1973
|
-
<
|
|
1974
|
-
<div className="mb-4 inline-flex h-12 w-12 items-center justify-center rounded-xl gradient-bg text-2xl">{s.icon}</div>
|
|
1975
|
-
<h3 className="font-semibold">{s.title}</h3>
|
|
1976
|
-
<p className="mt-1 text-sm text-muted">{s.desc}</p>
|
|
1977
|
-
</div>
|
|
1984
|
+
<FeatureCard key={s.title} icon={s.icon} title={s.title} desc={s.desc} />
|
|
1978
1985
|
))}
|
|
1979
1986
|
</div>
|
|
1980
1987
|
</section>
|
|
1981
|
-
<section className="
|
|
1982
|
-
<
|
|
1983
|
-
<Link href="/contact" className="mt-6 inline-block rounded-full gradient-bg px-8 py-3 font-semibold text-black">Start a conversation</Link>
|
|
1988
|
+
<section className="px-6 pb-8">
|
|
1989
|
+
<Testimonial quote="They shipped faster than we thought possible \u2014 and it looked incredible." author="Jordan Ellis" role="Founder, Northwind" />
|
|
1984
1990
|
</section>`
|
|
1985
1991
|
});
|
|
1986
1992
|
var featuresPage = (ctx) => pageFile({
|
|
1987
1993
|
title: "Features",
|
|
1988
1994
|
path: "/features",
|
|
1989
1995
|
description: `Everything ${ctx.template.siteName} gives your team, in one place.`,
|
|
1996
|
+
cta: { title: "Ready to ship faster?", subtitle: "Start free \u2014 no credit card required.", label: "See pricing", href: "/pricing" },
|
|
1990
1997
|
body: ` <section className="mx-auto max-w-3xl px-6 py-24 text-center">
|
|
1991
|
-
<
|
|
1992
|
-
<h1 className="mt-
|
|
1998
|
+
<Pill>Features</Pill>
|
|
1999
|
+
<h1 className="mt-4 text-4xl font-bold sm:text-5xl">Built to <span className="gradient-text">ship faster</span></h1>
|
|
1993
2000
|
<p className="mx-auto mt-4 max-w-xl text-lg text-muted">A focused set of features that do the heavy lifting so your team can move.</p>
|
|
1994
2001
|
</section>
|
|
1995
|
-
<section className="mx-auto max-w-6xl px-6 pb-
|
|
2002
|
+
<section className="mx-auto max-w-6xl px-6 pb-16">
|
|
1996
2003
|
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
1997
2004
|
{[
|
|
1998
2005
|
{ icon: "\u26A1", title: "Fast by default", desc: "Edge-rendered and cached \u2014 instant everywhere." },
|
|
@@ -2002,25 +2009,27 @@ var featuresPage = (ctx) => pageFile({
|
|
|
2002
2009
|
{ icon: "\u{1F9E9}", title: "Extensible", desc: "A clean API and webhooks for anything custom." },
|
|
2003
2010
|
{ icon: "\u{1F317}", title: "Delightful UX", desc: "Dark mode, a \u2318K palette and thoughtful details." },
|
|
2004
2011
|
].map((f) => (
|
|
2005
|
-
<
|
|
2006
|
-
<div className="mb-4 inline-flex h-12 w-12 items-center justify-center rounded-xl gradient-bg text-2xl">{f.icon}</div>
|
|
2007
|
-
<h3 className="font-semibold">{f.title}</h3>
|
|
2008
|
-
<p className="mt-1 text-sm text-muted">{f.desc}</p>
|
|
2009
|
-
</div>
|
|
2012
|
+
<FeatureCard key={f.title} icon={f.icon} title={f.title} desc={f.desc} />
|
|
2010
2013
|
))}
|
|
2011
2014
|
</div>
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
</
|
|
2015
|
+
</section>
|
|
2016
|
+
<section className="mx-auto max-w-5xl px-6 pb-8">
|
|
2017
|
+
<h2 className="mb-8 text-center text-2xl font-bold">How it works</h2>
|
|
2018
|
+
<Steps items={[
|
|
2019
|
+
{ title: "Connect", desc: "Sign up and link the tools you already use." },
|
|
2020
|
+
{ title: "Configure", desc: "Set it up your way in a few clicks \u2014 no code required." },
|
|
2021
|
+
{ title: "Ship", desc: "Go live and watch the numbers in real time." },
|
|
2022
|
+
]} />
|
|
2015
2023
|
</section>`
|
|
2016
2024
|
});
|
|
2017
2025
|
var workPage = (ctx) => pageFile({
|
|
2018
2026
|
title: "Work",
|
|
2019
2027
|
path: "/work",
|
|
2020
2028
|
description: `Selected projects by ${ctx.template.siteName}.`,
|
|
2029
|
+
cta: { title: "Have something in mind?", subtitle: "I'm currently open to new projects.", label: "Get in touch", href: "/contact" },
|
|
2021
2030
|
body: ` <section className="mx-auto max-w-3xl px-6 py-24">
|
|
2022
|
-
<
|
|
2023
|
-
<h1 className="mt-
|
|
2031
|
+
<Pill>Work</Pill>
|
|
2032
|
+
<h1 className="mt-4 text-4xl font-bold sm:text-5xl">Selected <span className="gradient-text">work</span></h1>
|
|
2024
2033
|
<p className="mt-4 text-lg text-muted">A few things I've designed and built recently.</p>
|
|
2025
2034
|
</section>
|
|
2026
2035
|
<section className="mx-auto max-w-6xl px-6 pb-24">
|
|
@@ -2049,9 +2058,10 @@ var menuPage = (ctx) => pageFile({
|
|
|
2049
2058
|
title: "Menu",
|
|
2050
2059
|
path: "/menu",
|
|
2051
2060
|
description: `The menu at ${ctx.template.siteName} \u2014 seasonal plates and natural wine.`,
|
|
2061
|
+
cta: { title: "Hungry?", subtitle: "Book a table \u2014 we can't wait to cook for you.", label: "Reserve a table", href: "/reservations" },
|
|
2052
2062
|
body: ` <section className="mx-auto max-w-3xl px-6 py-24 text-center">
|
|
2053
|
-
<
|
|
2054
|
-
<h1 className="mt-
|
|
2063
|
+
<Pill>Menu</Pill>
|
|
2064
|
+
<h1 className="mt-4 text-4xl font-bold sm:text-5xl gradient-text">Tonight's menu</h1>
|
|
2055
2065
|
<p className="mx-auto mt-4 max-w-xl text-lg text-muted">Seasonal, ingredient-led and always changing. Here's what we're serving now.</p>
|
|
2056
2066
|
</section>
|
|
2057
2067
|
<section className="mx-auto max-w-3xl px-6 pb-24">
|
|
@@ -2072,18 +2082,16 @@ var menuPage = (ctx) => pageFile({
|
|
|
2072
2082
|
</div>
|
|
2073
2083
|
</div>
|
|
2074
2084
|
))}
|
|
2075
|
-
<div className="text-center">
|
|
2076
|
-
<Link href="/reservations" className="inline-block rounded-full gradient-bg px-8 py-3 font-semibold text-black">Book a table</Link>
|
|
2077
|
-
</div>
|
|
2078
2085
|
</section>`
|
|
2079
2086
|
});
|
|
2080
2087
|
var cardGridPage = (o) => pageFile({
|
|
2081
2088
|
title: o.title,
|
|
2082
2089
|
path: o.path,
|
|
2083
2090
|
description: o.lead,
|
|
2091
|
+
cta: o.cta,
|
|
2084
2092
|
body: ` <section className="mx-auto max-w-3xl px-6 py-24">
|
|
2085
|
-
<
|
|
2086
|
-
<h1 className="mt-
|
|
2093
|
+
<Pill>${o.eyebrow}</Pill>
|
|
2094
|
+
<h1 className="mt-4 text-4xl font-bold sm:text-5xl">${o.heading}</h1>
|
|
2087
2095
|
<p className="mt-4 text-lg text-muted">${o.lead}</p>
|
|
2088
2096
|
</section>
|
|
2089
2097
|
<section className="mx-auto max-w-6xl px-6 pb-24">
|
|
@@ -2103,6 +2111,7 @@ var topicsPage = (ctx) => cardGridPage({
|
|
|
2103
2111
|
eyebrow: "Topics",
|
|
2104
2112
|
heading: "Browse by topic",
|
|
2105
2113
|
lead: "Find what you care about \u2014 from deep dives to quick notes.",
|
|
2114
|
+
cta: { title: "Never miss a post", subtitle: "Subscribe and get new pieces in your inbox.", label: "Join the newsletter", href: "/newsletter" },
|
|
2106
2115
|
items: [
|
|
2107
2116
|
{ title: "Engineering", desc: "How we build and the decisions behind it." },
|
|
2108
2117
|
{ title: "Design", desc: "Craft, systems and the details that matter." },
|
|
@@ -2118,6 +2127,7 @@ var guidesPage = (ctx) => cardGridPage({
|
|
|
2118
2127
|
eyebrow: "Guides",
|
|
2119
2128
|
heading: "Guides & tutorials",
|
|
2120
2129
|
lead: "Task-focused walkthroughs to get you productive fast.",
|
|
2130
|
+
cta: { title: "Can't find what you need?", subtitle: "We're happy to help \u2014 reach out any time.", label: "Contact us", href: "/contact" },
|
|
2121
2131
|
items: [
|
|
2122
2132
|
{ title: "Getting started", desc: "Install, configure and run your first build." },
|
|
2123
2133
|
{ title: "Authentication", desc: "Add sign-in, sessions and protected routes." },
|
|
@@ -2301,6 +2311,97 @@ export function SettingsPanel() {
|
|
|
2301
2311
|
);
|
|
2302
2312
|
}
|
|
2303
2313
|
`;
|
|
2314
|
+
var uiKitFiles = () => ({
|
|
2315
|
+
"components/ui/section.tsx": `import type { ReactNode } from "react";
|
|
2316
|
+
|
|
2317
|
+
export function Section({ eyebrow, title, lead, children, className = "" }: { eyebrow?: string; title?: string; lead?: string; children?: ReactNode; className?: string }) {
|
|
2318
|
+
return (
|
|
2319
|
+
<section className={"mx-auto max-w-6xl px-6 py-16 " + className}>
|
|
2320
|
+
{eyebrow ? <p className="text-sm font-semibold uppercase tracking-widest text-faint">{eyebrow}</p> : null}
|
|
2321
|
+
{title ? <h2 className="mt-3 text-3xl font-bold sm:text-4xl">{title}</h2> : null}
|
|
2322
|
+
{lead ? <p className="mt-4 max-w-2xl text-lg text-muted">{lead}</p> : null}
|
|
2323
|
+
{children ? <div className="mt-10">{children}</div> : null}
|
|
2324
|
+
</section>
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
`,
|
|
2328
|
+
"components/ui/pill.tsx": `import type { ReactNode } from "react";
|
|
2329
|
+
|
|
2330
|
+
export function Pill({ children, className = "" }: { children: ReactNode; className?: string }) {
|
|
2331
|
+
return <span className={"inline-flex items-center gap-1 rounded-full border border-hairline bg-surface px-3 py-1 text-xs font-semibold uppercase tracking-widest text-muted " + className}>{children}</span>;
|
|
2332
|
+
}
|
|
2333
|
+
`,
|
|
2334
|
+
"components/ui/stat-card.tsx": `export function StatCard({ label, value, delta }: { label: string; value: string; delta?: string }) {
|
|
2335
|
+
return (
|
|
2336
|
+
<div className="rounded-2xl border border-hairline bg-surface p-6 transition hover:-translate-y-1">
|
|
2337
|
+
<div className="text-3xl font-bold tabular-nums">{value}</div>
|
|
2338
|
+
<div className="mt-1 text-sm text-muted">{label}</div>
|
|
2339
|
+
{delta ? <div className="mt-2 text-xs font-medium text-emerald-400">{delta}</div> : null}
|
|
2340
|
+
</div>
|
|
2341
|
+
);
|
|
2342
|
+
}
|
|
2343
|
+
`,
|
|
2344
|
+
"components/ui/feature-card.tsx": `import type { ReactNode } from "react";
|
|
2345
|
+
|
|
2346
|
+
export function FeatureCard({ icon, title, desc }: { icon?: ReactNode; title: string; desc: string }) {
|
|
2347
|
+
return (
|
|
2348
|
+
<div className="rounded-2xl border border-hairline bg-surface p-6 transition hover:-translate-y-1 hover:border-[color:var(--accent-to)]">
|
|
2349
|
+
{icon ? <div className="mb-4 inline-flex h-12 w-12 items-center justify-center rounded-xl gradient-bg text-2xl">{icon}</div> : null}
|
|
2350
|
+
<h3 className="font-semibold">{title}</h3>
|
|
2351
|
+
<p className="mt-1 text-sm leading-relaxed text-muted">{desc}</p>
|
|
2352
|
+
</div>
|
|
2353
|
+
);
|
|
2354
|
+
}
|
|
2355
|
+
`,
|
|
2356
|
+
"components/ui/testimonial.tsx": `export function Testimonial({ quote, author, role }: { quote: string; author: string; role?: string }) {
|
|
2357
|
+
return (
|
|
2358
|
+
<figure className="mx-auto max-w-2xl rounded-3xl border border-hairline bg-surface p-8 text-center">
|
|
2359
|
+
<div className="text-4xl leading-none gradient-text">“</div>
|
|
2360
|
+
<blockquote className="mt-2 text-lg font-medium leading-relaxed">{quote}</blockquote>
|
|
2361
|
+
<figcaption className="mt-4 text-sm text-muted">\u2014 {author}{role ? ", " + role : ""}</figcaption>
|
|
2362
|
+
</figure>
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
`,
|
|
2366
|
+
"components/ui/steps.tsx": `export function Steps({ items }: { items: { title: string; desc: string }[] }) {
|
|
2367
|
+
return (
|
|
2368
|
+
<ol className="grid gap-6 sm:grid-cols-3">
|
|
2369
|
+
{items.map((s, i) => (
|
|
2370
|
+
<li key={s.title} className="rounded-2xl border border-hairline bg-surface p-6">
|
|
2371
|
+
<div className="mb-3 inline-flex h-8 w-8 items-center justify-center rounded-full gradient-bg text-sm font-bold text-black">{i + 1}</div>
|
|
2372
|
+
<h3 className="font-semibold">{s.title}</h3>
|
|
2373
|
+
<p className="mt-1 text-sm text-muted">{s.desc}</p>
|
|
2374
|
+
</li>
|
|
2375
|
+
))}
|
|
2376
|
+
</ol>
|
|
2377
|
+
);
|
|
2378
|
+
}
|
|
2379
|
+
`,
|
|
2380
|
+
"components/ui/cta-band.tsx": `import Link from "next/link";
|
|
2381
|
+
|
|
2382
|
+
export function CTABand({ title, subtitle, ctaLabel = "Get started", ctaHref = "/contact" }: { title: string; subtitle?: string; ctaLabel?: string; ctaHref?: string }) {
|
|
2383
|
+
return (
|
|
2384
|
+
<section className="mx-auto max-w-6xl px-6 py-20">
|
|
2385
|
+
<div className="relative overflow-hidden rounded-3xl border border-hairline bg-surface p-10 text-center sm:p-16">
|
|
2386
|
+
<div aria-hidden className="pointer-events-none absolute -right-16 -top-16 h-56 w-56 rounded-full gradient-bg opacity-40 blur-3xl animate-floaty" />
|
|
2387
|
+
<div aria-hidden className="pointer-events-none absolute -bottom-16 -left-16 h-56 w-56 rounded-full gradient-bg opacity-30 blur-3xl animate-floaty-slow" />
|
|
2388
|
+
<h2 className="relative text-3xl font-bold sm:text-4xl">{title}</h2>
|
|
2389
|
+
{subtitle ? <p className="relative mx-auto mt-3 max-w-xl text-muted">{subtitle}</p> : null}
|
|
2390
|
+
<Link href={ctaHref} className="relative mt-8 inline-block rounded-full gradient-bg px-8 py-3 font-semibold text-black transition hover:opacity-90">{ctaLabel}</Link>
|
|
2391
|
+
</div>
|
|
2392
|
+
</section>
|
|
2393
|
+
);
|
|
2394
|
+
}
|
|
2395
|
+
`,
|
|
2396
|
+
"components/ui/index.ts": `export * from "./section";
|
|
2397
|
+
export * from "./pill";
|
|
2398
|
+
export * from "./stat-card";
|
|
2399
|
+
export * from "./feature-card";
|
|
2400
|
+
export * from "./testimonial";
|
|
2401
|
+
export * from "./steps";
|
|
2402
|
+
export * from "./cta-band";
|
|
2403
|
+
`
|
|
2404
|
+
});
|
|
2304
2405
|
function realPageFiles(ctx) {
|
|
2305
2406
|
const k = ctx.template.key;
|
|
2306
2407
|
const f = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-lacspace-app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Scaffold a beautiful, production-ready Next.js app from a Lacspace template — portfolio, business, e-commerce, SaaS, blog, docs, dashboard or restaurant — pre-wired with SEO, security headers, sitemap and robots. Like create-next-app, but you start gorgeous.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|