<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="ventes en ligne, rapeto service, madagascar">
<title>{% block title %} Dashboard Templates !{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css">
{# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #}
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.0/css/all.min.css">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<style>
/* Dans votre fichier CSS */
.logo-overlay {
position: absolute;
top: 0;
right: 0;
width: 50%; /* Ajustez la largeur du logo selon vos besoins */
height: auto;
pointer-events: none;
z-index: 10;
}
/* S'assurer que le wrapper a position: relative */
.image-wrapper {
position: relative !important;
display: inline-block; /* ou selon votre layout */
}
/**/
.mega-dropdown {
position: fixed; /* 👈 important */
left: 50%;
transform: translateX(-26%);
/*width: 1200px;*/
max-width: 95vw;
max-height: 60vh; /* 60% of viewport height */
overflow-y: auto; /* scroll if content exceeds max-height */
background: #fff;
border-radius: 15px;
box-shadow: 0 15px 40px rgba(0,0,0,0.08);
z-index: 9999;
padding-top: 40px;
}
/**/
.category-header {
padding: 10px 14px;
background: #f8f9fa;
border-radius: 10px;
}
.category-title {
font-size: 0.95rem;
font-weight: 600;
letter-spacing: 0.3px;
text-transform: capitalize; /* backup capitalization */
}
.view-all {
color: #0d6efd;
transition: 0.2s ease;
}
.view-all:hover {
opacity: 0.7;
}
.divider {
height: 1px;
background: linear-gradient(to right, #e9ecef, transparent);
}
/* Add smooth appearance */
.mega-dropdown.show {
animation: fadeDown 0.25s ease;
}
@keyframes fadeDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.product-item {
cursor: pointer;
transition: transform 0.2s ease;
}
.product-item:hover {
transform: translateY(-3px);
}
.product-img-wrapper {
background: #f8f9fa;
padding: 8px;
border-radius: 8px;
}
.product-item img {
width: 100%;
height: 100px;
object-fit: contain;
}
</style>
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</head>
<body id="page-top">
{% block body %}{% endblock %}
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- Select2 JS -->
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script>
<script>
$(document).ready(function() {
$('.select2').select2({
placeholder: "Choisir un ou plusieurs services",
allowClear: true,
});
});
</script>
{# <script>
$(document).ready(function () {
$('.datatable').DataTable({
pageLength: 25,
ordering: true,
searching: true,
info: true,
language: {
url: "//cdn.datatables.net/plug-ins/1.13.8/i18n/fr-FR.json"
},
});
});
</script> #}
<script>
$(document).ready(function () {
$('.datatable').DataTable({
pageLength: 25,
ordering: true,
searching: true,
info: true,
language: {
decimal: ',',
thousands: ' ',
emptyTable: 'Aucune donnée disponible',
info: 'Affichage de _START_ à _END_ sur _TOTAL_ entrées',
infoEmpty: 'Affichage de 0 à 0 sur 0 entrée',
infoFiltered: '(filtré depuis _MAX_ entrées au total)',
lengthMenu: 'Afficher _MENU_ entrées',
loadingRecords: 'Chargement...',
processing: 'Traitement...',
search: 'Rechercher :',
zeroRecords: 'Aucun enregistrement correspondant trouvé',
paginate: {
first: 'Premier',
last: 'Dernier',
next: 'Suivant',
previous: 'Précédent'
}
}
});
});
</script>
<script>
document.querySelectorAll('.product-link').forEach(link => {
link.addEventListener('click', function () {
const url = this.dataset.clickUrl;
if (navigator.sendBeacon) {
navigator.sendBeacon(url);
} else {
fetch(url, { method: 'POST', keepalive: true });
}
});
});
const logoSrc = '/img/logo-rapeto-img.png';
function addLogoToProductImages() {
document.querySelectorAll(".image-wrapper").forEach(wrapper => {
// Maka ny sary produit
const productImg = wrapper.querySelector("img");
// Raha tsy misy sary, dia tsy mamorona logo
if (!productImg) return;
// Raha efa misy logo, tsy mamorona indray
if (wrapper.querySelector(".logo-overlay")) return;
// Mamorona logo
const logo = document.createElement("img");
logo.src = logoSrc;
logo.alt = "Logo";
logo.className = "logo-overlay";
wrapper.appendChild(logo);
});
}
// Alefa rehefa loaded ny DOM
document.addEventListener("DOMContentLoaded", addLogoToProductImages);
</script>
<script>
const productClickBaseUrl = "{{ path('app_product_click_search', {'id': 'PRODUCT_ID'}) }}";
const productShowBaseUrl = "{{ path('app_product_show', {'id': 'PRODUCT_ID'}) }}";
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
const input = document.getElementById("search-input");
const suggestionsBox = document.getElementById("search-suggestions");
const suggestionsBoxResults = document.getElementById("search-suggestions-results");
input.addEventListener("focus", function () {
if (this.value.length >= 2) return;
fetch("{{ path('ajax_random_products') }}")
.then(response => response.json())
.then(data => {
const categoryContainer = document.getElementById("categoryResults");
categoryContainer.innerHTML = "";
if (!data || data.length === 0) {
categoryContainer.innerHTML = `
<div class="text-center text-muted py-4">
Aucun produit disponible.
</div>
`;
}
(data || []).forEach(group => {
let block = document.createElement("div");
block.classList.add("mb-4");
// block.innerHTML = `
// <div class="d-flex justify-content-between align-items-center mb-2">
// <div class="fw-bold">${group.categoryName.charAt(0).toUpperCase() + group.categoryName.slice(1)}</div>
// <a href="#" class="small text-primary"></a>
// </div>
// <div class="row g-3" id="cat-${group.categoryId}"></div>
// `;
block.innerHTML = `
<div class="category-header d-flex justify-content-between align-items-center mb-3">
<h6 class="category-title mb-0">
${group.categoryName
? group.categoryName.charAt(0).toUpperCase() + group.categoryName.slice(1)
: ''}
</h6>
<a href="#" class="small text-decoration-none fw-semibold view-all"></a>
</div>
<div class="divider mb-3"></div>
<div class="row g-3" id="cat-${group.categoryId}"></div>
`;
categoryContainer.appendChild(block);
let row = block.querySelector(`#cat-${group.categoryId}`);
group.products.slice(0, 4).forEach(product => {
let col = document.createElement("div");
// col.classList.add("col-3");
col.classList.add("col-6", "col-md-4", "col-lg-3");
col.innerHTML = `
<div class="product-item">
<img src="/uploads/products/${product.image}">
<div class="small mt-2">${product.title}</div>
</div>
`;
col.querySelector(".product-item").addEventListener("click", function (e) {
e.preventDefault();
let clickUrl = productClickBaseUrl.replace('PRODUCT_ID', product.id);
let showUrl = productShowBaseUrl.replace('PRODUCT_ID', product.id);
fetch(clickUrl + "?fromSearch=1", {
method: "POST",
headers: {
"X-Requested-With": "XMLHttpRequest"
}
})
.then(() => {
window.location.href = showUrl;
});
});
row.appendChild(col);
});
});
// suggestionsBox.style.display = "block";
suggestionsBox.style.display = "block";
suggestionsBox.classList.add("show");
});
});
input.addEventListener("keyup", function () {
let query = this.value;
if (query.length < 2) {
suggestionsBox.style.display = "none";
return;
}
fetch("{{ path('ajax_search') }}?q=" + query)
.then(response => response.json())
.then(data => {
suggestionsBoxResults.innerHTML = "";
if (data.length === 0) {
suggestionsBoxResults.innerHTML = `
<div class="list-group-item text-muted">
Aucun produit trouvé.
</div>
`;
suggestionsBoxResults.style.display = "block";
return;
}
data.forEach(product => {
let item = document.createElement("a");
item.href = "#"; // prevent default link behavior
item.classList.add("list-group-item", "list-group-item-action");
item.innerHTML = `
<div class="d-flex align-items-center">
<img src="{{ asset('uploads/products/') }}${product.image}"
width="40"
height="40"
class="me-2 rounded">
<div>
<div>${product.title}</div>
</div>
</div>
`;
item.addEventListener("click", function (e) {
e.preventDefault();
let clickUrl = productClickBaseUrl.replace('PRODUCT_ID', product.id);
let showUrl = productShowBaseUrl.replace('PRODUCT_ID', product.id);
fetch(clickUrl + "?fromSearch=1", {
method: "POST",
headers: {
"X-Requested-With": "XMLHttpRequest"
}
})
.then(() => {
window.location.href = showUrl;
});
});
suggestionsBoxResults.appendChild(item);
});
suggestionsBoxResults.style.display = "block";
});
});
// Hide when clicking outside
// document.addEventListener("click", function (e) {
// if (!input.contains(e.target)) {
// suggestionsBox.style.display = "none";
// }
// });
document.addEventListener("click", function (e) {
if (!input.contains(e.target) && !suggestionsBox.contains(e.target)) {
suggestionsBox.style.display = "none";
}
});
// document.addEventListener("click", function (e) {
// if (!input.contains(e.target) && !suggestionsBoxResults.contains(e.target)) {
// suggestionsBoxResults.style.display = "none";
// }
// });
});
</script>
</body>
</html>