Feat: adjustable superscript index, loyalty badges, centered unit price, global badge apply, brevo url fix

This commit is contained in:
Jakub_Hostacny committed 2026-09-24 12:33:39 +02:00
1 parent 245e3f8471
commit 4e4e5e5af3
10 files changed
+539 -290

No files matched your search

+99 -17
View File
@@ -226,20 +226,11 @@ export const BadgeEditorModal: React.FC<BadgeEditorModalProps> = ({
}
} catch (e) {}
// Doplnenie predpripravených dizajnových šablón (DEFAULT_BADGE_TEMPLATES)
const allBadges = [...loaded];
const existingIds = new Set(allBadges.map((b) => b.id));
for (const preset of DEFAULT_BADGE_TEMPLATES) {
if (!existingIds.has(preset.id)) {
allBadges.push(preset);
}
}
setBadges(allBadges);
if (!activeBadge && allBadges.length > 0) {
setActiveBadge(allBadges[0]);
if (allBadges[0].layersConfig?.[0]) {
setSelectedLayerId(allBadges[0].layersConfig[0].id);
setBadges(loaded);
if (!activeBadge && loaded.length > 0) {
setActiveBadge(loaded[0]);
if (loaded[0].layersConfig?.[0]) {
setSelectedLayerId(loaded[0].layersConfig[0].id);
}
}
};
@@ -452,15 +443,28 @@ export const BadgeEditorModal: React.FC<BadgeEditorModalProps> = ({
// Vykreslenie vrstvy v React náhľade s centami ako horný index (sup) a BEZ znaku €
const renderLayerVisualContent = (layer: BadgeLayer) => {
const raw = layer.text || '';
const baseFontSize = layer.fontSize || 16;
const subFontSize = layer.indexFontSize ? `${layer.indexFontSize}px` : `${Math.max(10, Math.round(baseFontSize * 0.55))}px`;
const subY = layer.indexOffsetY !== undefined ? `${layer.indexOffsetY}px` : '-10px';
const subX = layer.indexOffsetX !== undefined ? `${layer.indexOffsetX}px` : '2px';
if (raw.includes('{cena}')) {
const parts = raw.split('{cena}');
return (
<span>
{parts[0]}
<span>{currentPriceMain}</span>
<sup style={{ fontSize: '0.55em', verticalAlign: 'top', lineHeight: 1.1, marginLeft: '1px' }}>
<span
style={{
display: 'inline-block',
fontSize: subFontSize,
transform: `translate(${subX}, ${subY})`,
fontWeight: layer.fontWeight || '700',
lineHeight: 1
}}
>
{currentPriceSub}
</sup>
</span>
{parts[1]}
</span>
);
@@ -471,7 +475,17 @@ export const BadgeEditorModal: React.FC<BadgeEditorModalProps> = ({
return (
<span>
{parts[0]}
<sup style={{ fontSize: '0.55em', verticalAlign: 'top', lineHeight: 1.1 }}>{currentPriceSub}</sup>
<span
style={{
display: 'inline-block',
fontSize: subFontSize,
transform: `translate(${subX}, ${subY})`,
fontWeight: layer.fontWeight || '700',
lineHeight: 1
}}
>
{currentPriceSub}
</span>
{parts[1]}
</span>
);
@@ -1101,6 +1115,74 @@ export const BadgeEditorModal: React.FC<BadgeEditorModalProps> = ({
</div>
</div>
{/* Nastavenie veľkosti a pozície horného indexu (centov) */}
{(activeLayer.text?.includes('{cena}') || activeLayer.text?.includes('{centy}')) && (
<div className="pt-2.5 pb-1 border-t border-blue-200/80 bg-blue-50/70 p-3 rounded-xl border border-blue-100 space-y-2.5">
<div className="flex items-center justify-between">
<span className="text-[11px] font-bold text-blue-900">
Nastavenie horného indexu (Centov)
</span>
<span className="text-[10px] text-blue-700 bg-blue-100 px-1.5 py-0.5 rounded font-mono font-bold">
{activeLayer.indexFontSize ?? Math.max(10, Math.round((activeLayer.fontSize || 16) * 0.55))}px
</span>
</div>
{/* Veľkosť indexu */}
<div>
<div className="flex justify-between items-center text-[10px] text-gray-600 mb-0.5">
<span>Veľkosť písma indexu</span>
<span className="font-bold text-gray-800">
{activeLayer.indexFontSize ?? Math.max(10, Math.round((activeLayer.fontSize || 16) * 0.55))} px
</span>
</div>
<input
type="range"
min="8"
max="40"
value={activeLayer.indexFontSize ?? Math.max(10, Math.round((activeLayer.fontSize || 16) * 0.55))}
onChange={(e) => updateActiveLayer({ indexFontSize: Number(e.target.value) })}
className="w-full accent-blue-600"
/>
</div>
{/* Vertikálny posun (Hore / Dole) */}
<div>
<div className="flex justify-between items-center text-[10px] text-gray-600 mb-0.5">
<span>Vertikálna pozícia (Posun Hore / Dole)</span>
<span className="font-bold text-gray-800">
{activeLayer.indexOffsetY ?? -10} px
</span>
</div>
<input
type="range"
min="-30"
max="20"
value={activeLayer.indexOffsetY ?? -10}
onChange={(e) => updateActiveLayer({ indexOffsetY: Number(e.target.value) })}
className="w-full accent-blue-600"
/>
</div>
{/* Horizontálna medzera (Vľavo / Vpravo) */}
<div>
<div className="flex justify-between items-center text-[10px] text-gray-600 mb-0.5">
<span>Horizontálna medzera (Vľavo / Vpravo)</span>
<span className="font-bold text-gray-800">
{activeLayer.indexOffsetX ?? 2} px
</span>
</div>
<input
type="range"
min="-10"
max="25"
value={activeLayer.indexOffsetX ?? 2}
onChange={(e) => updateActiveLayer({ indexOffsetX: Number(e.target.value) })}
className="w-full accent-blue-600"
/>
</div>
</div>
)}
<div className="pt-1 flex justify-between items-center">
<button
onClick={() => removeLayer(activeLayer.id)}