feat: zakladne cenovky (s vykricnikom a bez) v tagoch sablon pre import
Prazdna Zlava graficka v podkladoch = zakladna cenovka; stlpec Vykricnik rozlisi variant s vykricnikom. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
08fb233da0
commit
11392722e2
3 files changed
+23
-14
No files matched your search
@@ -5,7 +5,7 @@
|
||||
// v súradniciach viewBoxu. Klávesnica: šípky posun (Shift = viac), Delete zmaže vrstvu, Ctrl+Z / Ctrl+Y späť / znova,
|
||||
// Ctrl+S uloží.
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||
import { BadgeTemplate, BadgeLayer, BadgeImportTags, BadgeColor } from '@/types/newsletter';
|
||||
import { BadgeTemplate, BadgeLayer, BadgeImportTags, BadgeColor, BADGE_IMPORT_TYPES } from '@/types/newsletter';
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { renderCleanBadgeSvg, BadgeProductData, BadgeRow, badgeFromRow, badgeCode } from '@/lib/badgeUtils';
|
||||
import {
|
||||
@@ -149,7 +149,6 @@ function loadFont(layer: BadgeLayer) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Tagy šablóny pre import podkladov: ktorým riadkom tabuľky (Zľava grafická + Farba cenovky + Pôvod) patrí
|
||||
const BADGE_TYPES = ['SUPER CENA', 'SUPER VÝHODNÉ'];
|
||||
const ImportTagsEditor: React.FC<{ tags: BadgeImportTags; onChange: (tags: BadgeImportTags) => void }> = ({ tags, onChange }) => {
|
||||
const cls = 'w-full text-[11px] border border-gray-300 rounded-lg px-2 py-1.5 bg-white';
|
||||
return (
|
||||
@@ -158,10 +157,10 @@ const ImportTagsEditor: React.FC<{ tags: BadgeImportTags; onChange: (tags: Badge
|
||||
<span className="text-[10px] font-semibold text-gray-600">Typ</span>
|
||||
<select value={tags.type || ''} onChange={(e) => onChange({ ...tags, type: e.target.value || undefined })} className={cls}>
|
||||
<option value="">— nepoužiť pri importe —</option>
|
||||
{BADGE_TYPES.map((t) => (
|
||||
<option key={t} value={t}>{t}</option>
|
||||
{BADGE_IMPORT_TYPES.map((t) => (
|
||||
<option key={t.value} value={t.value}>{t.label}</option>
|
||||
))}
|
||||
{tags.type && !BADGE_TYPES.includes(tags.type) && <option value={tags.type}>{tags.type}</option>}
|
||||
{tags.type && !BADGE_IMPORT_TYPES.some((t) => t.value === tags.type) && <option value={tags.type}>{tags.type}</option>}
|
||||
</select>
|
||||
<span className="text-[10px] font-semibold text-gray-600">Farba</span>
|
||||
<select value={tags.color || ''} onChange={(e) => onChange({ ...tags, color: (e.target.value || undefined) as BadgeColor | undefined })} className={cls}>
|
||||
@@ -177,7 +176,7 @@ const ImportTagsEditor: React.FC<{ tags: BadgeImportTags; onChange: (tags: Badge
|
||||
</select>
|
||||
</div>
|
||||
<p className="text-[10px] text-gray-400 leading-snug">
|
||||
Pri importe ZIP-u sa šablóna priradí produktom so stĺpcami Zľava grafická, Farba cenovky a Pôvod podľa týchto tagov.
|
||||
Pri importe ZIP-u sa šablóna priradí produktom podľa stĺpcov Zľava grafická (prázdna = základná, s výkričníkom podľa stĺpca Výkričník), Farba cenovky a Pôvod.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Import ZIP-u s podkladmi z Databázy produktov: tabuľka podklady_*.xlsx (jeden riadok = jeden produkt)
|
||||
// a fotky v priečinkoch <EAN>/web/*.png.
|
||||
import JSZip from 'jszip';
|
||||
import { BadgeColor, BadgeTemplate, ProductItem } from '@/types/newsletter';
|
||||
import { BADGE_IMPORT_TYPES, BadgeColor, BadgeTemplate, ProductItem } from '@/types/newsletter';
|
||||
import { findBadgeByCode } from './badgeUtils';
|
||||
import { CARD_BG_BY_BADGE_COLOR } from './productCard';
|
||||
|
||||
@@ -43,14 +43,13 @@ function toBadgeColor(value: string): BadgeColor | undefined {
|
||||
// opačne nie – zahraničný produkt nesmie dostať cenovku so slovenskou vlajkou.
|
||||
function findBadgeByTags(
|
||||
badges: BadgeTemplate[],
|
||||
graphic: string,
|
||||
type: string,
|
||||
color: BadgeColor | undefined,
|
||||
origin: string
|
||||
): { badge: BadgeTemplate; match: 'exact' | 'origin' } | undefined {
|
||||
if (!graphic) return undefined;
|
||||
const sk = norm(origin) === 'sk' ? 'SK' : '';
|
||||
const candidates = badges.filter(
|
||||
(b) => b.importTags?.type && norm(b.importTags.type) === norm(graphic) && (!b.importTags.color || b.importTags.color === color)
|
||||
(b) => b.importTags?.type && norm(b.importTags.type) === norm(type) && (!b.importTags.color || b.importTags.color === color)
|
||||
);
|
||||
// presná farba má prednosť pred „hocijakou“
|
||||
const rank = (b: BadgeTemplate) => (b.importTags?.color ? 0 : 1);
|
||||
@@ -143,7 +142,8 @@ export async function readPodkladyZip(file: File, badges: BadgeTemplate[]): Prom
|
||||
color: col('Farba cenovky'),
|
||||
origin: col('Pôvod'),
|
||||
formats: col('Formát'),
|
||||
deposit: col('Zálohovanie')
|
||||
deposit: col('Zálohovanie'),
|
||||
exclaim: col('Výkričník')
|
||||
};
|
||||
if (c.ean < 0) throw new Error('Tabuľka nemá stĺpec EAN – nejde o podklady z Databázy produktov?');
|
||||
const get = (row: string[], i: number) => (i >= 0 ? String(row[i] ?? '').trim() : '');
|
||||
@@ -163,8 +163,10 @@ export async function readPodkladyZip(file: File, badges: BadgeTemplate[]): Prom
|
||||
const colorText = get(row, c.color);
|
||||
const color = toBadgeColor(colorText);
|
||||
const origin = get(row, c.origin);
|
||||
// prázdna „Zľava grafická“ = základná cenovka (s výkričníkom podľa stĺpca Výkričník)
|
||||
const type = graphic || (norm(get(row, c.exclaim)) === 'ano' ? 'ZÁKLADNÁ !' : 'ZÁKLADNÁ');
|
||||
const tries = [[graphic, colorText, origin], [graphic, colorText], [graphic]].map((parts) => parts.filter(Boolean).join(' | '));
|
||||
const byTags = findBadgeByTags(badges, graphic, color, origin);
|
||||
const byTags = findBadgeByTags(badges, type, color, origin);
|
||||
const byName = !byTags && graphic ? tries.map((t) => findBadgeByCode(badges, t)).find(Boolean) : undefined;
|
||||
|
||||
const formats = norm(get(row, c.formats));
|
||||
@@ -178,7 +180,7 @@ export async function readPodkladyZip(file: File, badges: BadgeTemplate[]): Prom
|
||||
cardPrice: toNumber(get(row, c.cardPrice)),
|
||||
unitPrice: formatUnitPrice(get(row, c.unitPrice)),
|
||||
discount: discount ? `${Math.round(discount)}%` : '',
|
||||
badgeLabel: tries[0],
|
||||
badgeLabel: [BADGE_IMPORT_TYPES.find((t) => t.value === type)?.label || type, colorText, origin].filter(Boolean).join(' | '),
|
||||
badge: byTags?.badge || byName,
|
||||
badgeMatch: byTags ? byTags.match : byName ? 'exact' : undefined,
|
||||
color,
|
||||
|
||||
@@ -243,10 +243,18 @@ export interface BadgeTemplate {
|
||||
importTags?: BadgeImportTags; // podľa čoho sa šablóna vyberie pri importe podkladov (ZIP)
|
||||
}
|
||||
|
||||
// Druhy cenoviek v podkladoch: „Zľava grafická“, a keď je prázdna, základná cenovka s výkričníkom alebo bez
|
||||
export const BADGE_IMPORT_TYPES = [
|
||||
{ value: 'SUPER CENA', label: 'SUPER CENA' },
|
||||
{ value: 'SUPER VÝHODNÉ', label: 'SUPER VÝHODNÉ' },
|
||||
{ value: 'ZÁKLADNÁ !', label: 'Základná s výkričníkom' },
|
||||
{ value: 'ZÁKLADNÁ', label: 'Základná (bez nápisu)' }
|
||||
];
|
||||
|
||||
// Tagy šablóny cenovky pre import podkladov – zodpovedajú stĺpcom tabuľky z Databázy produktov
|
||||
export type BadgeColor = 'cervena' | 'oranzova' | 'zelena';
|
||||
export interface BadgeImportTags {
|
||||
type?: string; // „Zľava grafická“, napr. SUPER CENA, SUPER VÝHODNÉ
|
||||
type?: string; // druh cenovky – jeden z BADGE_IMPORT_TYPES (SUPER CENA, SUPER VÝHODNÉ, ZÁKLADNÁ, ZÁKLADNÁ !)
|
||||
color?: BadgeColor; // „Farba cenovky“
|
||||
origin?: 'SK' | ''; // „Pôvod“: SK alebo bez pôvodu
|
||||
}
|
||||
Reference in new issue
Block a user