Compare commits

...

7 Commits

5 changed files with 1291 additions and 54 deletions

View File

@@ -8,10 +8,12 @@
return <<<'ORIBI_SYNC_CONTENT'
<!-- wp:oribi/hero-animated {"label":"● Digital Signage Solutions","title":"Turn any screen into a dynamic communication tool.","highlightWord":"dynamic","description":"Digital signage is the modern way to connect with your audience. From eye-catching retail displays to dynamic informational screens, we craft tailored solutions that capture attention and deliver your message.","secondaryBtnText":"Request Demo","secondaryBtnUrl":"/demo","stat1Value":"4K","stat1Label":"Resolution Supported","stat2Value":"500+","stat2Label":"Screens Supported","stat3Value":"99.9%","stat3Label":"Uptime"} /-->
<!-- wp:oribi/platform-section {"label":"The Complete Package","heading":"Everything You Need for Engaging Digital Signage","lead":"High-quality visuals, real-time data, and reliable playback — all managed from one powerful platform."} -->
<!-- wp:oribi/platform-row {"heading":"Professional Content Creation","description":"Our in-house photography and video production services showcase your products, services, and environment with polished, engaging visuals. From digital menu boards to branded promotions, we create content that captures attention.","btnText":"See Features","btnUrl":"/features"} /-->
<!-- wp:oribi/use-cases {"label":"● Use Cases","heading":"Built for Every Scenario","lead":"From menus to meeting-room dashboards, digital signage adapts to your environment.","case1Title":"Menu Boards","case1Desc":"Showcase food, drinks, and daily specials with dynamic, always-current displays.","case2Title":"Event Displays","case2Desc":"Promote schedules, speakers, and live countdowns across lobbies and venues.","case3Title":"Office Dashboards","case3Desc":"Surface KPIs, occupancy data, and team alerts on screens throughout your workspace.","case4Title":"Wayfinding","case4Desc":"Guide visitors through complex buildings with interactive maps and directional signs."} /-->
<!-- wp:oribi/platform-row {"heading":"Live Data \u0026amp; Web Dashboards","description":"Integrate your existing web dashboards, social feeds, and real-time data sources directly to your displays. Bring your most important information to life on screen, automatically and effortlessly.","btnUrl":"/features","reversed":true,"isDashboard":true} /-->
<!-- wp:oribi/platform-section {"label":"The Complete Package","heading":"Everything You Need for Engaging Digital Signage","lead":"High-quality visuals, real-time data, and reliable playback — all managed from one powerful platform."} -->
<!-- wp:oribi/platform-row {"heading":"Professional Content Creation","description":"Our in-house photography and video production services showcase your products, services, and environment with polished, engaging visuals. From digital menu boards to branded promotions, we create content that captures attention.","btnText":"See Features","btnUrl":"/features","cameraAnim":true} /-->
<!-- wp:oribi/platform-row {"heading":"Live Data u0026amp; Web Dashboards","description":"Integrate your existing web dashboards, social feeds, and real-time data sources directly to your displays. Bring your most important information to life on screen, automatically and effortlessly.","btnUrl":"/features","reversed":true,"isDashboard":true} /-->
<!-- wp:oribi/platform-row {"heading":"Reliable on Any Screen","description":"Our intelligent player devices work on any screen with HDMI, and keep your message running even when the internet goes down. Enterprise-grade hardware designed for uninterrupted, always-on signage.","btnText":"View Devices","btnUrl":"/devices","deviceAnim":true} /-->
<!-- /wp:oribi/platform-section -->

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@
var LINE_W = 340; // line graph width in SVG units
var PIE_R = 55; // pie chart radius
var DARK = { text: '#E0E0E0', muted: '#9E9E9E', border: '#333', center: '#222' };
var DARK = { text: '#E0E0E0', muted: '#9E9E9E', border: '#333', center: '#1A1A1A' };
var LIGHT = { text: '#333333', muted: '#666666', border: '#E0E0E0', center: '#fff' };
function isDark() { return document.documentElement.getAttribute('data-theme') === 'dark'; }

View File

@@ -1180,6 +1180,7 @@ reg('oribi/platform-row', {
imgUrl: { type: 'string', default: '' },
imgAlt: { type: 'string', default: '' },
imgWidth: { type: 'number', default: 300 },
cameraAnim: { type: 'boolean', default: false },
},
edit: function (props) {
var a = props.attributes, s = props.setAttributes;
@@ -1189,7 +1190,8 @@ reg('oribi/platform-row', {
el(PB, { title: 'Row Settings' },
el(TC, { label: 'Visual (emoji)', value: a.visual, onChange: function(v){s({visual:v});} }),
el(TC, { label: 'Button URL', value: a.btnUrl, onChange: function(v){s({btnUrl:v});} }),
el(TG, { label: 'Reversed', checked: !!a.reversed, onChange: function(v){s({reversed:v});} })
el(TG, { label: 'Reversed', checked: !!a.reversed, onChange: function(v){s({reversed:v});} }),
el(TG, { label: 'Camera Animation', checked: !!a.cameraAnim, onChange: function(v){s({cameraAnim:v});} })
),
el(PB, { title: 'Visual Image', initialOpen: false },
el(MUC, null,
@@ -1220,7 +1222,67 @@ reg('oribi/platform-row', {
a.btnUrl ? el(RT, { tagName: 'span', className: 'btn btn-outline mt-3',
value: a.btnText, onChange: function(v){s({btnText:v});}, placeholder: 'Button...' }) : null
),
a.imgUrl
a.cameraAnim
? el('div', { className: 'platform-visual has-camera' },
el('div', { className: 'cam-stage', 'aria-hidden': 'true' },
// Photo camera (left)
el('div', { className: 'pc-wrap' },
el('div', { className: 'pc-body' },
el('div', { className: 'pc-flash-unit' }),
el('div', { className: 'pc-top' },
el('div', { className: 'pc-shutter-btn' }),
el('div', { className: 'pc-viewfinder' })
),
el('div', { className: 'pc-front' },
el('div', { className: 'pc-lens-ring' },
el('div', { className: 'pc-lens-glass' },
el('div', { className: 'pc-lens-reflex' })
)
),
el('div', { className: 'pc-grip' })
)
),
el('div', { className: 'pc-prints' },
el('div', { className: 'pc-print pc-print--1', style: { opacity: '1', transform: 'rotate(-12deg) translateY(0)' } },
el('div', { className: 'pc-print__img' })
)
)
),
// Centre scene
el('div', { className: 'cam-scene' },
el('div', { className: 'cam-subject cam-subject--1' }),
el('div', { className: 'cam-flash-overlay' }),
el('div', { className: 'cam-vid-overlay' })
),
// Video camera on tripod (right)
el('div', { className: 'vc-wrap' },
el('div', { className: 'vc-camera' },
el('div', { className: 'vc-handle' }),
el('div', { className: 'vc-body' },
el('div', { className: 'vc-lens-barrel' },
el('div', { className: 'vc-lens-tip' },
el('div', { className: 'vc-lens-glass' },
el('div', { className: 'vc-lens-reflex' })
)
)
),
el('div', { className: 'vc-top-rail' }),
el('div', { className: 'vc-rec-light' }),
el('div', { className: 'vc-eyepiece' })
)
),
el('div', { className: 'vc-tripod' },
el('div', { className: 'vc-stem' }),
el('div', { className: 'vc-legs' },
el('div', { className: 'vc-leg vc-leg--l' }),
el('div', { className: 'vc-leg vc-leg--c' }),
el('div', { className: 'vc-leg vc-leg--r' })
)
)
)
)
)
: a.imgUrl
? el('div', { className: 'platform-visual has-img' },
el('img', { src: a.imgUrl, style: { width: imgW + 'px', maxWidth: '100%', height: 'auto', borderRadius: '4px', objectFit: 'contain', display: 'block', marginInline: 'auto' } })
)
@@ -1701,7 +1763,6 @@ reg('oribi/hero-animated', {
save: function () { return null; }
});
/* ANIMATED PAGE HERO ──────────────────────────────────────────────────── */
reg('oribi/page-hero-animated', {
title: 'Animated Page Hero',
icon: 'flag',
@@ -1784,4 +1845,81 @@ reg('oribi/site-footer', {
save: function () { return null; }
});
/* USE CASES SHOWCASE ──────────────────────────────────────────────────── */
reg('oribi/use-cases', {
title: 'Use Cases Showcase',
icon: 'grid-view',
category: 'oribi',
supports: { html: false },
attributes: {
label: { type: 'string', default: '\u25cf Use Cases' },
heading: { type: 'string', default: 'Built for Every Scenario' },
lead: { type: 'string', default: 'From menus to meeting-room dashboards, digital signage adapts to your environment.' },
case1Title: { type: 'string', default: 'Menu Boards' },
case1Desc: { type: 'string', default: 'Showcase food, drinks, and daily specials with dynamic, always-current displays.' },
case2Title: { type: 'string', default: 'Event Displays' },
case2Desc: { type: 'string', default: 'Promote schedules, speakers, and live countdowns across lobbies and venues.' },
case3Title: { type: 'string', default: 'Office Dashboards' },
case3Desc: { type: 'string', default: 'Surface KPIs, occupancy data, and team alerts on screens throughout your workspace.' },
case4Title: { type: 'string', default: 'Wayfinding' },
case4Desc: { type: 'string', default: 'Guide visitors through complex buildings with interactive maps and directional signs.' },
},
edit: function (props) {
var a = props.attributes, s = props.setAttributes;
return el(Frag, null,
el(IC, null,
el(PB, { title: 'Section Header' },
el(TC, { label: 'Label', value: a.label, onChange: function(v){s({label:v});} }),
el(TC, { label: 'Heading', value: a.heading, onChange: function(v){s({heading:v});} }),
el(TA, { label: 'Lead', value: a.lead, onChange: function(v){s({lead:v});} })
),
el(PB, { title: 'Use Case 1 Menu Boards', initialOpen: false },
el(TC, { label: 'Title', value: a.case1Title, onChange: function(v){s({case1Title:v});} }),
el(TA, { label: 'Description', value: a.case1Desc, onChange: function(v){s({case1Desc:v});} })
),
el(PB, { title: 'Use Case 2 Events', initialOpen: false },
el(TC, { label: 'Title', value: a.case2Title, onChange: function(v){s({case2Title:v});} }),
el(TA, { label: 'Description', value: a.case2Desc, onChange: function(v){s({case2Desc:v});} })
),
el(PB, { title: 'Use Case 3 Dashboards', initialOpen: false },
el(TC, { label: 'Title', value: a.case3Title, onChange: function(v){s({case3Title:v});} }),
el(TA, { label: 'Description', value: a.case3Desc, onChange: function(v){s({case3Desc:v});} })
),
el(PB, { title: 'Use Case 4 Wayfinding', initialOpen: false },
el(TC, { label: 'Title', value: a.case4Title, onChange: function(v){s({case4Title:v});} }),
el(TA, { label: 'Description', value: a.case4Desc, onChange: function(v){s({case4Desc:v});} })
)
),
el('section', { className: 'section use-cases-section' },
el('div', { className: 'container' },
el('div', { className: 'section-header' },
a.label ? el('span', { className: 'section-label' }, a.label) : null,
a.heading ? el('h2', null, a.heading) : null,
a.lead ? el('p', { className: 'lead' }, a.lead) : null
),
el('div', { className: 'uc-track' },
['menu', 'event', 'dashboard', 'wayfinding'].map(function (mod, i) {
var n = i + 1;
var title = a['case' + n + 'Title'];
var desc = a['case' + n + 'Desc'];
return el('div', { key: mod, className: 'uc-item' },
el('div', { className: 'uc-circle uc-anim--' + mod,
style: { display:'flex', alignItems:'center', justifyContent:'center',
fontSize:'.7rem', color:'var(--color-muted)', textAlign:'center', padding:'8px' } },
mod
),
el('div', { className: 'uc-item-body' },
el('div', { className: 'uc-item-title' }, title),
desc ? el('p', { className: 'uc-item-desc' }, desc) : null
)
);
})
)
)
)
);
},
save: function () { return null; }
});
})(window.wp);

View File

@@ -555,6 +555,7 @@ add_action( 'init', function () {
'imgWidth' => [ 'type' => 'number', 'default' => 300 ],
'deviceAnim' => [ 'type' => 'boolean', 'default' => false ],
'tvStick' => [ 'type' => 'boolean', 'default' => false ],
'cameraAnim' => [ 'type' => 'boolean', 'default' => false ],
],
'supports' => $block_supports,
'render_callback' => 'oribi_render_platform_row',
@@ -655,6 +656,25 @@ add_action( 'init', function () {
'render_callback' => 'oribi_render_page_hero_animated',
] );
/* Use Cases Showcase - 4 animated circles beneath the homepage hero */
register_block_type( 'oribi/use-cases', [
'attributes' => [
'label' => [ 'type' => 'string', 'default' => '● Use Cases' ],
'heading' => [ 'type' => 'string', 'default' => 'Built for Every Scenario' ],
'lead' => [ 'type' => 'string', 'default' => 'From menus to meeting-room dashboards, digital signage adapts to your environment.' ],
'case1Title' => [ 'type' => 'string', 'default' => 'Menu Boards' ],
'case1Desc' => [ 'type' => 'string', 'default' => 'Showcase food, drinks, and daily specials with dynamic, always-current displays.' ],
'case2Title' => [ 'type' => 'string', 'default' => 'Event Displays' ],
'case2Desc' => [ 'type' => 'string', 'default' => 'Promote schedules, speakers, and live countdowns across lobbies and venues.' ],
'case3Title' => [ 'type' => 'string', 'default' => 'Office Dashboards' ],
'case3Desc' => [ 'type' => 'string', 'default' => 'Surface KPIs, occupancy data, and team alerts on screens throughout your workspace.' ],
'case4Title' => [ 'type' => 'string', 'default' => 'Wayfinding' ],
'case4Desc' => [ 'type' => 'string', 'default' => 'Guide visitors through complex buildings with interactive maps and directional signs.' ],
],
'supports' => $block_supports,
'render_callback' => 'oribi_render_use_cases',
] );
} );
/* ══════════════════════════════════════════════════════════════════════════════
@@ -1498,6 +1518,59 @@ function oribi_render_platform_row( $a ) {
$ts .= '</div>';
$visual_html = $ts;
$visual_cls = 'platform-visual has-tv-stick';
} elseif ( ! empty( $a['cameraAnim'] ) ) {
$ca = '<div class="cam-stage" aria-hidden="true">';
// ── Left: compact photo camera ──
$ca .= '<div class="pc-wrap">';
$ca .= '<div class="pc-body">';
$ca .= '<div class="pc-flash-unit"></div>';
$ca .= '<div class="pc-top"><div class="pc-shutter-btn"></div><div class="pc-viewfinder"></div></div>';
$ca .= '<div class="pc-front">';
$ca .= '<div class="pc-lens-ring"><div class="pc-lens-glass"><div class="pc-lens-reflex"></div></div></div>';
$ca .= '<div class="pc-grip"></div>';
$ca .= '</div>';
$ca .= '</div>'; // pc-body
$ca .= '<div class="pc-prints">';
$ca .= '<div class="pc-print pc-print--1"><div class="pc-print__img"></div></div>';
$ca .= '<div class="pc-print pc-print--2"><div class="pc-print__img"></div></div>';
$ca .= '<div class="pc-print pc-print--3"><div class="pc-print__img"></div></div>';
$ca .= '</div>'; // pc-prints
$ca .= '</div>'; // pc-wrap
// ── Centre: product scene both cameras shoot ──
$ca .= '<div class="cam-scene">';
$ca .= '<div class="cam-subject cam-subject--1"></div>';
$ca .= '<div class="cam-subject cam-subject--2"></div>';
$ca .= '<div class="cam-subject cam-subject--3"></div>';
$ca .= '<div class="cam-flash-overlay"></div>';
$ca .= '<div class="cam-vid-overlay"></div>';
$ca .= '</div>'; // cam-scene
// ── Right: retro VHS video camera on tripod ──
$ca .= '<div class="vc-wrap">';
$ca .= '<div class="vc-camera">';
$ca .= '<div class="vc-handle"></div>';
$ca .= '<div class="vc-body">';
$ca .= '<div class="vc-lens-barrel"><div class="vc-lens-tip"><div class="vc-lens-glass"><div class="vc-lens-reflex"></div></div></div></div>';
$ca .= '<div class="vc-top-rail"></div>';
$ca .= '<div class="vc-rec-light"></div>';
$ca .= '<div class="vc-eyepiece"></div>';
$ca .= '</div>'; // vc-body
$ca .= '</div>'; // vc-camera
$ca .= '<div class="vc-tripod">';
$ca .= '<div class="vc-stem"></div>';
$ca .= '<div class="vc-legs">';
$ca .= '<div class="vc-leg vc-leg--l"></div>';
$ca .= '<div class="vc-leg vc-leg--c"></div>';
$ca .= '<div class="vc-leg vc-leg--r"></div>';
$ca .= '</div>'; // vc-legs
$ca .= '</div>'; // vc-tripod
$ca .= '</div>'; // vc-wrap
$ca .= '</div>'; // cam-stage
$visual_html = $ca;
$visual_cls = 'platform-visual has-camera';
} else {
$visual_html = oribi_render_icon( $a['visual'] ?? '' );
$visual_cls = 'platform-visual';
@@ -1708,3 +1781,95 @@ function oribi_render_page_hero_animated( $a ) {
</section>
<?php return ob_get_clean();
}
/* ── Use Cases Showcase ────────────────────────────────────────────────── */
function oribi_uc_anim_inner( $mod ) {
switch ( $mod ) {
case 'menu':
return '
<div class="uc-inner uc-inner--menu" aria-hidden="true">
<div class="uc-menu-header"></div>
<div class="uc-menu-row"><span class="uc-menu-name"></span><span class="uc-menu-price"></span></div>
<div class="uc-menu-row uc-menu-row--highlight"><span class="uc-menu-name"></span><span class="uc-menu-price"></span></div>
<div class="uc-menu-row"><span class="uc-menu-name uc-menu-name--sm"></span><span class="uc-menu-price"></span></div>
<div class="uc-menu-row"><span class="uc-menu-name"></span><span class="uc-menu-price"></span></div>
<div class="uc-menu-divider"></div>
<div class="uc-menu-row"><span class="uc-menu-name uc-menu-name--sm"></span><span class="uc-menu-price"></span></div>
</div>';
case 'event':
return '
<div class="uc-inner uc-inner--event" aria-hidden="true">
<div class="uc-event-cursor"></div>
<div class="uc-event-header"></div>
<div class="uc-event-row"><div class="uc-event-time"></div><div class="uc-event-bar uc-event-bar--active"></div></div>
<div class="uc-event-row"><div class="uc-event-time"></div><div class="uc-event-bar"></div></div>
<div class="uc-event-row"><div class="uc-event-time"></div><div class="uc-event-bar uc-event-bar--accent"></div></div>
<div class="uc-event-row"><div class="uc-event-time"></div><div class="uc-event-bar"></div></div>
</div>';
case 'dashboard':
return '
<div class="uc-inner uc-inner--dashboard" aria-hidden="true">
<div class="uc-db-bars">
<div class="uc-db-bar uc-db-bar--1"></div>
<div class="uc-db-bar uc-db-bar--2"></div>
<div class="uc-db-bar uc-db-bar--3"></div>
<div class="uc-db-bar uc-db-bar--4"></div>
</div>
<div class="uc-db-baseline"></div>
<div class="uc-db-labels">
<div class="uc-db-lbl"></div>
<div class="uc-db-lbl"></div>
<div class="uc-db-lbl"></div>
<div class="uc-db-lbl"></div>
</div>
</div>';
case 'wayfinding':
return '
<div class="uc-inner uc-inner--wayfinding" aria-hidden="true">
<div class="uc-wf-corridor uc-wf-corridor--h"></div>
<div class="uc-wf-corridor uc-wf-corridor--v"></div>
<div class="uc-wf-room uc-wf-room--1"></div>
<div class="uc-wf-room uc-wf-room--2"></div>
<div class="uc-wf-room uc-wf-room--3"></div>
<div class="uc-wf-dot"></div>
<div class="uc-wf-arrow"></div>
</div>';
default:
return '';
}
}
function oribi_render_use_cases( $a ) {
$cases = [
[ 'title' => $a['case1Title'], 'desc' => $a['case1Desc'], 'mod' => 'menu' ],
[ 'title' => $a['case2Title'], 'desc' => $a['case2Desc'], 'mod' => 'event' ],
[ 'title' => $a['case3Title'], 'desc' => $a['case3Desc'], 'mod' => 'dashboard' ],
[ 'title' => $a['case4Title'], 'desc' => $a['case4Desc'], 'mod' => 'wayfinding' ],
];
ob_start(); ?>
<section class="section use-cases-section">
<div class="container">
<?php if ( $a['label'] || $a['heading'] || $a['lead'] ) : ?>
<div class="section-header">
<?php if ( $a['label'] ) : ?><span class="section-label"><?php echo esc_html( $a['label'] ); ?></span><?php endif; ?>
<?php if ( $a['heading'] ) : ?><h2><?php echo wp_kses_post( $a['heading'] ); ?></h2><?php endif; ?>
<?php if ( $a['lead'] ) : ?><p class="lead"><?php echo wp_kses_post( $a['lead'] ); ?></p><?php endif; ?>
</div>
<?php endif; ?>
<div class="uc-track">
<?php foreach ( $cases as $c ) : ?>
<div class="uc-item">
<div class="uc-circle uc-anim--<?php echo esc_attr( $c['mod'] ); ?>">
<?php echo oribi_uc_anim_inner( $c['mod'] ); ?>
</div>
<div class="uc-item-body">
<div class="uc-item-title"><?php echo esc_html( $c['title'] ); ?></div>
<?php if ( $c['desc'] ) : ?><p class="uc-item-desc"><?php echo esc_html( $c['desc'] ); ?></p><?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<?php return ob_get_clean();
}