'use client'; import React from 'react'; import { NewsletterModule, ProductItem, BadgeTemplate } from '@/types/newsletter'; import { Plus, Trash2, Image as ImageIcon, Tag, Store, Globe, Palette, Check, Code } from 'lucide-react'; import { SUPABASE_ASSETS_BASE } from '@/lib/defaultCampaign'; import { ImageUploadInput } from './ImageUploadInput'; import { pickAlt } from '@/lib/altText'; import { renderGeneratedModuleHtml, CUSTOM_HTML_MODULE_TYPES } from '@/lib/emailRenderer'; const PRODUCT_BG_PRESETS = [ { label: 'Červená', sub: 'Fantasticky', color: '#feeaea', border: '#f5d4d4' }, { label: 'Žltá', sub: 'Domáce', color: '#fef0c7', border: '#e6d49a' }, { label: 'Hnedá', sub: 'Gril', color: '#dcb085', border: '#c49a6c' }, { label: 'Sivá', sub: 'Neutrálna', color: '#e6e1d9', border: '#d5cfc5' }, { label: 'Zelená', sub: 'Bio', color: '#e8f5e9', border: '#c8e6c9' }, { label: 'Biela', sub: 'Čistá', color: '#ffffff', border: '#e5e7eb' }, ]; interface ConfigPanelProps { module: NewsletterModule | null; onUpdateModule: (updated: NewsletterModule) => void; onApplyBadgeToAll?: (badge: BadgeTemplate, badgeLayout?: 'below' | 'side') => void; onSetGlobalValidity?: (validity: string) => void; // nastaví platnosť vo všetkých produktových sekciách onOpenBadgeManager?: (productId: string) => void; onOpenImport?: () => void; availableBadges?: BadgeTemplate[]; } // Pomer strán obrázka (výška / šírka); pri chybe načítania 1 const loadImageAspect = (url: string): Promise => new Promise((resolve) => { if (!url) return resolve(1); const img = new window.Image(); img.onload = () => resolve(img.naturalWidth ? img.naturalHeight / img.naturalWidth : 1); img.onerror = () => resolve(1); img.src = url; }); // Úprava produktovej fotky: zoom a posun (čo presahuje rámik, sa oreže) const ProductImageAdjust: React.FC<{ product: ProductItem; onChange: (patch: Partial) => void; }> = ({ product, onChange }) => { const scale = product.imageScale ?? 1; const offsetX = product.imageOffsetX || 0; const offsetY = product.imageOffsetY || 0; const isAdjusted = scale !== 1 || offsetX !== 0 || offsetY !== 0; const update = async (patch: Partial) => { // Pomer strán fotky potrebujeme pre presný výpočet pozadia; zistíme ho pri prvej úprave if (!product.imageAspect && product.imageUrl) { patch = { ...patch, imageAspect: await loadImageAspect(product.imageUrl) }; } onChange(patch); }; const slider = (label: string, value: number, display: string, min: number, max: number, step: number, key: keyof ProductItem) => (
{label} update({ [key]: Number(e.target.value) } as Partial)} className="w-full h-1 accent-red-600 cursor-pointer" /> {display}
); return (
Úprava fotky {isAdjusted && ( )}
{slider('Veľkosť', scale, `${Math.round(scale * 100)} %`, 0.5, 2.5, 0.05, 'imageScale')} {slider('Vodorovne', offsetX, `${offsetX} px`, -150, 150, 1, 'imageOffsetX')} {slider('Zvisle', offsetY, `${offsetY} px`, -120, 120, 1, 'imageOffsetY')}

Čo presahuje rámik, sa oreže. Pri polohe cenovky „vedľa obrázka“ sa dá produkt zasunúť pod cenovku.

); }; // Jednoduchý HTML editor: vlastné HTML nahradí modul vygenerovaný z formulára const CustomHtmlEditor: React.FC<{ module: NewsletterModule; updateData: (patch: Record) => void; }> = ({ module, updateData }) => { const enabled = !!module.data.useCustomHtml; const toggle = () => { if (enabled) { // Neupravené HTML nedržíme, aby sa pri ďalšom zapnutí predvyplnilo aktuálne z formulára const unchanged = (module.data.customHtml || '').trim() === renderGeneratedModuleHtml(module); updateData({ useCustomHtml: false, ...(unchanged ? { customHtml: undefined } : {}) }); } else { // Pri prvom zapnutí predvyplníme aktuálne vygenerované HTML updateData({ useCustomHtml: true, customHtml: module.data.customHtml || renderGeneratedModuleHtml(module) }); } }; const reloadFromForm = () => { if (confirm('Prepísať vlastné HTML aktuálnym HTML vygenerovaným z formulára?')) { updateData({ customHtml: renderGeneratedModuleHtml(module) }); } }; return (
{enabled ? ( <>