132 lines
4.3 KiB
PHP
132 lines
4.3 KiB
PHP
// --- Language Apply Script ---
|
|
function applyLanguage(node) {
|
|
const docLang = document.documentElement.lang || 'ar';
|
|
const targetAttr = docLang === 'ar' ? 'data-ar' : 'data-en';
|
|
|
|
let elements = [];
|
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
if (node.hasAttribute(targetAttr)) {
|
|
elements.push(node);
|
|
}
|
|
node.querySelectorAll('[' + targetAttr + ']').forEach(el => elements.push(el));
|
|
}
|
|
|
|
elements.forEach(el => {
|
|
const text = el.getAttribute(targetAttr);
|
|
if (!text) return;
|
|
|
|
if (el.hasAttribute('placeholder')) {
|
|
el.setAttribute('placeholder', text);
|
|
}
|
|
if (el.hasAttribute('title')) {
|
|
el.setAttribute('title', text);
|
|
}
|
|
|
|
let textNodes = [];
|
|
el.childNodes.forEach(child => {
|
|
if (child.nodeType === Node.TEXT_NODE && child.nodeValue.trim() !== '') {
|
|
textNodes.push(child);
|
|
}
|
|
});
|
|
|
|
if (textNodes.length > 0) {
|
|
textNodes[0].nodeValue = text;
|
|
for (let i = 1; i < textNodes.length; i++) {
|
|
textNodes[i].nodeValue = '';
|
|
}
|
|
} else if (el.children.length === 1 && ['STRONG', 'B', 'SPAN', 'SMALL'].includes(el.children[0].tagName)) {
|
|
el.children[0].textContent = text;
|
|
} else if (el.children.length === 0) {
|
|
el.textContent = text;
|
|
}
|
|
});
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
applyLanguage(document.body);
|
|
|
|
const observer = new MutationObserver(mutations => {
|
|
mutations.forEach(mutation => {
|
|
mutation.addedNodes.forEach(node => {
|
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
applyLanguage(node);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
});
|
|
// -----------------------------
|
|
<?php if ($page === 'dashboard' && can('dashboard_view')): ?>
|
|
const normalizeSalesSeries = (series) => Array.isArray(series)
|
|
? series.map(point => ({
|
|
label: String(point.label ?? ''),
|
|
total: Number(point.total ?? 0)
|
|
}))
|
|
: [];
|
|
|
|
const monthlyData = normalizeSalesSeries(<?= json_encode($data['monthly_sales']) ?>);
|
|
const yearlyData = normalizeSalesSeries(<?= json_encode($data['yearly_sales']) ?>);
|
|
const salesChartCanvas = document.getElementById('salesChart');
|
|
const salesChartEmptyState = document.getElementById('salesChartEmptyState');
|
|
|
|
if (salesChartCanvas) {
|
|
const ctx = salesChartCanvas.getContext('2d');
|
|
let salesChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: monthlyData.map(d => d.label),
|
|
datasets: [{
|
|
label: 'Sales (OMR)',
|
|
data: monthlyData.map(d => d.total),
|
|
borderColor: '#0d6efd',
|
|
backgroundColor: 'rgba(13, 110, 253, 0.1)',
|
|
fill: true,
|
|
tension: 0.4
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: { display: false }
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: {
|
|
callback: function(value) {
|
|
return 'OMR ' + Number(value).toFixed(3);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
const renderSalesSeries = (series) => {
|
|
salesChart.data.labels = series.map(d => d.label);
|
|
salesChart.data.datasets[0].data = series.map(d => d.total);
|
|
salesChart.update();
|
|
|
|
if (salesChartEmptyState) {
|
|
salesChartEmptyState.classList.toggle('d-none', series.length > 0);
|
|
}
|
|
};
|
|
|
|
renderSalesSeries(monthlyData);
|
|
|
|
document.getElementById('btnMonthly')?.addEventListener('click', function() {
|
|
this.classList.add('active');
|
|
document.getElementById('btnYearly')?.classList.remove('active');
|
|
renderSalesSeries(monthlyData);
|
|
});
|
|
|
|
document.getElementById('btnYearly')?.addEventListener('click', function() {
|
|
this.classList.add('active');
|
|
document.getElementById('btnMonthly')?.classList.remove('active');
|
|
renderSalesSeries(yearlyData);
|
|
});
|
|
}
|
|
<?php endif; ?>
|