export interface PrintfulMeta { sku: number; sizes?: string[]; colors?: { id: string; name: string; hex: string }[]; } export interface ProductTemplate { id: string; name: string; description: string; // Print area dimensions in mm printArea: { widthMm: number; heightMm: number }; // Output DPI dpi: number; // Bleed in mm bleedMm: number; // What artifact spec fields to use productType: string; substrates: string[]; requiredCapabilities: string[]; finish: string; // Printful product metadata (optional — cosmolocal-only products omit this) printful?: PrintfulMeta; // Computed pixel dimensions (at DPI) get widthPx(): number; get heightPx(): number; } function makeTemplate(opts: Omit): ProductTemplate { return { ...opts, get widthPx() { return Math.round(((this.printArea.widthMm + this.bleedMm * 2) / 25.4) * this.dpi); }, get heightPx() { return Math.round(((this.printArea.heightMm + this.bleedMm * 2) / 25.4) * this.dpi); }, }; } export const PRODUCTS: Record = { sticker: makeTemplate({ id: "sticker", name: "Sticker Sheet", description: "A4 sheet of die-cut vinyl stickers", printArea: { widthMm: 210, heightMm: 297 }, dpi: 300, bleedMm: 2, productType: "sticker-sheet", substrates: ["vinyl-matte", "vinyl-gloss", "sticker-paper-matte"], requiredCapabilities: ["vinyl-cut"], finish: "matte", printful: { sku: 358 }, }), poster: makeTemplate({ id: "poster", name: "Poster (A3)", description: "A3 art print / poster", printArea: { widthMm: 297, heightMm: 420 }, dpi: 300, bleedMm: 3, productType: "poster", substrates: ["paper-160gsm-cover", "paper-100gsm"], requiredCapabilities: ["inkjet-print"], finish: "matte", }), tee: makeTemplate({ id: "tee", name: "T-Shirt", description: "Front print on cotton tee (12x16 inch print area)", printArea: { widthMm: 305, heightMm: 406 }, dpi: 300, bleedMm: 0, productType: "tee", substrates: ["cotton-standard", "cotton-organic"], requiredCapabilities: ["dtg-print"], finish: "none", printful: { sku: 71, sizes: ["S", "M", "L", "XL", "2XL", "3XL"], colors: [ { id: "black", name: "Black", hex: "#0a0a0a" }, { id: "white", name: "White", hex: "#ffffff" }, { id: "forest_green", name: "Forest Green", hex: "#2d4a3e" }, { id: "heather_charcoal", name: "Heather Charcoal", hex: "#4a4a4a" }, { id: "maroon", name: "Maroon", hex: "#5a2d2d" }, ], }, }), hoodie: makeTemplate({ id: "hoodie", name: "Hoodie", description: "Front print on pullover hoodie (14x16 inch print area)", printArea: { widthMm: 356, heightMm: 406 }, dpi: 300, bleedMm: 0, productType: "hoodie", substrates: ["cotton-polyester-blend", "cotton-organic"], requiredCapabilities: ["dtg-print"], finish: "none", printful: { sku: 146, sizes: ["S", "M", "L", "XL", "2XL"], colors: [ { id: "black", name: "Black", hex: "#0a0a0a" }, { id: "dark_grey_heather", name: "Dark Grey Heather", hex: "#3a3a3a" }, ], }, }), }; export function getProduct(id: string): ProductTemplate | undefined { return PRODUCTS[id]; } // ── POD product configurations ── // Maps design product types to POD provider SKUs and pricing export interface PodProductConfig { type: string; provider: "printful" | "prodigi"; sku: string; variants: string[]; retailPrice: number; } /** Default POD product configs applied to each design */ export const POD_PRODUCTS: Record = { sticker: [ { type: "sticker", provider: "prodigi", sku: "GLOBAL-STI-KIS-3X3", variants: ["matte", "gloss"], retailPrice: 3.50 }, ], poster: [ { type: "print", provider: "prodigi", sku: "GLOBAL-FAP-A4", variants: ["matte"], retailPrice: 12.99 }, ], tee: [ { type: "shirt", provider: "printful", sku: "71", variants: ["S", "M", "L", "XL", "2XL"], retailPrice: 29.99 }, ], hoodie: [ { type: "hoodie", provider: "printful", sku: "146", variants: ["S", "M", "L", "XL", "2XL"], retailPrice: 39.99 }, ], }; /** * Get the POD product configs for a product type. * Returns an array of purchasable SKU configurations. */ export function getPodProducts(productType: string): PodProductConfig[] { return POD_PRODUCTS[productType] || []; } /** * Flatten all designs into purchasable storefront products. * Each design × product config = one storefront listing. */ export interface StorefrontProduct { slug: string; designSlug: string; name: string; description: string; category: string; productType: string; imageUrl: string; basePrice: number; variants: string[]; provider: string; sku: string; isActive: boolean; }