feat: zalamovanie riadkov v nadpisoch, cely nahlad cenovky v zozname sablon
- Enter alebo <br> v nadpise = novy riadok (clanky, recepty, letaky, banner, nazov produktu); polia nadpisov su viacriadkove - nahlad sablony v editore cenoviek uz nie je orezany zhora a zdola Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
090fd8d1ce
commit
a2d009bcb8
3 files changed
+35
-23
No files matched your search
@@ -722,7 +722,7 @@ export const BadgeEditorModal: React.FC<BadgeEditorModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="w-full h-12 flex items-center justify-center transform scale-75 origin-center overflow-hidden pointer-events-none"
|
className="w-full h-20 flex items-center justify-center overflow-hidden pointer-events-none [&>svg]:h-full! [&>svg]:w-auto! [&>svg]:max-w-full!"
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: renderCleanBadgeSvg(
|
__html: renderCleanBadgeSvg(
|
||||||
b,
|
b,
|
||||||
|
|||||||
@@ -526,11 +526,12 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-semibold text-gray-700 mb-1">Nadpis pod bannerom</label>
|
<label className="block text-xs font-semibold text-gray-700 mb-1">Nadpis pod bannerom</label>
|
||||||
<input
|
<textarea
|
||||||
type="text"
|
rows={2}
|
||||||
value={module.data.title || ''}
|
value={module.data.title || ''}
|
||||||
onChange={(e) => updateData({ title: e.target.value })}
|
onChange={(e) => updateData({ title: e.target.value })}
|
||||||
className="w-full text-sm border border-gray-300 rounded-lg p-2"
|
title="Enter = nový riadok (alebo <br>)"
|
||||||
|
className="w-full text-sm border border-gray-300 rounded-lg p-2 resize-y"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -2020,13 +2021,14 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
|||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Nadpis letáku</label>
|
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Nadpis letáku</label>
|
||||||
<input
|
<textarea
|
||||||
type="text"
|
rows={2}
|
||||||
value={module.data.item1?.title || ''}
|
value={module.data.item1?.title || ''}
|
||||||
onChange={(e) => updateData({
|
onChange={(e) => updateData({
|
||||||
item1: { ...module.data.item1, title: e.target.value }
|
item1: { ...module.data.item1, title: e.target.value }
|
||||||
})}
|
})}
|
||||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold"
|
title="Enter = nový riadok (alebo <br>)"
|
||||||
|
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold resize-y"
|
||||||
placeholder="Aktuálne letáky"
|
placeholder="Aktuálne letáky"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -2065,13 +2067,14 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
|||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Nadpis letáku</label>
|
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Nadpis letáku</label>
|
||||||
<input
|
<textarea
|
||||||
type="text"
|
rows={2}
|
||||||
value={module.data.item2?.title || ''}
|
value={module.data.item2?.title || ''}
|
||||||
onChange={(e) => updateData({
|
onChange={(e) => updateData({
|
||||||
item2: { ...module.data.item2, title: e.target.value }
|
item2: { ...module.data.item2, title: e.target.value }
|
||||||
})}
|
})}
|
||||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold"
|
title="Enter = nový riadok (alebo <br>)"
|
||||||
|
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold resize-y"
|
||||||
placeholder="Rozšírený leták"
|
placeholder="Rozšírený leták"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -2113,13 +2116,14 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
|||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Názov / Text článku</label>
|
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Názov / Text článku</label>
|
||||||
<input
|
<textarea
|
||||||
type="text"
|
rows={2}
|
||||||
value={module.data.item1?.title || ''}
|
value={module.data.item1?.title || ''}
|
||||||
onChange={(e) => updateData({
|
onChange={(e) => updateData({
|
||||||
item1: { ...module.data.item1, title: e.target.value }
|
item1: { ...module.data.item1, title: e.target.value }
|
||||||
})}
|
})}
|
||||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold"
|
title="Enter = nový riadok (alebo <br>)"
|
||||||
|
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold resize-y"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -2156,13 +2160,14 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
|||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Názov / Text článku</label>
|
<label className="text-[10px] text-gray-600 font-semibold block mb-0.5">Názov / Text článku</label>
|
||||||
<input
|
<textarea
|
||||||
type="text"
|
rows={2}
|
||||||
value={module.data.item2?.title || ''}
|
value={module.data.item2?.title || ''}
|
||||||
onChange={(e) => updateData({
|
onChange={(e) => updateData({
|
||||||
item2: { ...module.data.item2, title: e.target.value }
|
item2: { ...module.data.item2, title: e.target.value }
|
||||||
})}
|
})}
|
||||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold"
|
title="Enter = nový riadok (alebo <br>)"
|
||||||
|
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white font-bold resize-y"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -328,8 +328,8 @@ function renderModule(m: any, campaign: NewsletterCampaign): string {
|
|||||||
${m.data.title || m.data.description || m.data.buttonText ? `
|
${m.data.title || m.data.description || m.data.buttonText ? `
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 30px 20px; text-align: center;" class="mobile-padding">
|
<td style="padding: 30px 20px; text-align: center;" class="mobile-padding">
|
||||||
${m.data.title ? `<h1 class="force-text-dark" style="margin: 0 0 15px 0; font-size: 24px; color: #1a1a1a; font-weight: 700;">${escapeHtml(m.data.title)}</h1>` : ''}
|
${m.data.title ? `<h1 class="force-text-dark" style="margin: 0 0 15px 0; font-size: 24px; color: #1a1a1a; font-weight: 700;">${escapeWithBreaks(m.data.title)}</h1>` : ''}
|
||||||
${m.data.description ? `<p class="force-text-dark" style="margin: 0 0 25px 0; font-size: 15px; line-height: 1.5; color: #555555;">${escapeHtml(m.data.description)}</p>` : ''}
|
${m.data.description ? `<p class="force-text-dark" style="margin: 0 0 25px 0; font-size: 15px; line-height: 1.5; color: #555555;">${escapeWithBreaks(m.data.description)}</p>` : ''}
|
||||||
${m.data.buttonText ? `
|
${m.data.buttonText ? `
|
||||||
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: auto;" class="btn-table">
|
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: auto;" class="btn-table">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -473,7 +473,7 @@ function renderModule(m: any, campaign: NewsletterCampaign): string {
|
|||||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" height="100%" style="height: 100%;">
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" height="100%" style="height: 100%;">
|
||||||
<tr>
|
<tr>
|
||||||
<td valign="top" style="text-align: center; min-height: 44px; padding-bottom: 15px;">
|
<td valign="top" style="text-align: center; min-height: 44px; padding-bottom: 15px;">
|
||||||
<h3 class="force-text-white" style="margin: 0; font-size: 17px; color: ${it1.textColor || '#fefefe'}; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; line-height: 1.25;">${escapeHtml(it1.title)}</h3>
|
<h3 class="force-text-white" style="margin: 0; font-size: 17px; color: ${it1.textColor || '#fefefe'}; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; line-height: 1.25;">${escapeWithBreaks(it1.title)}</h3>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="1">
|
<tr height="1">
|
||||||
@@ -507,7 +507,7 @@ function renderModule(m: any, campaign: NewsletterCampaign): string {
|
|||||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" height="100%" style="height: 100%;">
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" height="100%" style="height: 100%;">
|
||||||
<tr>
|
<tr>
|
||||||
<td valign="top" style="text-align: center; min-height: 44px; padding-bottom: 15px;">
|
<td valign="top" style="text-align: center; min-height: 44px; padding-bottom: 15px;">
|
||||||
<h3 style="margin: 0; font-size: 17px; color: ${it2.textColor || '#29446f'}; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; line-height: 1.25;">${escapeHtml(it2.title)}</h3>
|
<h3 style="margin: 0; font-size: 17px; color: ${it2.textColor || '#29446f'}; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; line-height: 1.25;">${escapeWithBreaks(it2.title)}</h3>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr height="1">
|
<tr height="1">
|
||||||
@@ -560,7 +560,7 @@ function renderModule(m: any, campaign: NewsletterCampaign): string {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 15px 15px 25px 15px; text-align: center; height: 100%;" valign="middle">
|
<td style="padding: 15px 15px 25px 15px; text-align: center; height: 100%;" valign="middle">
|
||||||
<h3 class="force-text-white" style="margin: 0; font-size: 17px; color: #fefefe; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px; line-height: 1.25;">${escapeHtml(it1.title)}</h3>
|
<h3 class="force-text-white" style="margin: 0; font-size: 17px; color: #fefefe; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px; line-height: 1.25;">${escapeWithBreaks(it1.title)}</h3>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -589,7 +589,7 @@ function renderModule(m: any, campaign: NewsletterCampaign): string {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 15px 15px 25px 15px; text-align: center; height: 100%;" valign="middle">
|
<td style="padding: 15px 15px 25px 15px; text-align: center; height: 100%;" valign="middle">
|
||||||
<h3 class="force-text-white" style="margin: 0; font-size: 17px; color: #fefefe; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px; line-height: 1.25;">${escapeHtml(it2.title)}</h3>
|
<h3 class="force-text-white" style="margin: 0; font-size: 17px; color: #fefefe; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px; line-height: 1.25;">${escapeWithBreaks(it2.title)}</h3>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -717,7 +717,7 @@ function renderStackedImageRow(p: ProductItem, imgHtml: string, cellStyle: strin
|
|||||||
// názov 15px/700 · gramáž 15px/400 (v tom istom riadku) · jednotková cena 11px #555 · poznámka 10px #888
|
// názov 15px/700 · gramáž 15px/400 (v tom istom riadku) · jednotková cena 11px #555 · poznámka 10px #888
|
||||||
const PRODUCT_TEXT_FONT = "font-family: 'Poppins', Helvetica, Arial, sans-serif;";
|
const PRODUCT_TEXT_FONT = "font-family: 'Poppins', Helvetica, Arial, sans-serif;";
|
||||||
function renderProductTextBlock(p: { title?: string; quantity?: string; note?: string }, unitPrice?: string): string {
|
function renderProductTextBlock(p: { title?: string; quantity?: string; note?: string }, unitPrice?: string): string {
|
||||||
return `<h3 class="prod-name force-text-dark" style="margin: 0; ${PRODUCT_TEXT_FONT} font-size: 15px; line-height: 1.25; font-weight: 700; color: #1a1a1a;">${escapeHtml(p.title || '')}${p.quantity ? ` <span style="font-weight: 400;">${escapeHtml(p.quantity)}</span>` : ''}</h3>${
|
return `<h3 class="prod-name force-text-dark" style="margin: 0; ${PRODUCT_TEXT_FONT} font-size: 15px; line-height: 1.25; font-weight: 700; color: #1a1a1a;">${escapeWithBreaks(p.title || '')}${p.quantity ? ` <span style="font-weight: 400;">${escapeHtml(p.quantity)}</span>` : ''}</h3>${
|
||||||
unitPrice ? `
|
unitPrice ? `
|
||||||
<div class="prod-unit force-text-dark" style="margin-top: 3px; ${PRODUCT_TEXT_FONT} font-size: 11px; line-height: 1.3; color: #555555;">${escapeHtml(unitPrice)}</div>` : ''}${
|
<div class="prod-unit force-text-dark" style="margin-top: 3px; ${PRODUCT_TEXT_FONT} font-size: 11px; line-height: 1.3; color: #555555;">${escapeHtml(unitPrice)}</div>` : ''}${
|
||||||
p.note ? `
|
p.note ? `
|
||||||
@@ -1095,6 +1095,13 @@ function renderExactLoyaltyCard(p: any, validity: string, storesOffset: StoresOf
|
|||||||
</table>`;
|
</table>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Text nadpisu so zalomením riadkov: Enter (nový riadok) alebo <br> v texte = <br>, inak escapované
|
||||||
|
function escapeWithBreaks(str: string): string {
|
||||||
|
return escapeHtml(str)
|
||||||
|
.replace(/<br\s*\/?>/gi, '<br>')
|
||||||
|
.replace(/\r?\n/g, '<br>');
|
||||||
|
}
|
||||||
|
|
||||||
function escapeHtml(str: string): string {
|
function escapeHtml(str: string): string {
|
||||||
if (!str) return '';
|
if (!str) return '';
|
||||||
return String(str)
|
return String(str)
|
||||||
|
|||||||
Reference in new issue
Block a user