Making new "salony" page

This commit is contained in:
Roman Pyrih
2026-01-28 13:27:14 +01:00
parent cecfe792a7
commit 8c809ab084
4 changed files with 657 additions and 66 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,535 @@
@import 'variables';
@import '_mixins';
html {
scroll-behavior: smooth;
scroll-padding-top: 105px;
}
body {
&.fixed {
overflow: hidden;
}
}
p {
&:last-child {
margin-bottom: 0;
}
}
strong {
font-weight: 700;
}
.main-page {
padding-top: 0px;
padding-bottom: 0;
}
.breadcrumbs {
margin: 14px 0;
}
.box-1 {
background: #f7f6f5;
.box-1--wrapper {
.c-row {
display: flex;
flex-direction: row;
column-gap: 50px;
align-items: center;
justify-content: space-between;
min-height: 390px;
@include respond-below(md) {
flex-direction: column;
padding-top: 50px;
text-align: center;
row-gap: 50px;
}
.c-col {
&-1 {
width: 100%;
max-width: 500px;
.box-title {
margin-bottom: 20px;
h1 {
color: $cTxtBlack;
font-family: $font3;
font-weight: 500;
font-size: 55px;
line-height: 1;
letter-spacing: 2px;
@include respond-below(lg) {
font-size: 40px;
}
}
}
.box-text {
padding-bottom: 25px;
margin-bottom: 40px;
border-bottom: 1px solid #000;
p {
color: $cTxtBlack;
font-family: $font3;
font-weight: 300;
font-size: 30px;
line-height: 1.6;
letter-spacing: 2px;
text-transform: uppercase;
@include respond-below(lg) {
font-size: 24px;
}
}
}
.box-nav {
ol {
display: flex;
flex-direction: row;
align-items: center;
list-style: none;
padding: 0;
margin: 0;
gap: 16px;
li {
width: 100%;
max-width: 241px;
&:nth-child(1) {
a {
background-color: #1e2832;
}
}
&:nth-child(2) {
a {
background-color: #b8aea4;
}
}
a {
display: block;
padding: 18px 13px;
border-radius: 10px;
text-align: center;
@include respond-below(lg) {
padding: 14px 13px;
}
span {
display: inline-block;
color: $cWhite;
font-family: $font3;
font-weight: 700;
font-size: 16px;
line-height: 1.2;
@include respond-below(lg) {
font-size: 14px;
}
}
}
}
}
}
}
&-2 {
.box-img {
width: 100%;
max-width: 700px;
img {
width: 100%;
}
}
}
}
}
}
}
#box-map-showrooms {
display: flex;
height: calc(100svh - 119px);
#showrooms-sidebar {
width: 500px;
min-width: 500px;
background: #fff;
transition: all 300ms ease-in-out;
#showrooms-sidebar--header {
padding: 20px;
#search-showrooms-form {
display: flex;
flex-direction: row;
align-items: center;
background: #f7f6f5;
border-radius: 100px;
#place {
width: 100%;
border: none;
padding: 12px 12px 12px 30px;
color: #1d1d1e;
font-size: 20px;
font-weight: 500;
background: transparent;
outline: none !important;
&::placeholder {
color: #1d1d1e;
}
}
button[type='submit'] {
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 16px 30px 15px;
background: #1e2832;
border-radius: 100px;
border: none !important;
box-shadow: none !important;
outline: none !important;
cursor: pointer;
}
}
}
#results-list {
display: flex;
flex-direction: column;
row-gap: 12px;
padding: 20px;
overflow-y: auto;
overflow-x: hidden;
height: calc(100svh - 119px);
.sidebar-item {
position: relative;
cursor: pointer;
&.active {
.sidebar-item--wrapper {
background: #fff;
border: 1px solid #b4aaa2;
box-shadow: -2px 2px 4.6px #b4aaa2;
}
}
.sidebar-item--wrapper {
display: grid;
grid-template-columns: 200px 1fr;
gap: 16px 32px;
padding: 24px;
// border: 1px solid #b4aaa2;
border-radius: 10px;
width: 100%;
background: #f7f6f5;
transition: all 250ms ease-in-out;
border: 1px solid #f7f6f5;
.item-type {
&.sales {
span {
background: #1e2832;
}
}
&.partner {
span {
background: #b4aaa2;
}
}
span {
display: inline-flex;
padding: 8px 22px 7px;
color: $cWhite;
font-family: $font3;
font-style: normal;
font-weight: 700;
font-size: 16px;
line-height: 1;
border-radius: 100px;
}
}
.item-location {
display: inline-block;
border-left: 5px solid #1e2832;
padding-left: 14px;
height: fit-content;
> strong {
font-size: 17px;
}
p {
color: #1d1d1e;
font-size: 16px;
font-family: $font3;
}
}
.item-working-hours {
p {
color: #1d1d1e;
font-size: 16px;
line-height: 1.5;
font-family: $font3;
}
}
.item-contact {
ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
row-gap: 6px;
li {
display: flex;
flex-direction: row;
align-content: center;
column-gap: 6px;
a {
color: #1d1d1e;
font-size: 16px;
line-height: 1.5;
font-family: $font3;
}
}
}
}
}
}
}
}
#showrooms-data-box {
position: relative;
display: flex;
width: 100%;
height: 100%;
#showroom-popup.showroom-card--popup {
visibility: hidden;
opacity: 0;
transition: all 50ms ease-in-out;
position: absolute;
z-index: 1;
// left: calc(50% + 250px);
left: 30px;
top: 50%;
transform: translateY(-50%);
&.active {
visibility: visible;
opacity: 1;
}
.showroom-card--popup-wrapper {
width: 650px;
// margin-top: 120px;
background: $cWhite;
border-radius: 30px;
display: flex;
flex-direction: column;
overflow: hidden;
.popup--head {
display: flex;
flex-direction: row;
padding: 40px 60px 35px 60px;
&[data-type='sales'] {
background: #1e2832;
}
&[data-type='partner'] {
background: #b6aca3;
}
p {
color: $cWhite;
font-family: $font3;
font-weight: 600;
font-size: 20px;
line-height: 1;
margin: 0;
position: relative;
&.text {
padding-right: 25px;
margin-right: 25px;
&::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 3px;
width: 1px;
background: $cWhite;
}
}
}
.close-popup {
cursor: pointer;
margin: 0 0 0 auto;
width: 20px;
height: 20px;
color: #fff;
font-size: 35px;
line-height: 0.7;
}
}
.popup--body {
.popup--body-info {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 30px;
padding: 20px;
p,
a {
color: $cTxtBlack;
font-family: $font3;
font-weight: 400;
font-size: 16px;
line-height: 1.5;
strong {
font-weight: 700;
}
}
.info-name {
padding-left: 11px;
border-left: 5px solid #000;
height: fit-content;
p {
}
}
.info-time {
}
.info-products {
padding-left: 15px;
> p {
color: $cTxtBlack;
font-family: $font3;
font-weight: 700;
font-size: 16px;
line-height: 1;
margin-bottom: 20px;
}
ul {
padding: 0;
margin: 0;
list-style: none;
display: flex;
flex-direction: row;
column-gap: 30px;
max-width: 180px;
align-items: center;
li {
display: flex;
flex-direction: column;
align-items: center;
row-gap: 12px;
width: calc(100% / 3 - (30px - (30px / 3)));
p {
color: $cTxtBlack;
font-family: $font3;
font-weight: 600;
font-size: 8px;
line-height: 1;
text-transform: uppercase;
margin: 0;
}
img {
max-height: 30px;
}
}
}
}
.info-contact {
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
row-gap: 6px;
li {
display: flex;
flex-direction: row;
align-content: center;
column-gap: 6px;
a {
color: #1d1d1e;
font-family: $font3;
font-size: 16px;
line-height: 1.5;
}
}
}
.showroom-contact-btn {
color: #1e2832;
font-family: $font3;
font-size: 10px;
font-weight: 700;
padding: 13px 16px 10px;
margin: 10px 0 0 auto;
width: fit-content;
background: #ffed00;
box-shadow: 0px 4px 4px #e9e3de;
border-radius: 10px;
}
}
}
.popup--body-footer {
.popup--body-footer--baner {
padding: 0 20px 20px 20px;
img {
border-radius: 10px;
width: 100%;
}
}
}
}
}
}
}
}

View File

@@ -3,31 +3,46 @@
?>
<div class="main-page" id="places-contact-maps">
<section class="box-1" id="box-map-showrooms" style="position: relative; display: flex; height: 700px;">
<section class="box-1" id="box-map-showrooms">
<div id="showrooms-sidebar">
<div id="results-list">
<!-- <p>Wpisz miasto</p> -->
<div id="showrooms-sidebar--header">
<form id="search-showrooms-form">
<input type="text" id="place" placeholder="wpisz miejscowość" />
<button type="submit">FILTRUJ</button>
</form>
</div>
<div id="showrooms-sidebar--body">
<div id="results-list"></div>
</div>
</div>
<div id="map" style="flex-grow: 1; height: 100%;"></div>
<div id="showrooms-data-box">
<div id="map" style="flex-grow: 1; height: 100%;"></div>
<div id="showroom-popup" class="showroom-card--popup">
<div class="showroom-card--popup-wrapper">
<div class="popup--head">
<p class="text">PUNKT SPRZEDAŻY</p>
<p>VIDOK Okna i Drzwi</p>
<span class="close-popup">&times;</span>
</div>
<div class="popup--body">
<div class="popup--body-info">
<div class="info-name"><p></p></div>
<div class="info-time"><p></p></div>
<div class="info-products">
<p>Dostępne produkty</p>
<img src="" alt="">
<div id="showroom-popup" class="showroom-card--popup">
<div class="showroom-card--popup-wrapper">
<div class="popup--head">
<p class="text">PUNKT SPRZEDAŻY</p>
<p>VIDOK Okna i Drzwi</p>
<span class="close-popup">&times;</span>
</div>
<div class="popup--body">
<div class="popup--body-info">
<div class="info-name"><p></p></div>
<div class="info-time">
<strong>Godziny otwarcia</strong><br/>
<div class="info-time--data"></div>
</div>
<div class="info-products">
<p>Dostępne produkty</p>
<ul>
</ul>
</div>
<div class="info-contact"></div>
</div>
<div class="popup--body-footer">
</div>
<div class="info-contact"><p></p></div>
</div>
</div>
</div>
@@ -48,13 +63,16 @@
/**
* Fetch showroom data from API
*/
fetch('/api/kontakt-mapa')
const showroomsPromise = fetch('/api/kontakt-mapa')
.then(response => response.json())
.then(data => {
showrooms = data.data;
showrooms = (data && data.data) ? data.data : [];
return showrooms;
})
.catch(error => {
console.error('Error fetching showroom data:', error);
showrooms = [];
return showrooms;
});
@@ -72,27 +90,29 @@
map = new google.maps.Map(document.getElementById("map"), mapOptions);
// Utworzenie markerów dla wszystkich salonów
renderMarkers();
showroomsPromise.then(() => {
// Utworzenie markerów dla wszystkich salonów
renderMarkers();
// Inicjalizacja klastrów (grupowanie markerów)
if (typeof markerClusterer !== 'undefined') {
markerCluster = new markerClusterer.MarkerClusterer({ map, markers });
}
// Inicjalizacja klastrów (grupowanie markerów)
if (typeof markerClusterer !== 'undefined') {
markerCluster = new markerClusterer.MarkerClusterer({ map, markers });
}
// Inicjalizacja wyszukiwarki
initSearchLogic();
// Inicjalizacja wyszukiwarki
initSearchLogic();
});
}
/**
* Renderowanie markerów na mapie
*/
function renderMarkers() {
console.log(showrooms);
if (markerCluster) markerCluster.clearMarkers();
markers.forEach(m => m.setMap(null));
markers = [];
markers = showrooms.map((item) => {
console.log('item: ', item);
const marker = new google.maps.Marker({
position: { lat: parseFloat(item.position.lat), lng: parseFloat(item.position.lng) },
title: item.city,
@@ -149,7 +169,7 @@
function handleLocationSelection(location) {
map.setCenter(location);
map.setZoom(11);
updateSidebarList(location);
scrollToMap();
}
@@ -165,7 +185,7 @@
// 1. Czyszczenie kontenera
$resultsContainer.empty();
$('#results-list').parent().addClass('has-results');
// 2. Filtrowanie i obliczanie dystansu
let filtered = showrooms
.map(item => ({
@@ -173,7 +193,14 @@
distance: calculateDistance(searchLat, searchLng, item.position.lat, item.position.lng)
}))
.filter(item => item.distance <= MAX_DISTANCE_KM)
.sort((a, b) => a.distance - b.distance);
.sort((a, b) => {
const aIsSales = a.salon_type === 'sales' ? 0 : 1;
const bIsSales = b.salon_type === 'sales' ? 0 : 1;
if (aIsSales !== bIsSales) return aIsSales - bIsSales;
return a.distance - b.distance;
});
// 3. Sprawdzenie wyników
if (filtered.length === 0) {
@@ -196,42 +223,48 @@
const lng = item.position.lng;
const distance = item.distance.toFixed(1);
const itemType = 'SALON SPRZEDAŻY';
const itemType = item.salon_type;
let itemTypeText = '';
console.log('item: ', item);
const $el = `
switch (itemType) {
case 'sales':
itemTypeText = 'SALON SPRZEDAŻY';
break;
case 'partner':
itemTypeText = 'SALON PARTNERSKI';
break;
}
const $el = $(`
<div class="sidebar-item" data-lat="${lat}" data-lng="${lng}">
<div class="sidebar-item--wrapper">
<div class="item-type"><span>${itemType}<\/span><\/div>
<div class="item-type ${itemType}"><span>${itemTypeText}<\/span><\/div>
<div class="item-working-hours">
<p>
${item.data_popup.time}
<\/p>
<strong>Godziny otwarcia:<\/strong><br/>
${item.opening_hours}
<\/div>
<div class="item-location">
<p>
${item.data.text}
<\/p>
<strong>${item.salon_name}<\/strong><br/>
${item.address}
<\/div>
<div class="item-contact">
<ul>
${renderContacts(item)}
<\/ul>
${renderContacts(item.contact)}
<\/div>
<\/div>
<\/div>
`;
`);
$el.on('click', () => openShowroomPopup(item));
return $el;
}
function renderContacts(item) {
if (item.contact) {
let html = '';
if (item) {
let html = '<ul>';
if (Array.isArray(item.contact.phone)) {
item.contact.phone.forEach(phone => {
if (Array.isArray(item.phones)) {
item.phones.forEach(phone => {
html += `
<li>
<img src="/upload/filemanager/icon/iphone.svg" alt="">
@@ -241,8 +274,8 @@
});
}
if (Array.isArray(item.contact.email)) {
item.contact.email.forEach(email => {
if (Array.isArray(item.emails)) {
item.emails.forEach(email => {
html += `
<li>
<img src="/upload/filemanager/icon/envelope.svg" alt="">
@@ -252,6 +285,7 @@
});
}
html += '</ul>';
return html;
}
@@ -278,11 +312,35 @@
*/
function openShowroomPopup(item) {
const $popup = $('#showroom-popup');
$popup.find('.info-name p').html(item.data_popup.text);
$popup.find('.info-time p').html(item.data_popup.time);
$popup.find('.info-contact p').html(item.data_popup.contact);
$popup.find('.info-products img').attr('src', item.data_popup.products);
// $popup.fadeIn();
let itemType = item.salon_type;
let itemTypeText = '';
switch (itemType) {
case 'sales':
itemTypeText = 'SALON SPRZEDAŻY';
break;
case 'partner':
itemTypeText = 'SALON PARTNERSKI';
break;
}
console.log('item: ', item);
$popup.find('.popup--head').attr('data-type', itemType);
$popup.find('.popup--head p.text').html(itemTypeText);
$popup.find('.info-name').html(`<strong>${item.salon_name}<\/strong><br/>${item.address}`);
$popup.find('.info-time .info-time--data').html(item.opening_hours);
$popup.find('.info-contact').html(`
${renderContacts(item.contact)}
${item.button.url ? `<a href="${item.button.url}" class="showroom-contact-btn">${item.button.label || 'SKONTAKTUJ SIĘ Z NAMI'}</a>` : ''}
`);
$popup.find('.info-products ul').html(
item.products.map(product => `<li>${product.name}<img src="/${product.icon}"></li>`)
);
$popup.find('.popup--body-footer').empty().html(`
<div class="popup--body-footer--baner">
<img src="${item.banner_image}">
<\/div>
`);
$popup.addClass('active');
}
@@ -320,10 +378,6 @@
* Uruchomienie po załadowaniu DOM
*/
$(document).ready(function() {
if (typeof google !== 'undefined') {
initMap();
}
$(document).on('click', '.close-popup', function() {
// $('#showroom-popup').fadeOut();
$('#showroom-popup').removeClass('active');