| 1 |
( function () { |
| 2 |
var el = wp.element.createElement; |
| 3 |
var Fragment = wp.element.Fragment; |
| 4 |
var useState = wp.element.useState; |
| 5 |
var __ = wp.i18n.__; |
| 6 |
var registerBlockType = wp.blocks.registerBlockType; |
| 7 |
var InspectorControls = wp.blockEditor.InspectorControls; |
| 8 |
var RichText = wp.blockEditor.RichText; |
| 9 |
var useBlockProps = wp.blockEditor.useBlockProps; |
| 10 |
var MediaUpload = wp.blockEditor.MediaUpload; |
| 11 |
var MediaUploadCheck = wp.blockEditor.MediaUploadCheck; |
| 12 |
var PanelBody = wp.components.PanelBody; |
| 13 |
var Button = wp.components.Button; |
| 14 |
var ToggleControl = wp.components.ToggleControl; |
| 15 |
var RangeControl = wp.components.RangeControl; |
| 16 |
var SelectControl = wp.components.SelectControl; |
| 17 |
var TextControl = wp.components.TextControl; |
| 18 |
var TextareaControl = wp.components.TextareaControl; |
| 19 |
var ColorPicker = wp.components.ColorPicker; |
| 20 |
var Popover = wp.components.Popover; |
| 21 |
|
| 22 |
function getTypographyControl() { return (window.bkbgTypographyControl || function () { return null; }); } |
| 23 |
function getTypoCssVars() { return (window.bkbgTypoCssVars || function () { return {}; }); } |
| 24 |
function _tv(typo, prefix) { var fn = getTypoCssVars(); return fn(typo || {}, prefix); } |
| 25 |
|
| 26 |
function makeId() { return 'cs' + Math.random().toString(36).substr(2,8); } |
| 27 |
|
| 28 |
var DEFAULT_METRICS = [ |
| 29 |
{ id: makeId(), value: '94%', prefix: '', suffix: '%', label: 'Reporting time reduced', description: 'From weekly to daily reports', color: '#6c3fb5' }, |
| 30 |
{ id: makeId(), value: '3.2×', prefix: '', suffix: '×', label: 'Productivity increase', description: 'Across all departments', color: '#059669' }, |
| 31 |
{ id: makeId(), value: '$1.4M',prefix: '$', suffix: 'M', label: 'Annual savings', description: 'In operational overhead', color: '#0ea5e9' }, |
| 32 |
]; |
| 33 |
|
| 34 |
/* ── Build wrapper CSS ──────────────────────────────────────────── */ |
| 35 |
function buildWrapStyle(a) { |
| 36 |
return Object.assign({ |
| 37 |
'--bkbg-cs-accent': a.accentColor, |
| 38 |
'--bkbg-cs-title': a.titleColor, |
| 39 |
'--bkbg-cs-subtitle': a.subtitleColor, |
| 40 |
'--bkbg-cs-label': a.labelColor, |
| 41 |
'--bkbg-cs-body': a.bodyColor, |
| 42 |
'--bkbg-cs-sec-lbl-bg': a.sectionLabelBg, |
| 43 |
'--bkbg-cs-sec-lbl-col': a.sectionLabelColor, |
| 44 |
'--bkbg-cs-card-bg': a.cardBg, |
| 45 |
'--bkbg-cs-card-border': a.cardBorder, |
| 46 |
'--bkbg-cs-metric-bg': a.metricBg, |
| 47 |
'--bkbg-cs-quote-bg': a.quoteBg, |
| 48 |
'--bkbg-cs-quote-border': a.quoteBorder, |
| 49 |
'--bkbg-cs-quote-color': a.quoteColor, |
| 50 |
'--bkbg-cs-cta-bg': a.ctaBg, |
| 51 |
'--bkbg-cs-cta-color': a.ctaColor, |
| 52 |
'--bkbg-cs-radius': a.cardRadius + 'px', |
| 53 |
paddingTop: a.paddingTop + 'px', |
| 54 |
paddingBottom: a.paddingBottom + 'px', |
| 55 |
backgroundColor: a.bgColor || undefined, |
| 56 |
}, |
| 57 |
_tv(a.typoTitle, '--bkbg-cs-tt-'), |
| 58 |
_tv(a.typoSubtitle, '--bkbg-cs-ts-'), |
| 59 |
_tv(a.typoBody, '--bkbg-cs-bd-'), |
| 60 |
_tv(a.typoQuote, '--bkbg-cs-qt-'), |
| 61 |
_tv(a.typoCta, '--bkbg-cs-ct-') |
| 62 |
); |
| 63 |
} |
| 64 |
|
| 65 |
/* ── Colour swatch helper ───────────────────────────────────────── */ |
| 66 |
function renderColorControl(key, label, value, onChange, openKey, setOpenKey) { |
| 67 |
var isOpen = openKey === key; |
| 68 |
return el('div', { key: key, style: { display:'flex', alignItems:'center', justifyContent:'space-between', padding:'4px 0', gap:'8px' } }, |
| 69 |
el('span', { style: { fontSize:'12px', color:'#1e1e1e', flex:1, lineHeight:1.4 } }, label), |
| 70 |
el('div', { style: { position:'relative', flexShrink:0 } }, |
| 71 |
el('button', { type:'button', onClick: function(){ setOpenKey(isOpen ? null : key); }, style: { width:'28px', height:'28px', borderRadius:'4px', border: isOpen ? '2px solid #007cba' : '2px solid #ddd', cursor:'pointer', padding:0, background: value||'#ccc' } }), |
| 72 |
isOpen && el(Popover, { position:'bottom left', onClose: function(){ setOpenKey(null); } }, |
| 73 |
el('div', { style:{ padding:'8px' } }, |
| 74 |
el(ColorPicker, { color:value, enableAlpha:true, onChange:onChange }) |
| 75 |
) |
| 76 |
) |
| 77 |
) |
| 78 |
); |
| 79 |
} |
| 80 |
|
| 81 |
/* ── Section label pill ──────────────────────────────────────────── */ |
| 82 |
function SectionLabel(props) { |
| 83 |
return el('span', { style: { |
| 84 |
display:'inline-block', padding:'3px 12px', borderRadius:'999px', |
| 85 |
background: props.bg || '#ede9fe', color: props.color || '#5b21b6', |
| 86 |
fontSize:'11px', fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:'10px', |
| 87 |
} }, props.children); |
| 88 |
} |
| 89 |
|
| 90 |
/* ── Metric row ──────────────────────────────────────────────────── */ |
| 91 |
function MetricCard(props) { |
| 92 |
var m = props.metric; |
| 93 |
var a = props.a; |
| 94 |
return el('div', { style: { background: a.metricBg||'#f5f3ff', borderRadius: a.cardRadius+'px', padding:'20px 18px', flex:'1 1 150px', minWidth:'130px', borderTop:'3px solid '+(m.color||a.accentColor||'#6c3fb5') } }, |
| 95 |
el('div', { style: { fontSize: a.metricValueSize+'px', fontWeight:900, color: m.color||a.accentColor||'#6c3fb5', lineHeight:1.1, marginBottom:'6px' } }, m.value), |
| 96 |
el('div', { style: { fontSize: a.metricLabelSize+'px', fontWeight:700, color: a.labelColor||'#374151', marginBottom:'4px' } }, m.label), |
| 97 |
m.description && el('div', { style: { fontSize:'12px', color: a.bodyColor||'#6b7280' } }, m.description) |
| 98 |
); |
| 99 |
} |
| 100 |
|
| 101 |
/* ── Metric Inspector row ─────────────────────────────────────────── */ |
| 102 |
function MetricEditor(props) { |
| 103 |
var m = props.metric; |
| 104 |
var onChange = props.onChange; |
| 105 |
var onRemove = props.onRemove; |
| 106 |
var openKey = props.openKey; |
| 107 |
var setOpenKey = props.setOpenKey; |
| 108 |
|
| 109 |
function upd(key, val) { var c=Object.assign({},m); c[key]=val; onChange(c); } |
| 110 |
|
| 111 |
return el('div', { style:{ background:'#f9f9f9', border:'1px solid #e0e0e0', borderRadius:'8px', padding:'10px 12px', marginBottom:'10px' } }, |
| 112 |
el(TextControl, { label:__('Display value (e.g. 94%)','blockenberg'), value:m.value, onChange:function(v){upd('value',v);} }), |
| 113 |
el(TextControl, { label:__('Label','blockenberg'), value:m.label, onChange:function(v){upd('label',v);} }), |
| 114 |
el(TextControl, { label:__('Description','blockenberg'), value:m.description||'', onChange:function(v){upd('description',v);} }), |
| 115 |
el('div', { style:{ display:'flex', alignItems:'center', justifyContent:'space-between', marginTop:'4px' } }, |
| 116 |
renderColorControl('mc-'+m.id, __('Accent colour','blockenberg'), m.color, function(v){upd('color',v);}, openKey, setOpenKey), |
| 117 |
el(Button, { variant:'tertiary', size:'compact', isDestructive:true, onClick:onRemove, style:{marginLeft:'8px'} }, '✕') |
| 118 |
) |
| 119 |
); |
| 120 |
} |
| 121 |
|
| 122 |
/* ── Register ────────────────────────────────────────────────────── */ |
| 123 |
registerBlockType('blockenberg/case-study', { |
| 124 |
title: __('Case Study','blockenberg'), |
| 125 |
icon: 'analytics', |
| 126 |
category: 'bkbg-business', |
| 127 |
|
| 128 |
edit: function(props) { |
| 129 |
var a = props.attributes; |
| 130 |
var setAttributes = props.setAttributes; |
| 131 |
|
| 132 |
var openColorState = useState(null); |
| 133 |
var openColorKey = openColorState[0]; |
| 134 |
var setOpenColorKey = openColorState[1]; |
| 135 |
|
| 136 |
var blockProps = useBlockProps({ style: buildWrapStyle(a) }); |
| 137 |
|
| 138 |
function cc(key, label, value, attrKey){ |
| 139 |
return renderColorControl(key, label, value, function(v){ var u={}; u[attrKey]=v; setAttributes(u); }, openColorKey, setOpenColorKey); |
| 140 |
} |
| 141 |
|
| 142 |
function updateMetric(id, upd) { setAttributes({ metrics: a.metrics.map(function(m){ return m.id===id ? upd : m; }) }); } |
| 143 |
function removeMetric(id) { setAttributes({ metrics: a.metrics.filter(function(m){ return m.id!==id; }) }); } |
| 144 |
function addMetric() { setAttributes({ metrics: a.metrics.concat([{ id:makeId(), value:'0', prefix:'', suffix:'', label:__('New metric','blockenberg'), description:'', color:'' }]) }); } |
| 145 |
|
| 146 |
var twoCol = a.layout === 'two-col'; |
| 147 |
|
| 148 |
return el(Fragment, null, |
| 149 |
el(InspectorControls, null, |
| 150 |
el(PanelBody, { title:__('Client Info','blockenberg'), initialOpen:true }, |
| 151 |
el(TextControl, { label:__('Client name','blockenberg'), value:a.clientName, onChange:function(v){setAttributes({clientName:v});} }), |
| 152 |
el(TextControl, { label:__('Industry / Category','blockenberg'), value:a.clientIndustry, onChange:function(v){setAttributes({clientIndustry:v});} }), |
| 153 |
el(TextControl, { label:__('Website URL','blockenberg'), value:a.clientUrl||'', onChange:function(v){setAttributes({clientUrl:v});} }), |
| 154 |
el(TextControl, { label:__('Tagline','blockenberg'), value:a.clientTagline||'', onChange:function(v){setAttributes({clientTagline:v});} }), |
| 155 |
el('p', { style:{margin:'4px 0 8px',fontSize:'12px',color:'#555'} }, __('Client logo:','blockenberg')), |
| 156 |
el(MediaUploadCheck, null, |
| 157 |
el(MediaUpload, { onSelect:function(m){setAttributes({clientLogoUrl:m.url,clientLogoId:m.id});}, allowedTypes:['image'], value:a.clientLogoId, |
| 158 |
render:function(mp){ |
| 159 |
return el(Fragment, null, |
| 160 |
a.clientLogoUrl && el('img', { src:a.clientLogoUrl, style:{maxHeight:'48px', objectFit:'contain', display:'block', marginBottom:'6px' } }), |
| 161 |
el(Button, { variant:'secondary', size:'compact', onClick:mp.open }, a.clientLogoUrl ? __('Change logo','blockenberg') : __('Upload logo','blockenberg')), |
| 162 |
a.clientLogoUrl && el(Button, { variant:'tertiary', size:'compact', isDestructive:true, onClick:function(){setAttributes({clientLogoUrl:'',clientLogoId:0});}, style:{marginLeft:'6px'} }, __('Remove','blockenberg')) |
| 163 |
); |
| 164 |
} |
| 165 |
}) |
| 166 |
) |
| 167 |
), |
| 168 |
el(PanelBody, { title:__('Header','blockenberg'), initialOpen:false }, |
| 169 |
el(ToggleControl, { label:__('Show title','blockenberg'), checked:a.showTitle, onChange:function(v){setAttributes({showTitle:v});}, __nextHasNoMarginBottom:true }), |
| 170 |
a.showTitle && el(TextControl, { label:__('Title','blockenberg'), value:a.title, onChange:function(v){setAttributes({title:v});} }), |
| 171 |
el(ToggleControl, { label:__('Show subtitle','blockenberg'), checked:a.showSubtitle, onChange:function(v){setAttributes({showSubtitle:v});}, __nextHasNoMarginBottom:true }), |
| 172 |
a.showSubtitle && el(TextControl, { label:__('Subtitle','blockenberg'), value:a.subtitle||'', onChange:function(v){setAttributes({subtitle:v});} }) |
| 173 |
), |
| 174 |
el(PanelBody, { title:__('Challenge & Solution labels','blockenberg'), initialOpen:false }, |
| 175 |
el(TextControl, { label:__('Challenge label','blockenberg'), value:a.challengeLabel||__('The Challenge','blockenberg'), onChange:function(v){setAttributes({challengeLabel:v});} }), |
| 176 |
el(TextControl, { label:__('Solution label','blockenberg'), value:a.solutionLabel||__('The Solution','blockenberg'), onChange:function(v){setAttributes({solutionLabel:v});} }) |
| 177 |
), |
| 178 |
el(PanelBody, { title:__('Metrics','blockenberg'), initialOpen:false }, |
| 179 |
(a.metrics||[]).map(function(m){ |
| 180 |
return el(MetricEditor, { key:m.id, metric:m, onChange:function(upd){updateMetric(m.id,upd);}, onRemove:function(){removeMetric(m.id);}, openKey:openColorKey, setOpenKey:setOpenColorKey }); |
| 181 |
}), |
| 182 |
el(Button, { variant:'primary', onClick:addMetric }, '+ ' + __('Add metric','blockenberg')) |
| 183 |
), |
| 184 |
el(PanelBody, { title:__('Quote','blockenberg'), initialOpen:false }, |
| 185 |
el(ToggleControl, { label:__('Show quote','blockenberg'), checked:a.showQuote, onChange:function(v){setAttributes({showQuote:v});}, __nextHasNoMarginBottom:true }), |
| 186 |
el(TextareaControl, { label:__('Quote text','blockenberg'), value:a.quote||'', onChange:function(v){setAttributes({quote:v});} }), |
| 187 |
el(TextControl, { label:__('Author name','blockenberg'), value:a.quoteAuthor||'', onChange:function(v){setAttributes({quoteAuthor:v});} }), |
| 188 |
el(TextControl, { label:__('Author role','blockenberg'), value:a.quoteAuthorRole||'', onChange:function(v){setAttributes({quoteAuthorRole:v});} }), |
| 189 |
el('p', { style:{margin:'4px 0 8px',fontSize:'12px',color:'#555'} }, __('Avatar:','blockenberg')), |
| 190 |
el(MediaUploadCheck, null, |
| 191 |
el(MediaUpload, { onSelect:function(m){setAttributes({quoteAvatarUrl:m.url,quoteAvatarId:m.id});}, allowedTypes:['image'], value:a.quoteAvatarId, |
| 192 |
render:function(mp){ |
| 193 |
return el(Fragment, null, |
| 194 |
a.quoteAvatarUrl && el('img', { src:a.quoteAvatarUrl, style:{width:'48px',height:'48px',objectFit:'cover',borderRadius:'50%',display:'block',marginBottom:'6px'} }), |
| 195 |
el(Button, { variant:'secondary', size:'compact', onClick:mp.open }, a.quoteAvatarUrl ? __('Change avatar','blockenberg') : __('Upload avatar','blockenberg')), |
| 196 |
a.quoteAvatarUrl && el(Button, { variant:'tertiary', size:'compact', isDestructive:true, onClick:function(){setAttributes({quoteAvatarUrl:'',quoteAvatarId:0});}, style:{marginLeft:'6px'} }, __('Remove','blockenberg')) |
| 197 |
); |
| 198 |
} |
| 199 |
}) |
| 200 |
) |
| 201 |
), |
| 202 |
el(PanelBody, { title:__('Call to Action','blockenberg'), initialOpen:false }, |
| 203 |
el(ToggleControl, { label:__('Show CTA button','blockenberg'), checked:a.showCta, onChange:function(v){setAttributes({showCta:v});}, __nextHasNoMarginBottom:true }), |
| 204 |
el(TextControl, { label:__('Button label','blockenberg'), value:a.ctaLabel||'', onChange:function(v){setAttributes({ctaLabel:v});} }), |
| 205 |
el(TextControl, { label:__('Button URL','blockenberg'), value:a.ctaUrl||'', onChange:function(v){setAttributes({ctaUrl:v});} }), |
| 206 |
el(ToggleControl, { label:__('Open in new tab','blockenberg'), checked:a.ctaNewTab, onChange:function(v){setAttributes({ctaNewTab:v});}, __nextHasNoMarginBottom:true }) |
| 207 |
), |
| 208 |
el(PanelBody, { title:__('Layout','blockenberg'), initialOpen:false }, |
| 209 |
el(SelectControl, { label:__('Layout','blockenberg'), value:a.layout, options:[{ label:__('Two columns (challenge / solution)','blockenberg'), value:'two-col' },{ label:__('Stacked','blockenberg'), value:'stack' }], onChange:function(v){setAttributes({layout:v});} }) |
| 210 |
), |
| 211 |
el(PanelBody, { title:__('Colours','blockenberg'), initialOpen:false }, |
| 212 |
cc('accentColor', __('Accent','blockenberg'), a.accentColor, 'accentColor'), |
| 213 |
cc('titleColor', __('Title','blockenberg'), a.titleColor, 'titleColor'), |
| 214 |
cc('subtitleColor', __('Subtitle','blockenberg'), a.subtitleColor, 'subtitleColor'), |
| 215 |
cc('labelColor', __('Label / metric label','blockenberg'), a.labelColor, 'labelColor'), |
| 216 |
cc('bodyColor', __('Body text','blockenberg'), a.bodyColor, 'bodyColor'), |
| 217 |
cc('sectionLabelBg', __('Section label background','blockenberg'), a.sectionLabelBg, 'sectionLabelBg'), |
| 218 |
cc('sectionLabelColor', __('Section label text','blockenberg'), a.sectionLabelColor, 'sectionLabelColor'), |
| 219 |
cc('cardBg', __('Card background','blockenberg'), a.cardBg, 'cardBg'), |
| 220 |
cc('metricBg', __('Metric card background','blockenberg'), a.metricBg, 'metricBg'), |
| 221 |
cc('quoteBg', __('Quote background','blockenberg'), a.quoteBg, 'quoteBg'), |
| 222 |
cc('quoteBorder', __('Quote border','blockenberg'), a.quoteBorder, 'quoteBorder'), |
| 223 |
cc('quoteColor', __('Quote text','blockenberg'), a.quoteColor, 'quoteColor'), |
| 224 |
cc('ctaBg', __('CTA background','blockenberg'), a.ctaBg, 'ctaBg'), |
| 225 |
cc('ctaColor', __('CTA text','blockenberg'), a.ctaColor, 'ctaColor'), |
| 226 |
cc('bgColor', __('Section background','blockenberg'), a.bgColor, 'bgColor') |
| 227 |
), |
| 228 |
el(PanelBody, { title:__('Appearance','blockenberg'), initialOpen:false }, |
| 229 |
el(RangeControl, { label:__('Card radius (px)','blockenberg'), value:a.cardRadius, min:0, max:40, onChange:function(v){setAttributes({cardRadius:v});} }), |
| 230 |
el(RangeControl, { label:__('CTA radius (px)','blockenberg'), value:a.ctaRadius, min:0, max:40, onChange:function(v){setAttributes({ctaRadius:v});} }) |
| 231 |
), |
| 232 |
el(PanelBody, { title:__('Spacing','blockenberg'), initialOpen:false }, |
| 233 |
el(RangeControl, { label:__('Padding top (px)','blockenberg'), value:a.paddingTop, min:0, max:200, onChange:function(v){setAttributes({paddingTop:v});} }), |
| 234 |
el(RangeControl, { label:__('Padding bottom (px)','blockenberg'), value:a.paddingBottom, min:0, max:200, onChange:function(v){setAttributes({paddingBottom:v});} }) |
| 235 |
), |
| 236 |
el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false }, |
| 237 |
el(getTypographyControl(), { label: __('Title', 'blockenberg'), value: a.typoTitle, onChange: function (v) { setAttributes({ typoTitle: v }); } }), |
| 238 |
el(getTypographyControl(), { label: __('Subtitle', 'blockenberg'), value: a.typoSubtitle, onChange: function (v) { setAttributes({ typoSubtitle: v }); } }), |
| 239 |
el(getTypographyControl(), { label: __('Body Text', 'blockenberg'), value: a.typoBody, onChange: function (v) { setAttributes({ typoBody: v }); } }), |
| 240 |
el(getTypographyControl(), { label: __('Quote Text', 'blockenberg'), value: a.typoQuote, onChange: function (v) { setAttributes({ typoQuote: v }); } }), |
| 241 |
el(getTypographyControl(), { label: __('CTA Button', 'blockenberg'), value: a.typoCta, onChange: function (v) { setAttributes({ typoCta: v }); } }), |
| 242 |
el(RangeControl, { label:__('Metric value size (px)','blockenberg'), value:a.metricValueSize, min:24, max:72, onChange:function(v){setAttributes({metricValueSize:v});} }), |
| 243 |
el(RangeControl, { label:__('Metric label size (px)','blockenberg'), value:a.metricLabelSize, min:10, max:20, onChange:function(v){setAttributes({metricLabelSize:v});} }) |
| 244 |
) |
| 245 |
), |
| 246 |
|
| 247 |
el('div', blockProps, |
| 248 |
/* Header */ |
| 249 |
(a.showTitle || a.showSubtitle) && el('div', { style:{ textAlign:'center', marginBottom:'32px' } }, |
| 250 |
a.showTitle && el('h2', { className: 'bkbg-cs-title', style:{ margin:'0 0 8px' } }, a.title), |
| 251 |
a.showSubtitle && el('p', { className: 'bkbg-cs-subtitle', style:{ margin:0 } }, a.subtitle) |
| 252 |
), |
| 253 |
|
| 254 |
/* Client info */ |
| 255 |
el('div', { style:{ display:'flex', alignItems:'center', gap:'18px', background: a.cardBg||'#fff', borderRadius: a.cardRadius+'px', padding:'20px 24px', marginBottom:'28px', boxShadow:'0 1px 8px rgba(0,0,0,0.06)' } }, |
| 256 |
a.clientLogoUrl && el('img', { src:a.clientLogoUrl, style:{ maxHeight:'60px', objectFit:'contain', flexShrink:0 } }), |
| 257 |
el('div', null, |
| 258 |
el('div', { style:{ fontWeight:800, fontSize:'20px', color: a.titleColor||'#1e1b4b' } }, a.clientName), |
| 259 |
el('div', { style:{ fontSize:'13px', color: a.accentColor||'#6c3fb5', fontWeight:600 } }, a.clientIndustry), |
| 260 |
a.clientTagline && el('div', { style:{ fontSize:'13px', color: a.bodyColor||'#6b7280', marginTop:'2px' } }, a.clientTagline) |
| 261 |
) |
| 262 |
), |
| 263 |
|
| 264 |
/* Challenge / Solution */ |
| 265 |
el('div', { style:{ display:'grid', gridTemplateColumns: twoCol ? '1fr 1fr' : '1fr', gap:'24px', marginBottom:'28px' } }, |
| 266 |
el('div', { style:{ background: a.cardBg||'#faf9ff', borderRadius: a.cardRadius+'px', padding:'24px' } }, |
| 267 |
el(SectionLabel, { bg: a.sectionLabelBg, color: a.sectionLabelColor }, a.challengeLabel || __('The Challenge','blockenberg')), |
| 268 |
el(RichText, { tagName:'div', className:'bkbg-cs-rt', value:a.challenge, onChange:function(v){setAttributes({challenge:v});}, placeholder:__('Describe the problem this client faced…','blockenberg') }) |
| 269 |
), |
| 270 |
el('div', { style:{ background: a.cardBg||'#faf9ff', borderRadius: a.cardRadius+'px', padding:'24px' } }, |
| 271 |
el(SectionLabel, { bg: a.sectionLabelBg, color: a.sectionLabelColor }, a.solutionLabel || __('The Solution','blockenberg')), |
| 272 |
el(RichText, { tagName:'div', className:'bkbg-cs-rt', value:a.solution, onChange:function(v){setAttributes({solution:v});}, placeholder:__('Describe how you solved it…','blockenberg') }) |
| 273 |
) |
| 274 |
), |
| 275 |
|
| 276 |
/* Metrics */ |
| 277 |
(a.metrics||[]).length > 0 && el('div', { style:{ display:'flex', flexWrap:'wrap', gap:'16px', marginBottom:'28px' } }, |
| 278 |
(a.metrics||[]).map(function(m){ return el(MetricCard, { key:m.id, metric:m, a:a }); }) |
| 279 |
), |
| 280 |
|
| 281 |
/* Quote */ |
| 282 |
a.showQuote && a.quote && el('blockquote', { style:{ margin:'0 0 28px', padding:'24px 28px', background: a.quoteBg||'#f5f3ff', borderLeft:'4px solid '+(a.quoteBorder||'#6c3fb5'), borderRadius: a.cardRadius+'px', color: a.quoteColor||'#1e1b4b' } }, |
| 283 |
el('p', { style:{ fontSize:'18px', fontStyle:'italic', lineHeight:1.6, margin:'0 0 14px' } }, '\u201C' + a.quote + '\u201D'), |
| 284 |
el('div', { style:{ display:'flex', alignItems:'center', gap:'12px' } }, |
| 285 |
a.quoteAvatarUrl && el('img', { src:a.quoteAvatarUrl, style:{ width:'40px', height:'40px', borderRadius:'50%', objectFit:'cover' } }), |
| 286 |
el('div', null, |
| 287 |
el('div', { style:{ fontWeight:700, fontSize:'14px' } }, a.quoteAuthor), |
| 288 |
el('div', { style:{ fontSize:'12px', opacity:0.7 } }, a.quoteAuthorRole) |
| 289 |
) |
| 290 |
) |
| 291 |
), |
| 292 |
|
| 293 |
/* CTA */ |
| 294 |
a.showCta && a.ctaLabel && el('div', { style:{ textAlign:'center' } }, |
| 295 |
el('a', { href: a.ctaUrl||'#', style:{ display:'inline-block', padding:'14px 32px', background: a.ctaBg||'#6c3fb5', color: a.ctaColor||'#fff', borderRadius: a.ctaRadius+'px', fontWeight:700, fontSize:'16px', textDecoration:'none' } }, a.ctaLabel) |
| 296 |
) |
| 297 |
) |
| 298 |
); |
| 299 |
}, |
| 300 |
|
| 301 |
save: function(props) { |
| 302 |
var a = props.attributes; |
| 303 |
var twoCol = a.layout === 'two-col'; |
| 304 |
return el('div', wp.blockEditor.useBlockProps.save({ |
| 305 |
className: 'bkbg-cs-wrapper bkbg-cs-layout-' + a.layout, |
| 306 |
style: buildWrapStyle(a), |
| 307 |
}), |
| 308 |
(a.showTitle || a.showSubtitle) && el('div', { className:'bkbg-cs-header' }, |
| 309 |
a.showTitle && el('h2', { className:'bkbg-cs-title' }, a.title), |
| 310 |
a.showSubtitle && el('p', { className:'bkbg-cs-subtitle' }, a.subtitle) |
| 311 |
), |
| 312 |
el('div', { className:'bkbg-cs-client-bar' }, |
| 313 |
a.clientLogoUrl && el('img', { className:'bkbg-cs-logo', src:a.clientLogoUrl, alt:a.clientName, loading:'lazy' }), |
| 314 |
el('div', { className:'bkbg-cs-client-info' }, |
| 315 |
el('div', { className:'bkbg-cs-client-name' }, a.clientName), |
| 316 |
el('div', { className:'bkbg-cs-client-industry' }, a.clientIndustry), |
| 317 |
a.clientTagline && el('div', { className:'bkbg-cs-client-tagline' }, a.clientTagline) |
| 318 |
) |
| 319 |
), |
| 320 |
el('div', { className: 'bkbg-cs-content-grid' + (twoCol ? ' bkbg-cs-two-col' : '') }, |
| 321 |
el('div', { className:'bkbg-cs-card bkbg-cs-challenge' }, |
| 322 |
el('span', { className:'bkbg-cs-section-label' }, a.challengeLabel || 'The Challenge'), |
| 323 |
el(RichText.Content, { tagName:'div', className:'bkbg-cs-rt', value:a.challenge }) |
| 324 |
), |
| 325 |
el('div', { className:'bkbg-cs-card bkbg-cs-solution' }, |
| 326 |
el('span', { className:'bkbg-cs-section-label' }, a.solutionLabel || 'The Solution'), |
| 327 |
el(RichText.Content, { tagName:'div', className:'bkbg-cs-rt', value:a.solution }) |
| 328 |
) |
| 329 |
), |
| 330 |
(a.metrics||[]).length > 0 && el('div', { className:'bkbg-cs-metrics' }, |
| 331 |
(a.metrics||[]).map(function(m){ |
| 332 |
return el('div', { key:m.id, className:'bkbg-cs-metric', style:{ borderTopColor: m.color||a.accentColor||'' } }, |
| 333 |
el('div', { className:'bkbg-cs-metric-value' }, m.value), |
| 334 |
el('div', { className:'bkbg-cs-metric-label' }, m.label), |
| 335 |
m.description && el('div', { className:'bkbg-cs-metric-desc' }, m.description) |
| 336 |
); |
| 337 |
}) |
| 338 |
), |
| 339 |
a.showQuote && a.quote && el('blockquote', { className:'bkbg-cs-quote' }, |
| 340 |
el('p', { className:'bkbg-cs-quote-text' }, '\u201C' + a.quote + '\u201D'), |
| 341 |
el('div', { className:'bkbg-cs-quote-author' }, |
| 342 |
a.quoteAvatarUrl && el('img', { className:'bkbg-cs-avatar', src:a.quoteAvatarUrl, alt:a.quoteAuthor, loading:'lazy' }), |
| 343 |
el('div', null, |
| 344 |
el('div', { className:'bkbg-cs-author-name' }, a.quoteAuthor), |
| 345 |
el('div', { className:'bkbg-cs-author-role' }, a.quoteAuthorRole) |
| 346 |
) |
| 347 |
) |
| 348 |
), |
| 349 |
a.showCta && a.ctaLabel && el('div', { className:'bkbg-cs-cta-row' }, |
| 350 |
el('a', { className:'bkbg-cs-cta', href:a.ctaUrl||'#', target: a.ctaNewTab ? '_blank' : undefined, rel: a.ctaNewTab ? 'noopener noreferrer' : undefined }, a.ctaLabel) |
| 351 |
) |
| 352 |
); |
| 353 |
} |
| 354 |
}); |
| 355 |
}() ); |
| 356 |
|