Add stats counter functionality and update theme styles for improved aesthetics
This commit is contained in:
parent
a8f9d4edf8
commit
eea113d2d5
@ -30,6 +30,7 @@
|
||||
'dine360_theme_shivasakthi/static/src/scss/shop.scss',
|
||||
'dine360_theme_shivasakthi/static/src/js/deal_switcher.js',
|
||||
'dine360_theme_shivasakthi/static/src/js/category_slider.js',
|
||||
'dine360_theme_shivasakthi/static/src/js/stats_counter.js',
|
||||
],
|
||||
},
|
||||
'images': [
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||
|
||||
publicWidget.registry.StatsCounter = publicWidget.Widget.extend({
|
||||
selector: '.s_stats_section',
|
||||
start: function () {
|
||||
this.$counters = this.$('.stat-counter');
|
||||
if (!this.$counters.length) {
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Initialize IntersectionObserver to track when stats section is in view
|
||||
this.observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
this._animateCounters();
|
||||
} else {
|
||||
this._resetCounters();
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.1 });
|
||||
|
||||
this.observer.observe(this.el);
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Formats numerical value to human readable format (e.g. 2000 -> 2K)
|
||||
* @param {number} value
|
||||
* @returns {string|number}
|
||||
*/
|
||||
_formatValue: function (value) {
|
||||
if (value >= 1000) {
|
||||
const kValue = value / 1000;
|
||||
return kValue % 1 === 0 ? kValue.toFixed(0) + 'K' : kValue.toFixed(1) + 'K';
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
_animateCounters: function () {
|
||||
this.$counters.each((index, el) => {
|
||||
const $el = $(el);
|
||||
if ($el.data('animating')) return;
|
||||
$el.data('animating', true);
|
||||
|
||||
const target = parseFloat($el.data('target')) || 0;
|
||||
const suffix = $el.data('suffix') || '';
|
||||
const duration = 1500; // 1.5 seconds animation
|
||||
const startTime = performance.now();
|
||||
|
||||
const updateCount = (currentTime) => {
|
||||
const elapsedTime = currentTime - startTime;
|
||||
const progress = Math.min(elapsedTime / duration, 1);
|
||||
|
||||
// easeOutQuad easing function
|
||||
const easeProgress = progress * (2 - progress);
|
||||
|
||||
const currentValue = Math.floor(easeProgress * target);
|
||||
$el.text(this._formatValue(currentValue) + suffix);
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(updateCount);
|
||||
} else {
|
||||
$el.text(this._formatValue(target) + suffix);
|
||||
$el.data('animating', false);
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame(updateCount);
|
||||
});
|
||||
},
|
||||
|
||||
_resetCounters: function () {
|
||||
this.$counters.each((index, el) => {
|
||||
const $el = $(el);
|
||||
const suffix = $el.data('suffix') || '';
|
||||
$el.text('0' + suffix);
|
||||
$el.data('animating', false);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default publicWidget.registry.StatsCounter;
|
||||
@ -3185,3 +3185,7 @@ body.o_edit_mode {
|
||||
box-shadow: 0 5px 15px rgba(255,184,0,0.2) !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
/* Enforce section title font size and weight */
|
||||
section h2.display-4, section h2.display-5, section h2.testi-main-title, section h2.thali-subtitle, section h2 { font-size: 56px !important; font-weight: 400 !important; }
|
||||
|
||||
|
||||
@ -26,9 +26,7 @@
|
||||
<div class="row mb-5">
|
||||
<div class="col-12 text-center">
|
||||
<h6 class="d-flex align-items-center justify-content-center mb-3" style="color: #ffb800; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;">
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/subtitle-icon.png" style="width: 25px; margin-right: 10px;" alt=""/>
|
||||
BLOG
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/subtitle-icon.png" style="width: 25px; margin-left: 10px;" alt=""/>
|
||||
</h6>
|
||||
<h2 class="display-4 fw-bold mb-4" style="color: #04121D; font-size: 48px;">News & Articles</h2>
|
||||
</div>
|
||||
|
||||
@ -30,9 +30,7 @@
|
||||
<div class="pe-lg-5">
|
||||
<!-- Title -->
|
||||
<h6 class="d-flex align-items-center mb-3" style="color: #ffb800; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;">
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/subtitle-icon.png" style="width: 20px; margin-right: 10px;" alt=""/>
|
||||
Shivasakthi
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/subtitle-icon.png" style="width: 20px; margin-left: 10px;" alt=""/>
|
||||
</h6>
|
||||
<h2 class="display-5 fw-bold mb-5" style="color: #04121D;">Frequently Asked Questions</h2>
|
||||
|
||||
|
||||
@ -130,10 +130,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<section class="s_about_premium o_colored_level pt96 pb96" data-snippet="s_about_premium" data-name="Premium About">
|
||||
<!-- Floating Elements -->
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/about-lemon.png" class="floating-lemon d-none d-lg-block" alt=""/>
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/about-leaves.png" class="floating-leaves d-none d-lg-block" alt=""/>
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/about-bellpepper.png" class="floating-bellpepper d-none d-lg-block" alt=""/>
|
||||
<!-- Floating Elements Removed as requested -->
|
||||
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
@ -148,9 +145,7 @@
|
||||
<div class="col-lg-6 ps-lg-5 o_colored_level">
|
||||
<div class="about-content">
|
||||
<h6 class="d-flex align-items-center mb-3" style="color: #ffb800; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;">
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/subtitle-icon.png" style="width: 25px; margin-right: 10px;" alt=""/>
|
||||
Real . authentic . South Indian
|
||||
<img src="/dine360_theme_shivasakthi/static/src/img/subtitle-icon.png" style="width: 25px; margin-left: 10px;" alt=""/>
|
||||
</h6>
|
||||
<h2 class="display-4 fw-bold mb-4" style="color: #04121D; line-height: 1.2;">Welcome to Shiva Sakthi Restaurant</h2>
|
||||
<p class="text-muted mb-5" style="font-size: 16px; line-height: 1.8;">
|
||||
@ -181,19 +176,19 @@
|
||||
<div class="row g-0 overflow-hidden shadow-lg stats-box-row" style="background: transparent;">
|
||||
<!-- Box 1 -->
|
||||
<div class="col-4 text-center py-4 px-2 d-flex flex-column align-items-center justify-content-center" style="background-color: #ffb800; color: #000; min-height: 170px;">
|
||||
<h2 class="fw-bold mb-1" style="font-size: clamp(32px, 4.5vw, 54px); line-height: 1; font-family: 'Bebas Neue', sans-serif !important;">20+</h2>
|
||||
<h2 class="fw-bold mb-1 stat-counter" data-target="20" data-suffix="+" style="font-size: clamp(32px, 4.5vw, 54px); line-height: 1; font-family: 'Bebas Neue', sans-serif !important;">0+</h2>
|
||||
<div class="wavy-line mb-3" style="font-size: 14px; font-weight: bold; color: #000; letter-spacing: -2px;">~~~~</div>
|
||||
<p class="text-uppercase fw-bold mb-0" style="font-size: clamp(10px, 1.2vw, 13px); letter-spacing: 0.5px; font-family: 'Bebas Neue', sans-serif !important;">Experience Chefs</p>
|
||||
</div>
|
||||
<!-- Box 2 -->
|
||||
<div class="col-4 text-center py-4 px-2 d-flex flex-column align-items-center justify-content-center" style="background-color: #1c1c1c; color: #fff; min-height: 170px;">
|
||||
<h2 class="fw-bold mb-1 text-white" style="font-size: clamp(32px, 4.5vw, 54px); line-height: 1; font-family: 'Bebas Neue', sans-serif !important;">2K+</h2>
|
||||
<h2 class="fw-bold mb-1 text-white stat-counter" data-target="2000" data-suffix="+" style="font-size: clamp(32px, 4.5vw, 54px); line-height: 1; font-family: 'Bebas Neue', sans-serif !important;">0+</h2>
|
||||
<div class="wavy-line mb-3" style="font-size: 14px; font-weight: bold; color: #fff; letter-spacing: -2px;">~~~~</div>
|
||||
<p class="text-uppercase fw-bold mb-0 text-white" style="font-size: clamp(10px, 1.2vw, 13px); letter-spacing: 0.5px; font-family: 'Bebas Neue', sans-serif !important;">Happy Customers</p>
|
||||
</div>
|
||||
<!-- Box 3 -->
|
||||
<div class="col-4 text-center py-4 px-2 d-flex flex-column align-items-center justify-content-center" style="background-color: #ffb800; color: #000; min-height: 170px;">
|
||||
<h2 class="fw-bold mb-1" style="font-size: clamp(32px, 4.5vw, 54px); line-height: 1; font-family: 'Bebas Neue', sans-serif !important;">40+</h2>
|
||||
<h2 class="fw-bold mb-1 stat-counter" data-target="40" data-suffix="+" style="font-size: clamp(32px, 4.5vw, 54px); line-height: 1; font-family: 'Bebas Neue', sans-serif !important;">0+</h2>
|
||||
<div class="wavy-line mb-3" style="font-size: 14px; font-weight: bold; color: #000; letter-spacing: -2px;">~~~~</div>
|
||||
<p class="text-uppercase fw-bold mb-0" style="font-size: clamp(10px, 1.2vw, 13px); letter-spacing: 0.5px; font-family: 'Bebas Neue', sans-serif !important;">Favorite Dishes</p>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user