Files
cms-SiteForge/app/static/studio-experience-v829.js
T
浅念 45c39b1695 feat: trust_bar + applications_band blocks; homepage now block-driven
- blueprints: register trust_bar (icon/title/text items) and applications_band
  (2x2 dark-band tiles) block types; render with escaped items, ordinal icon
  fallback, 8-item cap; auto-exposed in editor via /api/editor/blocks and
  grouped under business in the studio palette
- blocks.css: platform base layer for both blocks (app/static + trade-pro
  Layer A kept verbatim in sync) + trade-pro bridge vocabulary (icon-circle,
  hairline dividers, navy->brand gradient band, glass tiles, 900/620
  breakpoints, reduced-motion) without touching canvas hooks
- tests: test_trade_pro_home_block_driven covers the full studio-draft
  PUT -> publish -> build chain; 8 block types on the homepage, template
  markers absent under layout_mode=replace, clean build report
- scripts/setup_home_blocks.py: production write path for site 483295c29ea0
  (login -> draft -> publish -> build -> verify); real catalogue counts feed
  the stats block; run after the Docker image picks up the new block types

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-28 18:11:32 +08:00

48 lines
2.5 KiB
JavaScript

/* SiteForge V8.29: presentation-only studio helpers. No persisted-schema changes. */
'use strict';
(function(root){
const themes=new Set(['automotive','industrial','corporate','minimal','trade-pro']);
const pages=new Set(['home','listing','product','article','about','contact']);
const categories={
visual:new Set(['hero','banner','carousel','gallery','image','image_text','image-grid','video','slider']),
business:new Set(['collection','products','product_list','brand_wall','brands','features','stats','testimonials','faq','contact','form','cta','map','trust_bar','applications_band']),
advanced:new Set(['layout','columns','tabs','accordion','html-embed','embed','spacer','divider'])
};
function categoryOf(key){for(const [name,ids] of Object.entries(categories))if(ids.has(key))return name;return 'basic'}
function groupBlocks(blocks,query=''){
const result={basic:[],visual:[],business:[],advanced:[]};
const q=String(query).trim().toLocaleLowerCase().slice(0,70);
for(const [key,block] of Object.entries(blocks||{})){
if(!block||typeof block!=='object')continue;
const text=[key,block.name,block.description].join(' ').toLocaleLowerCase();
if(q&&!text.includes(q))continue;
result[categoryOf(key)].push({key,block});
}
return result;
}
function previewUrl(theme,page){
if(!themes.has(theme)||!pages.has(page))return null;
return `/api/factory/themes/${theme}/preview?page_type=${page}`;
}
/* Only CSS-token values accepted by the existing server-side block validator. */
const designPalettes={
automotive:['#ffffff','#14283d','#f3f6f9','#102e47'],
industrial:['#ffffff','#193f59','#eef5f8','#104a6d'],
corporate:['#ffffff','#262d58','#f4f3fb','#34397b'],
minimal:['#faf9f5','#292924','#f0efe9','#30302c'],
'trade-pro':['#ffffff','#17365c','#eef4fc','#0b3d91']
};
function stylePreset(theme,preset){
const [base,ink,soft,dark]=designPalettes[themes.has(theme)?theme:'corporate'];
switch(preset){
case 'clean':return {background:base,text_color:ink,padding:72};
case 'soft':return {background:soft,text_color:ink,padding:58};
case 'feature':return {background:dark,text_color:'#ffffff',padding:90};
default:return null;
}
}
const api=Object.freeze({categoryOf,groupBlocks,previewUrl,stylePreset});
if(typeof module!=='undefined'&&module.exports)module.exports=api;
if(root)root.SiteForgeStudioExperience=api;
})(typeof window!=='undefined'?window:null);