feat: tri styly textu produktu podla vzoru coop_nws_009
- nazov 15px/700, gramaz 15px/400 v tom istom riadku, jednotkova cena 11px #555 pod nazvom, volitelna poznamka 10px #888 (napr. Ilustracne foto) - text zarovnany vlavo s odsadenim 14px; jednotkova cena sa presunula spod cenovky - nove polia Gramaz / mnozstvo a Poznamka pri produkte aj vernostnom produkte Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ffba0e0842
commit
090fd8d1ce
3 files changed
+87
-16
No files matched your search
@@ -805,6 +805,37 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<label className="text-[10px] text-gray-500 font-semibold block mb-0.5">Gramáž / množstvo</label>
|
||||
<input
|
||||
type="text"
|
||||
value={p.quantity || ''}
|
||||
onChange={(e) => {
|
||||
const products = [...module.data.products];
|
||||
products[pIdx].quantity = e.target.value;
|
||||
updateData({ products });
|
||||
}}
|
||||
placeholder="napr. 35 g"
|
||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[10px] text-gray-500 font-semibold block mb-0.5">Poznámka (voliteľné)</label>
|
||||
<input
|
||||
type="text"
|
||||
value={p.note || ''}
|
||||
onChange={(e) => {
|
||||
const products = [...module.data.products];
|
||||
products[pIdx].note = e.target.value;
|
||||
updateData({ products });
|
||||
}}
|
||||
placeholder="napr. Ilustračné foto"
|
||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ImageUploadInput
|
||||
label="Obrázok produktu"
|
||||
value={p.imageUrl || ''}
|
||||
@@ -892,7 +923,7 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[10px] text-gray-500">Merná cena</label>
|
||||
<label className="text-[10px] text-gray-500">Jednotková cena</label>
|
||||
<input
|
||||
type="text"
|
||||
value={p.unitPrice}
|
||||
@@ -901,6 +932,7 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
products[pIdx].unitPrice = e.target.value;
|
||||
updateData({ products });
|
||||
}}
|
||||
placeholder="jednotková cena 9,43 EUR/kg"
|
||||
className="w-full text-xs border border-gray-300 rounded p-1 bg-white text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -1457,6 +1489,37 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<label className="text-[10px] text-gray-500 font-semibold block mb-0.5">Gramáž / množstvo</label>
|
||||
<input
|
||||
type="text"
|
||||
value={p.quantity || ''}
|
||||
onChange={(e) => {
|
||||
const products = [...module.data.products];
|
||||
products[pIdx].quantity = e.target.value;
|
||||
updateData({ products });
|
||||
}}
|
||||
placeholder="napr. 35 g"
|
||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[10px] text-gray-500 font-semibold block mb-0.5">Poznámka (voliteľné)</label>
|
||||
<input
|
||||
type="text"
|
||||
value={p.note || ''}
|
||||
onChange={(e) => {
|
||||
const products = [...module.data.products];
|
||||
products[pIdx].note = e.target.value;
|
||||
updateData({ products });
|
||||
}}
|
||||
placeholder="napr. Ilustračné foto"
|
||||
className="w-full text-xs border border-gray-300 rounded p-1.5 bg-white"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ImageUploadInput
|
||||
label="Obrázok produktu"
|
||||
value={p.imageUrl || ''}
|
||||
|
||||
+19
-13
@@ -713,6 +713,17 @@ function renderStackedImageRow(p: ProductItem, imgHtml: string, cellStyle: strin
|
||||
<!--<![endif]-->`;
|
||||
}
|
||||
|
||||
// Popis produktu podľa vzoru coop_nws_009: 3 štýly textu (+ voliteľná poznámka)
|
||||
// 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;";
|
||||
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>${
|
||||
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>` : ''}${
|
||||
p.note ? `
|
||||
<div class="prod-unit force-text-dark" style="margin-top: 2px; ${PRODUCT_TEXT_FONT} font-size: 10px; line-height: 1.3; color: #888888;">${escapeHtml(p.note)}</div>` : ''}`;
|
||||
}
|
||||
|
||||
// Štítky dostupnosti v predajniach (Potraviny / Supermarket / Tempo); prázdne, ak nie je zvolená žiadna
|
||||
function renderStoresHtml(p: { stores?: Partial<ProductItem["stores"]> }): string {
|
||||
const tag = (color: string, file: string, alt: string) =>
|
||||
@@ -866,7 +877,6 @@ function renderExactProductCard(
|
||||
</td>`;
|
||||
const badgeCell = `<td width="42%" style="padding: 8px 8px 8px 4px; text-align: center;" valign="middle">
|
||||
${renderBadgeContent(bWidth, bAlign, padTop, padBottom, marginStyle)}
|
||||
${p.unitPrice ? `<div style="font-size: 8px; color: #666666; font-weight: 500; font-family: Arial, sans-serif; text-align: center; margin-top: 4px;">${escapeHtml(p.unitPrice)}</div>` : ''}
|
||||
</td>`;
|
||||
if (!hasImageAdjust(p)) {
|
||||
return `<tr>${imgCell}${badgeCell}</tr>`;
|
||||
@@ -890,8 +900,8 @@ function renderExactProductCard(
|
||||
<!--<![endif]-->`;
|
||||
})()}
|
||||
<tr>
|
||||
<td colspan="2" height="54" style="padding: 0 8px 10px 8px; text-align: center; height: 54px; min-height: 54px;" valign="top">
|
||||
<h3 class="force-text-dark" style="margin: 0; font-size: 15px; color: #1a1a1a; font-weight: 600; line-height: 1.25;">${escapeHtml(p.title)}</h3>
|
||||
<td colspan="2" class="prod-pad" height="54" style="padding: 2px 14px 12px 14px; text-align: left; height: 54px; min-height: 54px;" valign="top">
|
||||
${renderProductTextBlock(p, p.unitPrice)}
|
||||
</td>
|
||||
</tr>
|
||||
</table>`;
|
||||
@@ -918,8 +928,8 @@ function renderExactProductCard(
|
||||
pickAlt(p.imageAlt, p.title, sectionTitle, 'Produkt')
|
||||
)}
|
||||
<tr>
|
||||
<td height="54" style="padding: 0 8px 10px 8px; text-align: center; height: 54px; min-height: 54px;" valign="top">
|
||||
<h3 class="force-text-dark" style="margin: 0; font-size: 15px; color: #1a1a1a; font-weight: 600; line-height: 1.25;">${escapeHtml(p.title)}</h3>
|
||||
<td class="prod-pad" height="54" style="padding: 2px 14px 12px 14px; text-align: left; height: 54px; min-height: 54px;" valign="top">
|
||||
${renderProductTextBlock(p, p.unitPrice)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="1">
|
||||
@@ -940,9 +950,7 @@ function renderExactProductCard(
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="1">
|
||||
<td align="center" valign="bottom" style="padding: 2px 8px 12px 8px; text-align: center; height: 1px;">
|
||||
${p.unitPrice ? `<div style="font-size: 9px; color: #666666; font-weight: 500; font-family: Arial, sans-serif; text-align: center;">${escapeHtml(p.unitPrice)}</div>` : '<div style="font-size: 9px; line-height: 9px; height: 9px;"> </div>'}
|
||||
</td>
|
||||
<td style="padding: 0 0 12px 0; height: 1px; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>`;
|
||||
}
|
||||
@@ -979,8 +987,8 @@ function renderExactLoyaltyCard(p: any, validity: string, storesOffset: StoresOf
|
||||
</td>
|
||||
</tr>`}
|
||||
<tr>
|
||||
<td style="padding: 0 8px 10px 8px; text-align: center; height: 100%; min-height: 44px;" valign="top">
|
||||
<h3 class="force-text-dark" style="margin: 0; font-size: 15px; color: #1a1a1a; font-weight: 600; line-height: 1.25;">${escapeHtml(p.title)}</h3>
|
||||
<td class="prod-pad" style="padding: 2px 14px 12px 14px; text-align: left; height: 100%; min-height: 44px;" valign="top">
|
||||
${renderProductTextBlock(p, p.badgeCustomTemplate || p.customBadgePngUrl ? p.cardUnitPrice || p.unitPrice : '')}
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="1">
|
||||
@@ -1082,9 +1090,7 @@ function renderExactLoyaltyCard(p: any, validity: string, storesOffset: StoresOf
|
||||
</tr>
|
||||
${p.badgeCustomTemplate || p.customBadgePngUrl ? `
|
||||
<tr height="1">
|
||||
<td align="center" valign="bottom" style="padding: 2px 8px 12px 8px; text-align: center; height: 1px;">
|
||||
${p.cardUnitPrice || p.unitPrice ? `<div style="font-size: 9px; color: #666666; font-weight: 500; font-family: Arial, sans-serif; text-align: center;">${escapeHtml(p.cardUnitPrice || p.unitPrice)}</div>` : '<div style="font-size: 9px; line-height: 9px; height: 9px;"> </div>'}
|
||||
</td>
|
||||
<td style="padding: 0 0 12px 0; height: 1px; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>` : ''}
|
||||
</table>`;
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@ export interface StoreTag {
|
||||
|
||||
export interface ProductItem {
|
||||
id: string;
|
||||
title: string;
|
||||
title: string; // názov (tučne), napr. "Deli tyčinka 3 druhy"
|
||||
quantity?: string; // gramáž / množstvo (normálne písmo za názvom), napr. "35 g"
|
||||
note?: string; // poznámka pod jednotkovou cenou, napr. "Ilustračné foto"
|
||||
imageUrl: string;
|
||||
priceMain: string; // napr. "1" alebo "0"
|
||||
priceSub: string; // napr. "99" alebo "89"
|
||||
unitPrice: string; // napr. "1kg = 4,91 €"
|
||||
unitPrice: string; // jednotková cena pod názvom, napr. "jednotková cena 9,43 EUR/kg"
|
||||
discountText: string; // napr. "-23%" alebo "23%"
|
||||
cardPriceMain?: string; // cena s kartou (vernostná), celé eurá
|
||||
cardPriceSub?: string; // cena s kartou, centy
|
||||
|
||||
Reference in new issue
Block a user