fix: merge addon pills into one card, wire it to editable Settings
Two related fixes reported directly against live screenshots:
1. addonRow rendered each addon ("Напитки", "Чайная станция", ...) as
its own tall bordered pill sitting side by side -- disjointed, and
unlike the single-card "Полезные дополнения" treatment in the
referenced design. Now draws one card with a heading
("Рекомендуем добавить") containing all the icon+label items,
matching how checklistCard already works.
2. The addon list and the "Всё под контролем" checklist were hardcoded
constants in the canvas module, completely bypassing the app's
existing editable Client Offer Settings (Настройки → Предложение →
"Дополнительно к заказу", textarea-backed extraServices/controlLines
the user can already edit for the old templates). preparedSnapshot
now attaches the resolved controlLines/extraServices/titles onto
every snapshot; the 8 signature templates read them via a local
shadowing const (falls back to the previous defaults when nothing
is configured), so editing that Settings textarea now actually
changes what shows up in these templates too, on all 8 of them from
one change since addonRow/checklistCard are shared helpers.
Verified locally: default list (6 items) lays out cleanly in one card
with 2-line wrapping where needed; a snapshot with custom
controlLines/extraServices renders those exact custom strings instead
of the defaults, confirming the wiring actually works end to end and
isn't just falling back silently.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
44bf5e9af1
commit
14e3d6b45b
@ -1088,6 +1088,7 @@ window.SUN_LEGACY_CATALOG_V175=[{"id":"1","name":"Фуршетный бокс
|
||||
}
|
||||
copy.foodGrams=0;copy.drinkMl=0;copy.foodPieces=0;
|
||||
for(const item of copy.items){const measure=parseMeasure(item.weight);if(measure){if(measure.kind==='drink'||Number(item.categoryId)===3)copy.drinkMl+=measure.value*num(item.qty);else if([0,5].includes(Number(item.categoryId)))copy.foodGrams+=measure.value*num(item.qty);}if([0,5].includes(Number(item.categoryId))&&num(item.pieces)>0)copy.foodPieces+=num(item.pieces)*num(item.qty)}
|
||||
try{const cfg=offerSettingsForSnapshot(copy);copy.controlLines=Array.isArray(cfg.controlLines)&&cfg.controlLines.length?cfg.controlLines:DELIVERY_CONTROL;copy.extraServices=Array.isArray(cfg.extraServices)&&cfg.extraServices.length?cfg.extraServices:EXTRA_SERVICES.map(x=>x[0]);copy.controlTitle=cfg.texts?.controlTitle||'';copy.extrasTitle=cfg.texts?.extrasTitle||'';}catch(_){}
|
||||
return copy;
|
||||
}
|
||||
async function preparedPdfSnapshot(prepared){
|
||||
|
||||
@ -104,15 +104,18 @@
|
||||
}
|
||||
}
|
||||
function checklistCard(ctx,p,x,y,w,h,title,lines,{dark=true,fonts}={}){const lf=fonts?.label||'Arial';roundRect(ctx,x,y,w,h,16,dark?'rgba(255,255,255,.04)':p.paper,dark?'rgba(255,255,255,.14)':p.line);text(ctx,title,x+18,y+16,w-36,18,{font:`700 13px ${lf}`,color:p.accent,maxLines:1});const cols=2,rowH=22,colW=(w-36)/cols;lines.forEach((t,i)=>{const col=i%cols,row=Math.floor(i/cols),xx=x+18+col*colW,yy=y+46+row*rowH;roundRect(ctx,xx,yy+2,14,14,7,p.accent,null);text(ctx,'✓',xx+7,yy+3,10,12,{font:`700 9px ${lf}`,color:p.deep,align:'center',maxLines:1});text(ctx,t,xx+20,yy,colW-24,14,{font:`500 10px ${lf}`,color:dark?'#eef':p.ink,maxLines:1})})}
|
||||
function addonRow(ctx,p,x,y,w,h,items,{dark=true,fonts}={}){const lf=fonts?.label||'Arial';const gap=9,cw=(w-gap*(items.length-1))/items.length;items.forEach((t,i)=>{const xx=x+i*(cw+gap);roundRect(ctx,xx,y,cw,h,13,dark?'rgba(255,255,255,.04)':p.paper,dark?'rgba(255,255,255,.14)':p.line);roundRect(ctx,xx+cw/2-11,y+12,22,22,11,p.accent,null);text(ctx,'+',xx+cw/2,y+14,22,18,{font:`700 14px ${lf}`,color:p.deep,align:'center',maxLines:1});text(ctx,t,xx+cw/2,y+44,cw-16,14,{font:`600 10px ${lf}`,color:dark?'#eef':p.ink,align:'center',maxLines:2})})}
|
||||
function addonRow(ctx,p,x,y,w,h,items,{dark=true,fonts}={}){const lf=fonts?.label||'Arial';roundRect(ctx,x,y,w,h,16,dark?'rgba(255,255,255,.04)':p.paper,dark?'rgba(255,255,255,.14)':p.line);text(ctx,'Рекомендуем добавить',x+18,y+16,w-36,16,{font:`700 12px ${lf}`,color:p.accent,maxLines:1});const innerX=x+18,innerW=w-36,innerY=y+48,gap=8,cw=(innerW-gap*(items.length-1))/items.length;items.forEach((t,i)=>{const xx=innerX+i*(cw+gap);roundRect(ctx,xx+cw/2-11,innerY,22,22,11,p.accent,null);text(ctx,'+',xx+cw/2,innerY+2,22,18,{font:`700 13px ${lf}`,color:p.deep,align:'center',maxLines:1});text(ctx,t,xx+cw/2,innerY+32,cw,14,{font:`600 10px ${lf}`,color:dark?'#eef':p.ink,align:'center',maxLines:2})})}
|
||||
|
||||
const CHECK_LINES=['Доставка в фирменных боксах','Свежие продукты каждый день','Аккуратная подача и упаковка','Готовность к сервировке'];
|
||||
const ADDON_LINES=['Напитки','Чайная станция','Официант','Текстиль'];
|
||||
const CHECK_LINES_DEFAULT=['Доставка в фирменных боксах','Свежие продукты каждый день','Аккуратная подача и упаковка','Готовность к сервировке'];
|
||||
const ADDON_LINES_DEFAULT=['Напитки','Чайная станция','Официант','Текстиль'];
|
||||
|
||||
async function renderCover(s,id){
|
||||
await ensureFontsReady(id);
|
||||
const p=PALETTES[id]||PALETTES['cream-elegance'],f=fontsFor(id),canvas=document.createElement('canvas');canvas.width=Math.round(W*SCALE);canvas.height=Math.round(H*SCALE);const ctx=canvas.getContext('2d',{alpha:false});ctx.setTransform(SCALE,0,0,SCALE,0,0);ctx.fillStyle=p.bg;ctx.fillRect(0,0,W,H);
|
||||
const logo=await loadImage(s.logo||''),heroSrc=(s.items||[]).find(x=>safeImage(x.photoData||x.photo))?.photoData||(s.finalGallery||[]).find(safeImage)||'',hero=await loadImage(heroSrc),title=eventTitle(s),event=String(s.event||'Персональное предложение').trim();
|
||||
// Pull the user's editable "control"/"extras" lists from Settings when present (set in preparedSnapshot), falling back to sensible defaults otherwise.
|
||||
const CHECK_LINES=Array.isArray(s.controlLines)&&s.controlLines.length?s.controlLines:CHECK_LINES_DEFAULT;
|
||||
const ADDON_LINES=Array.isArray(s.extraServices)&&s.extraServices.length?s.extraServices:ADDON_LINES_DEFAULT;
|
||||
|
||||
if(id==='cream-elegance'){
|
||||
logoOrBrand(ctx,logo,p,{fonts:f},s.brandName);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user