@vitrine-kit/vitrine 0.3.1 → 0.4.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 +102 -83
- package/kit/registry/README.md +9 -0
- package/kit/registry/_index.json +74 -0
- package/kit/registry/cart/docs/cart.md +13 -0
- package/kit/registry/cart/feature.json +51 -0
- package/kit/registry/cart/files/app/(frontend)/cart/page.tsx +21 -0
- package/kit/registry/cart/files/app/api/cart/route.ts +41 -0
- package/kit/registry/cart/files/components/cart/AddToCart.tsx +40 -0
- package/kit/registry/cart/files/components/cart/CartIndicator.tsx +11 -0
- package/kit/registry/cart/files/components/cart/CartLineItem.tsx +27 -0
- package/kit/registry/cart/files/components/cart/CartSummary.tsx +31 -0
- package/kit/registry/cart/files/components/cart/CartView.tsx +31 -0
- package/kit/registry/cart/files/lib/cart/data.ts +12 -0
- package/kit/registry/cart/files/lib/cart/register.ts +10 -0
- package/kit/registry/catalog/docs/catalog.md +18 -0
- package/kit/registry/catalog/feature.json +43 -0
- package/kit/registry/catalog/files/components/catalog/CategoryNav.tsx +26 -0
- package/kit/registry/catalog/files/components/catalog/ProductCard.tsx +42 -0
- package/kit/registry/catalog/files/components/catalog/ProductGrid.tsx +25 -0
- package/kit/registry/catalog/files/lib/catalog/data.ts +24 -0
- package/kit/registry/catalog/files/lib/catalog/register.ts +8 -0
- package/kit/registry/checkout/docs/checkout.md +17 -0
- package/kit/registry/checkout/feature.json +47 -0
- package/kit/registry/checkout/files/app/api/checkout/route.ts +14 -0
- package/kit/registry/checkout/files/components/checkout/CheckoutButton.tsx +31 -0
- package/kit/registry/checkout/files/lib/checkout/fulfill.ts +72 -0
- package/kit/registry/checkout/files/lib/checkout/register.ts +8 -0
- package/kit/registry/checkout-paddle/docs/checkout-paddle.md +22 -0
- package/kit/registry/checkout-paddle/feature.json +62 -0
- package/kit/registry/checkout-paddle/files/app/api/webhooks/paddle/route.ts +22 -0
- package/kit/registry/checkout-paddle/files/lib/checkout-paddle/provider.ts +59 -0
- package/kit/registry/checkout-paddle/files/lib/checkout-paddle/register.ts +7 -0
- package/kit/registry/checkout-stripe/docs/checkout-stripe.md +17 -0
- package/kit/registry/checkout-stripe/feature.json +54 -0
- package/kit/registry/checkout-stripe/files/app/api/webhooks/stripe/route.ts +23 -0
- package/kit/registry/checkout-stripe/files/lib/checkout-stripe/provider.ts +73 -0
- package/kit/registry/checkout-stripe/files/lib/checkout-stripe/register.ts +7 -0
- package/kit/registry/checkout-yookassa/docs/checkout-yookassa.md +20 -0
- package/kit/registry/checkout-yookassa/feature.json +52 -0
- package/kit/registry/checkout-yookassa/files/app/api/webhooks/yookassa/route.ts +22 -0
- package/kit/registry/checkout-yookassa/files/lib/checkout-yookassa/provider.ts +82 -0
- package/kit/registry/checkout-yookassa/files/lib/checkout-yookassa/register.ts +7 -0
- package/kit/registry/product-page/docs/product-page.md +16 -0
- package/kit/registry/product-page/feature.json +39 -0
- package/kit/registry/product-page/files/components/product/ProductGallery.tsx +37 -0
- package/kit/registry/product-page/files/components/product/ProductView.tsx +42 -0
- package/kit/registry/product-page/files/lib/product/data.ts +10 -0
- package/kit/registry/seo/docs/seo.md +14 -0
- package/kit/registry/seo/feature.json +35 -0
- package/kit/registry/seo/files/components/seo/JsonLd.tsx +15 -0
- package/kit/registry/seo/files/lib/seo/jsonld.ts +29 -0
- package/kit/registry/seo/files/lib/seo/metadata.ts +35 -0
- package/kit/registry/stubs/route-glue.d.ts +45 -0
- package/kit/registry/tsconfig.json +21 -0
- package/kit/registry/tsconfig.routes.json +9 -0
- package/kit/templates/README.md +27 -0
- package/kit/templates/backend-payload/files/.dockerignore +8 -0
- package/kit/templates/backend-payload/files/Dockerfile +29 -0
- package/kit/templates/backend-payload/files/app/(payload)/admin/[[...segments]]/not-found.tsx +18 -0
- package/kit/templates/backend-payload/files/app/(payload)/admin/[[...segments]]/page.tsx +18 -0
- package/kit/templates/backend-payload/files/app/(payload)/admin/importMap.js +3 -0
- package/kit/templates/backend-payload/files/app/(payload)/api/[...slug]/route.ts +18 -0
- package/kit/templates/backend-payload/files/app/(payload)/api/graphql/route.ts +6 -0
- package/kit/templates/backend-payload/files/app/(payload)/api/graphql-playground/route.ts +5 -0
- package/kit/templates/backend-payload/files/app/(payload)/custom.scss +1 -0
- package/kit/templates/backend-payload/files/app/(payload)/layout.tsx +23 -0
- package/kit/templates/backend-payload/files/docker-compose.yml +35 -0
- package/kit/templates/backend-payload/files/lib/adapter/db-decision.ts +43 -0
- package/kit/templates/backend-payload/files/lib/adapter/db-ping.ts +29 -0
- package/kit/templates/backend-payload/files/lib/adapter/db.ts +27 -0
- package/kit/templates/backend-payload/files/lib/adapter/index.ts +31 -0
- package/kit/templates/backend-payload/files/lib/adapter/map.ts +112 -0
- package/kit/templates/backend-payload/files/lib/adapter/payload-catalog.ts +79 -0
- package/kit/templates/backend-payload/files/lib/adapter/payload-commerce.ts +154 -0
- package/kit/templates/backend-payload/files/lib/adapter/payload-types.ts +50 -0
- package/kit/templates/backend-payload/files/lib/seed/admin.ts +23 -0
- package/kit/templates/backend-payload/files/lib/seed/demo.ts +79 -0
- package/kit/templates/backend-payload/files/lib/seed/guards.ts +5 -0
- package/kit/templates/backend-payload/files/lib/seed/richtext.ts +26 -0
- package/kit/templates/backend-payload/files/lib/seed/run.ts +51 -0
- package/kit/templates/backend-payload/files/next.config.mjs +10 -0
- package/kit/templates/backend-payload/files/payload.config.ts +32 -0
- package/kit/templates/backend-payload/files/seed-assets/placeholder-1.svg +5 -0
- package/kit/templates/backend-payload/files/seed-assets/placeholder-2.svg +5 -0
- package/kit/templates/backend-payload/files/seed-assets/placeholder-3.svg +5 -0
- package/kit/templates/backend-payload/files/seed-assets/placeholder-4.svg +5 -0
- package/kit/templates/backend-payload/files/seed-assets/placeholder-5.svg +5 -0
- package/kit/templates/backend-vendure/files/.dockerignore +8 -0
- package/kit/templates/backend-vendure/files/Dockerfile +24 -0
- package/kit/templates/backend-vendure/files/docker-compose.yml +50 -0
- package/kit/templates/backend-vendure/files/lib/adapter/graphql.ts +27 -0
- package/kit/templates/backend-vendure/files/lib/adapter/index.ts +20 -0
- package/kit/templates/backend-vendure/files/lib/adapter/map.ts +107 -0
- package/kit/templates/backend-vendure/files/lib/adapter/vendure-catalog.ts +62 -0
- package/kit/templates/backend-vendure/files/lib/adapter/vendure-commerce.ts +76 -0
- package/kit/templates/backend-vendure/files/lib/adapter/vendure-types.ts +61 -0
- package/kit/templates/backend-vendure/files/lib/seed/populate.ts +22 -0
- package/kit/templates/backend-vendure/files/src/index.ts +15 -0
- package/kit/templates/backend-vendure/files/vendure-config.ts +56 -0
- package/kit/templates/base/files/.claude/commands/add-feature.md +18 -0
- package/kit/templates/base/files/.claude/commands/design.md +14 -0
- package/kit/templates/base/files/.claude/commands/doctor.md +15 -0
- package/kit/templates/base/files/.claude/commands/setup.md +15 -0
- package/kit/templates/base/files/.claude/commands/update.md +16 -0
- package/kit/templates/base/files/AGENTS.md +20 -0
- package/kit/templates/base/files/app/(frontend)/categories/[slug]/page.tsx +28 -0
- package/kit/templates/base/files/app/(frontend)/layout.tsx +32 -0
- package/kit/templates/base/files/app/(frontend)/page.tsx +27 -0
- package/kit/templates/base/files/app/(frontend)/products/[slug]/page.tsx +43 -0
- package/kit/templates/base/files/app/globals.css +6 -0
- package/kit/templates/base/files/components/layout/SiteFooter.tsx +15 -0
- package/kit/templates/base/files/components/layout/SiteHeader.tsx +23 -0
- package/kit/templates/base/files/design/README.md +9 -0
- package/kit/templates/base/files/lib/site.ts +10 -0
- package/kit/templates/base/files/next.config.mjs +7 -0
- package/kit/templates/base/files/postcss.config.mjs +7 -0
- package/kit/templates/base/files/public/.gitkeep +0 -0
- package/kit/templates/base/files/tailwind.config.ts +13 -0
- package/kit/templates/base/files/tsconfig.json +25 -0
- package/kit/templates/tsconfig.json +18 -0
- package/package.json +5 -4
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Root storefront layout (route group (frontend)). The Payload admin lives in
|
|
2
|
+
// its own route group (payload) with its own layout — so there's no root app/layout,
|
|
3
|
+
// and each group renders its own <html> (the Payload 3 + Next pattern).
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
import type { Metadata } from 'next';
|
|
6
|
+
import '../globals.css';
|
|
7
|
+
import { siteConfig } from '@/site.config';
|
|
8
|
+
import { registerSlots } from '@/lib/slots';
|
|
9
|
+
import { Slot } from '@vitrine-kit/core/react';
|
|
10
|
+
import { SiteHeader } from '@/components/layout/SiteHeader';
|
|
11
|
+
import { SiteFooter } from '@/components/layout/SiteFooter';
|
|
12
|
+
|
|
13
|
+
// Register installed features' slots (lib/slots.ts is generated by the CLI).
|
|
14
|
+
registerSlots();
|
|
15
|
+
|
|
16
|
+
export const metadata: Metadata = {
|
|
17
|
+
title: { default: 'Vitrine', template: '%s · Vitrine' },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default function FrontendLayout({ children }: { children: ReactNode }) {
|
|
21
|
+
return (
|
|
22
|
+
<html lang={siteConfig.i18n.defaultLocale}>
|
|
23
|
+
<body className="min-h-screen bg-bg font-sans text-fg antialiased">
|
|
24
|
+
<Slot name="global.banner-top" />
|
|
25
|
+
<SiteHeader />
|
|
26
|
+
<main className="mx-auto w-full max-w-container px-gutter py-section">{children}</main>
|
|
27
|
+
<SiteFooter />
|
|
28
|
+
<Slot name="global.body-end" />
|
|
29
|
+
</body>
|
|
30
|
+
</html>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Storefront home: catalog listing. Data via the CatalogSource contract
|
|
2
|
+
// (backend-agnostic); the grid is the catalog feature's component.
|
|
3
|
+
import { Slot } from '@vitrine-kit/core/react';
|
|
4
|
+
import { getCatalogSource } from '@/lib/adapter';
|
|
5
|
+
import { loadProducts } from '@/lib/catalog/data';
|
|
6
|
+
import { ProductGrid } from '@/components/catalog/ProductGrid';
|
|
7
|
+
|
|
8
|
+
export default async function HomePage() {
|
|
9
|
+
const source = await getCatalogSource();
|
|
10
|
+
const products = await loadProducts(source, { perPage: 12 });
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className="flex flex-col gap-section">
|
|
14
|
+
<Slot name="home.hero" />
|
|
15
|
+
<section aria-labelledby="catalog-heading" className="flex flex-col gap-gutter">
|
|
16
|
+
<h1 id="catalog-heading" className="font-heading text-fg">
|
|
17
|
+
Catalog
|
|
18
|
+
</h1>
|
|
19
|
+
<Slot name="catalog.grid-top" />
|
|
20
|
+
<ProductGrid products={products} />
|
|
21
|
+
<Slot name="catalog.grid-bottom" />
|
|
22
|
+
</section>
|
|
23
|
+
<Slot name="home.sections" />
|
|
24
|
+
<Slot name="home.bottom" />
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Product page. ProductView (the product-page feature) hosts the product.* slots.
|
|
2
|
+
// Metadata and JSON-LD come from the seo feature.
|
|
3
|
+
import type { Metadata } from 'next';
|
|
4
|
+
import { notFound } from 'next/navigation';
|
|
5
|
+
import { getCatalogSource } from '@/lib/adapter';
|
|
6
|
+
import { loadProduct } from '@/lib/catalog/data';
|
|
7
|
+
import { ProductView } from '@/components/product/ProductView';
|
|
8
|
+
import { buildProductMetadata } from '@/lib/seo/metadata';
|
|
9
|
+
import { productJsonLd } from '@/lib/seo/jsonld';
|
|
10
|
+
import { JsonLd } from '@/components/seo/JsonLd';
|
|
11
|
+
import { baseUrl } from '@/lib/site';
|
|
12
|
+
|
|
13
|
+
interface PageProps {
|
|
14
|
+
params: Promise<{ slug: string }>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
|
18
|
+
const { slug } = await params;
|
|
19
|
+
const source = await getCatalogSource();
|
|
20
|
+
const product = await loadProduct(source, slug);
|
|
21
|
+
if (!product) return {};
|
|
22
|
+
const meta = buildProductMetadata(product, { baseUrl });
|
|
23
|
+
return {
|
|
24
|
+
title: meta.title,
|
|
25
|
+
description: meta.description,
|
|
26
|
+
alternates: meta.canonical ? { canonical: meta.canonical } : undefined,
|
|
27
|
+
openGraph: meta.openGraph,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default async function ProductPage({ params }: PageProps) {
|
|
32
|
+
const { slug } = await params;
|
|
33
|
+
const source = await getCatalogSource();
|
|
34
|
+
const product = await loadProduct(source, slug);
|
|
35
|
+
if (!product) notFound();
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
<JsonLd data={productJsonLd(product, { baseUrl })} />
|
|
40
|
+
<ProductView product={product} />
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Storefront footer. Hosts the global.footer slot.
|
|
2
|
+
import { Slot } from '@vitrine-kit/core/react';
|
|
3
|
+
|
|
4
|
+
export function SiteFooter() {
|
|
5
|
+
return (
|
|
6
|
+
<footer className="mt-section border-t border-border">
|
|
7
|
+
<div className="mx-auto max-w-container px-gutter py-section text-muted-fg">
|
|
8
|
+
<Slot
|
|
9
|
+
name="global.footer"
|
|
10
|
+
fallback={<p>© {new Date().getFullYear()}</p>}
|
|
11
|
+
/>
|
|
12
|
+
</div>
|
|
13
|
+
</footer>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Storefront header. Hosts the global.header-nav slot (where the catalog feature's
|
|
2
|
+
// CategoryNav mounts) and passes it categories from the active CatalogSource.
|
|
3
|
+
import { Slot } from '@vitrine-kit/core/react';
|
|
4
|
+
import { getCatalogSource } from '@/lib/adapter';
|
|
5
|
+
|
|
6
|
+
export async function SiteHeader() {
|
|
7
|
+
const source = await getCatalogSource();
|
|
8
|
+
const categories = await source.listCategories();
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<header className="border-b border-border">
|
|
12
|
+
<div className="mx-auto flex max-w-container items-center justify-between gap-gutter px-gutter py-unit">
|
|
13
|
+
<a href="/" className="font-heading text-fg">
|
|
14
|
+
<Slot name="global.header-start" fallback={<span>Vitrine</span>} />
|
|
15
|
+
</a>
|
|
16
|
+
<Slot name="global.header-nav" categories={categories} />
|
|
17
|
+
<div className="flex items-center gap-unit">
|
|
18
|
+
<Slot name="global.header-actions" />
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</header>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# /design — export from Claude Design
|
|
2
|
+
|
|
3
|
+
Drop your design export here (React/HTML/CSS, tokens, screenshots) and run
|
|
4
|
+
`vitrine design apply`. The AI step reads this folder and the instruction from `CLAUDE.md`,
|
|
5
|
+
then sets **only the token values** in `theme/client.css` (palette, typography, spacing, radii,
|
|
6
|
+
shadows).
|
|
7
|
+
|
|
8
|
+
This folder is isolated from behavior: its contents don't affect logic, data, routing, or a11y —
|
|
9
|
+
only the look, via tokens. Re-running the design step is safe.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Aggregated site parameters from site.config + env. Safe to import on both
|
|
2
|
+
// the server and the client (public values only).
|
|
3
|
+
import { siteConfig } from '@/site.config';
|
|
4
|
+
|
|
5
|
+
/** Base URL for canonical/OG. Overridden by NEXT_PUBLIC_SITE_URL. */
|
|
6
|
+
export const baseUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'http://localhost:3000';
|
|
7
|
+
|
|
8
|
+
export const currency = siteConfig.i18n.currency;
|
|
9
|
+
export const defaultLocale = siteConfig.i18n.defaultLocale;
|
|
10
|
+
export const locales = siteConfig.i18n.locales;
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// The client's Tailwind: the Vitrine preset maps classes to the token contract's
|
|
2
|
+
// CSS variables (--vt-*). The variable values live in theme/client.css (design step).
|
|
3
|
+
import type { Config } from 'tailwindcss';
|
|
4
|
+
import { vitrinePreset } from '@vitrine-kit/contracts';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
presets: [vitrinePreset as Partial<Config>],
|
|
8
|
+
content: [
|
|
9
|
+
'./app/**/*.{ts,tsx}',
|
|
10
|
+
'./components/**/*.{ts,tsx}',
|
|
11
|
+
'./lib/**/*.{ts,tsx}',
|
|
12
|
+
],
|
|
13
|
+
} satisfies Config;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "Bundler",
|
|
7
|
+
"jsx": "preserve",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"allowJs": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"isolatedModules": true,
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"baseUrl": ".",
|
|
17
|
+
"plugins": [{ "name": "next" }],
|
|
18
|
+
"paths": {
|
|
19
|
+
"@/*": ["./*"],
|
|
20
|
+
"@payload-config": ["./payload.config.ts"]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
24
|
+
"exclude": ["node_modules", ".vitrine"]
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"noEmit": true,
|
|
5
|
+
"types": ["node"]
|
|
6
|
+
},
|
|
7
|
+
"//": "We typecheck only the pure template files (contracts + node) — the zero-config critical logic and the mappers. Files that import Next/Payload are checked when the client is instantiated (the stack is installed there).",
|
|
8
|
+
"include": [
|
|
9
|
+
"backend-payload/files/lib/adapter/db-decision.ts",
|
|
10
|
+
"backend-payload/files/lib/adapter/db-ping.ts",
|
|
11
|
+
"backend-payload/files/lib/adapter/payload-types.ts",
|
|
12
|
+
"backend-payload/files/lib/adapter/map.ts",
|
|
13
|
+
"backend-payload/files/lib/seed/demo.ts",
|
|
14
|
+
"backend-payload/files/lib/seed/guards.ts",
|
|
15
|
+
"backend-vendure/files/lib/adapter/vendure-types.ts",
|
|
16
|
+
"backend-vendure/files/lib/adapter/map.ts"
|
|
17
|
+
]
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitrine-kit/vitrine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Vitrine CLI — feature install primitive, init (wizard), add, update, doctor, design apply.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"vitrine": "./dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
-
"dist"
|
|
11
|
+
"dist",
|
|
12
|
+
"kit"
|
|
12
13
|
],
|
|
13
14
|
"publishConfig": {
|
|
14
15
|
"access": "public"
|
|
@@ -24,8 +25,8 @@
|
|
|
24
25
|
"@vitrine-kit/contracts": "1.2.0"
|
|
25
26
|
},
|
|
26
27
|
"scripts": {
|
|
27
|
-
"build": "tsup src/index.ts --format esm --clean",
|
|
28
|
-
"typecheck": "tsc --noEmit",
|
|
28
|
+
"build": "node scripts/generate-kit-versions.mjs && tsup src/index.ts --format esm --clean && node scripts/copy-kit.mjs",
|
|
29
|
+
"typecheck": "node scripts/generate-kit-versions.mjs && tsc --noEmit",
|
|
29
30
|
"test": "vitest run --passWithNoTests"
|
|
30
31
|
}
|
|
31
32
|
}
|