feat: vlastna PNG cenovka pre vynimocny produkt (uloha 16)
- pri produkte aj vernostnom produkte sa da nahrat cela cenovka ako PNG, ktora prekryje generovanu sablonu - tlacidlo Odstranit PNG vrati generovanu cenovku (sablona ostava zachovana) - hromadne pouzitie cenovky (sekcia / cely newsletter) produkty s PNG neprepisuje Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
92dc2081d0
commit
22a9a51d00
3 files changed
+76
-27
No files matched your search
@@ -26,6 +26,29 @@ interface ConfigPanelProps {
|
||||
availableBadges?: BadgeTemplate[];
|
||||
}
|
||||
|
||||
// Nahratie celej cenovky ako PNG pre výnimočný produkt (prekryje šablónu)
|
||||
const CustomBadgePngInput: React.FC<{ value?: string; onChange: (url: string) => void }> = ({ value, onChange }) => (
|
||||
<div className="p-2.5 rounded-xl border border-dashed border-amber-300 bg-amber-50/60 space-y-1.5">
|
||||
<ImageUploadInput
|
||||
label="Vlastná PNG cenovka (výnimka)"
|
||||
value={value || ''}
|
||||
onChange={onChange}
|
||||
placeholder="Nahrajte celú cenovku ako PNG"
|
||||
/>
|
||||
{value ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onChange('')}
|
||||
className="w-full py-1.5 text-[11px] font-bold text-amber-800 bg-white hover:bg-amber-100 border border-amber-300 rounded-lg transition-colors"
|
||||
>
|
||||
Odstrániť PNG a vrátiť generovanú cenovku
|
||||
</button>
|
||||
) : (
|
||||
<p className="text-[10px] text-amber-800/80">Nahraná PNG nahradí generovanú cenovku len pri tomto produkte.</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
module,
|
||||
onUpdateModule,
|
||||
@@ -731,6 +754,16 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Vlastná PNG cenovka (výnimka): prekryje šablónu, po odstránení sa vráti generovaná */}
|
||||
<CustomBadgePngInput
|
||||
value={p.customBadgePngUrl}
|
||||
onChange={(url) => {
|
||||
const products = [...module.data.products];
|
||||
products[pIdx].customBadgePngUrl = url || undefined;
|
||||
updateData({ products });
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Tlačidlá aplikácie cenovky */}
|
||||
{p.badgeCustomTemplate && (
|
||||
<div className="space-y-1.5">
|
||||
@@ -738,7 +771,8 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
type="button"
|
||||
onClick={() => {
|
||||
if (confirm(`Naozaj chcete aplikovať šablónu "${p.badgeCustomTemplate?.name}" na všetky produkty v tejto sekcii?`)) {
|
||||
const products = (module.data.products || []).map((prod: ProductItem) => ({
|
||||
// Produkty s vlastnou PNG cenovkou (výnimky) sa neprepisujú
|
||||
const products = (module.data.products || []).map((prod: ProductItem) => prod.customBadgePngUrl ? prod : ({
|
||||
...prod,
|
||||
badgeCustomTemplate: p.badgeCustomTemplate,
|
||||
badgeId: p.badgeCustomTemplate?.id,
|
||||
@@ -746,8 +780,7 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
badgeAlign: p.badgeAlign || p.badgeCustomTemplate?.align || 'center',
|
||||
badgePaddingTop: p.badgePaddingTop ?? p.badgeCustomTemplate?.paddingTop ?? 4,
|
||||
badgePaddingBottom: p.badgePaddingBottom ?? p.badgeCustomTemplate?.paddingBottom ?? 4,
|
||||
badgeLayout: p.badgeLayout || 'below',
|
||||
customBadgePngUrl: undefined
|
||||
badgeLayout: p.badgeLayout || 'below'
|
||||
}));
|
||||
updateData({ products });
|
||||
}
|
||||
@@ -1347,6 +1380,7 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
if (val === 'default_loyalty') {
|
||||
products[pIdx].badgeCustomTemplate = undefined;
|
||||
products[pIdx].badgeId = undefined;
|
||||
products[pIdx].customBadgePngUrl = undefined;
|
||||
} else {
|
||||
const found = (availableBadges || []).find((b) => b.id === val);
|
||||
if (found) {
|
||||
@@ -1356,6 +1390,7 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
products[pIdx].badgeAlign = found.align ?? products[pIdx].badgeAlign ?? 'center';
|
||||
products[pIdx].badgePaddingTop = found.paddingTop ?? products[pIdx].badgePaddingTop ?? 4;
|
||||
products[pIdx].badgePaddingBottom = found.paddingBottom ?? products[pIdx].badgePaddingBottom ?? 4;
|
||||
products[pIdx].customBadgePngUrl = undefined;
|
||||
}
|
||||
}
|
||||
updateData({ products });
|
||||
@@ -1371,6 +1406,16 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Vlastná PNG cenovka (výnimka): prekryje šablónu, po odstránení sa vráti generovaná */}
|
||||
<CustomBadgePngInput
|
||||
value={p.customBadgePngUrl}
|
||||
onChange={(url) => {
|
||||
const products = [...module.data.products];
|
||||
products[pIdx].customBadgePngUrl = url || undefined;
|
||||
updateData({ products });
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Tlačidlá aplikácie cenovky */}
|
||||
{p.badgeCustomTemplate && (
|
||||
<div className="space-y-1.5">
|
||||
@@ -1378,7 +1423,8 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
type="button"
|
||||
onClick={() => {
|
||||
if (confirm(`Naozaj chcete aplikovať šablónu "${p.badgeCustomTemplate?.name}" na všetky vernostné produkty?`)) {
|
||||
const products = (module.data.products || []).map((prod: any) => ({
|
||||
// Produkty s vlastnou PNG cenovkou (výnimky) sa neprepisujú
|
||||
const products = (module.data.products || []).map((prod: any) => prod.customBadgePngUrl ? prod : ({
|
||||
...prod,
|
||||
badgeCustomTemplate: p.badgeCustomTemplate,
|
||||
badgeId: p.badgeCustomTemplate?.id,
|
||||
@@ -1458,7 +1504,7 @@ export const ConfigPanel: React.FC<ConfigPanelProps> = ({
|
||||
)}
|
||||
|
||||
{/* Rýchle ovládanie veľkosti (Width), zarovnania a paddingu pre vernostnú cenovku */}
|
||||
{p.badgeCustomTemplate && (
|
||||
{(p.badgeCustomTemplate || p.customBadgePngUrl) && (
|
||||
<div className="bg-gray-50 p-2.5 rounded-xl border border-gray-200 space-y-2">
|
||||
{/* Šírka */}
|
||||
<div>
|
||||
|
||||
Reference in new issue
Block a user