{# <div id="recommendationsDebug">
{!#<div id="queryData" style="display: none;"></div><a href="javascript:void(0);" id="showQueryBtn">Показать запрос</a>#!}
<div id="profileViewsData">
<h6 style="color: #1ea471">Просмотры анкет на сайте</h6>
{% set profile_debug_data = profile_recommendations_debug_views() %}
{% include "Recommendations/_profile_recommendations_debug_profile_data_table.html.twig" %}
</div>
<div id="favouritesData">
<h6 style="color: #0d5aa7">Избранные</h6>
{% set profile_debug_data = profile_recommendations_debug_favourites() %}
{% include "Recommendations/_profile_recommendations_debug_profile_data_table.html.twig" %}
</div>
{% include "Recommendations/_profile_recommendations_debug_coeffs_data_table.html.twig" %}
<h6 style="color: #bd2130">Коэффициенты</h6>
<div id="coeffsData"></div>
{% include "Recommendations/_profile_recommendations_debug_viewed_profiles_data_table.html.twig" %}
<h6 style="color: #856404">Просмотренные рекомендации</h6>
<div id="viewedRecommendationsData"></div>
</div> #}
<div class="recommendation{{ componentClass is defined ? ' ' ~ componentClass : '' }} mb-4" id="profileRecommendations">
<div class="recommendation-heading d-flex-c">
<h2 class="text-xxl">РЕКОМЕНДОВАННЫЕ АНКЕТЫ</h2>
</div>
<div class="recommendation-container">
<div class="recommendation-list d-grid " id="profileRecommendationsContainer">
{% for i in 1..6 %}
<div class="recommendation-item recommendation-item--skeleton d-flex ">
<div class="card__avatar skeleton"></div>
<div class="recommendation-info d-flex">
<div class="recommendation-name skeleton"></div>
<div class="recommendation-station skeleton"></div>
<div class="recommendation-price skeleton"> </div>
{# <div class="recommendation-phone btn btn-fluid skeleton"> </div> #}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var showMorePressCount = 0;
const sortLines = (data) => {
{#// Инициализация объекта для хранения станций в соответствии с их типом#}
const sortedStations = data.reduce((acc, station) => {
if (station.name.startsWith('МЦД-')) {
acc.mcd.push(station);
} else if (station.name === 'МЦК') {
acc.mck.push(station);
} else {
acc.ordinary.push(station);
}
return acc;
}, { ordinary: [], mcd: [], mck: [] });
{#// Сортировка станций МЦД по номеру#}
sortedStations.mcd.sort((a, b) => {
const numA = parseInt(a.name.split('МЦД-')[1]);
const numB = parseInt(b.name.split('МЦД-')[1]);
return numA - numB;
});
{#// Объединение отсортированных станций#}
const result = [
...sortedStations.ordinary,
...sortedStations.mcd,
...sortedStations.mck
];
return result;
};
const iconMetroSingle = ({color, iconId, width = '18'}) => {
return `<svg class="metro-icon" width="${width}" height="18">
<use style="fill:#${color}" class="icon-container--element" xlink:href="#${iconId}"></use>
</svg>`
};
const iconMetroDouble = ({color1, color2}) => `
<svg class="metro-icon" width="17" height="16" fill="none">
<path fill="#8E8E8E" d="M3.7 8.83h-.77v1.04h3.94V8.83H5.7l.76-2.59L8.5 9.96l2.03-3.72.76 2.6h-1.16v1.03h3.94V8.83h-.78L10.7 2 8.5 6.51 6.3 2 3.7 8.83Z"/>
<rect width="7" height="3" x=".5" y="11.02" fill="#${color1}" rx="1.5"/>
<rect width="7" height="3" x="9.5" y="11" fill="#${color2}" rx="1.5"/>
</svg>`;
const iconMetroTriple = ({color1, color2, color3}) => `<svg class="metro-icon" width="17" height="16" fill="none">
<path fill="#8E8E8E" d="M3.7 8.83h-.77v1.04h3.94V8.83H5.7l.76-2.59L8.5 9.96l2.03-3.72.76 2.6h-1.16v1.03h3.94V8.83h-.78L10.7 2 8.5 6.51 6.3 2 3.7 8.83Z"/>
<rect width="4" height="3" x=".5" y="11.02" fill="#${color1}" rx="1.5"/>
<rect width="4" height="3" x="6.5" y="11.02" fill="#${color2}" rx="1.5"/>
<path fill="#${color3}" d="M12.5 12.5c0-.83.67-1.5 1.5-1.5h1a1.5 1.5 0 0 1 0 3h-1a1.5 1.5 0 0 1-1.5-1.5Z"/>
</svg>`;
const getAllData = (s) => [s.color, s.name];
const getIconId = (name) => name.toLowerCase().includes('мцк') ? 'mck' : (name.toLowerCase().includes('мцд') ? 'mcd-' + name.split('-')[1] : 'metro');
const getIconWidth = (name) => name.toLowerCase().includes('мцд') ? '22' : '16';
const wrapperIcon = (str) => `<span class="metro-icons d-flex-c">${str}</span>`;
const wrapperLink = (html, _name) => `<a class="modal-list__icons d-flex" href="${window.siteData.stations[_name]}">${html}</a>`;
function iconGen2({name, dataLines}) {
{#//for test#}
const root = document.getElementById('icon-test-gen2');
const lines = sortLines(dataLines);
const count = lines.length;
{#// Если линия 1шт#}
if (count === 1){
// Получаем данные по цветам и названиям линии
const [color, line_name] = getAllData(lines[0]);
{#// Иконка может быть обычным метро, мцд с номером или мцк#}
const iconId = getIconId(line_name);
const width = getIconWidth(line_name);
return wrapperLink(wrapperIcon(iconMetroSingle({color, iconId, width})+ name), name);
{#//return wrapperIcon(iconMetroSingle({color, iconId, width}));#}
} else if (count === 2) {
const [[color1, name1], [color2, name2]] = lines.map(getAllData);
const iconId1 = getIconId(name1);
const iconId2 = getIconId(name2);
{#// Если обе иконки это метро#}
if (iconId1 === 'metro' && iconId2 === 'metro') {
return wrapperLink(wrapperIcon(`${iconMetroDouble({color1, color2})} ${name}`), name);
} else {
const width1 = getIconWidth(name1);
const width2 = getIconWidth(name2);
return wrapperLink(wrapperIcon(`${iconMetroSingle({ color: color1, iconId: iconId1, width: width1 })}${iconMetroSingle({ color: color2, iconId: iconId2, width: width2 })} ${name}`), name);
}
} else if (count === 3) {
const [[color1, name1], [color2, name2], [color3, name3]] = lines.map(getAllData);
const iconId1 = getIconId(name1);
const iconId2 = getIconId(name2);
const iconId3 = getIconId(name3);
if (iconId1 === 'metro' && iconId2 === 'metro' && iconId3 === 'metro') {
return wrapperLink(wrapperIcon(`${iconMetroTriple({color1, color2, color3})} ${name}`), name);
} else if (iconId1 === 'metro' && iconId2 === 'metro') {
const width3 = getIconWidth(name3);
return wrapperLink(wrapperIcon(`${iconMetroDouble({color1, color2})}${iconMetroSingle({ color: color3, iconId: iconId3, width: width3 })} ${name}`), name);
} else {
const width1 = getIconWidth(name1);
const width2 = getIconWidth(name2);
const width3 = getIconWidth(name3);
return wrapperLink(wrapperIcon(`${iconMetroSingle({ color: color1, iconId: iconId1, width: width1 })}${iconMetroSingle({ color: color2, iconId: iconId2, width: width2 })}${iconMetroSingle({ color: color3, iconId: iconId3, width: width3 })} ${name}`), name);
}
} else if (count === 4) {
const [[color1, name1], [color2, name2], [color3, name3], [color4, name4]] = lines.map(getAllData);
const iconId1 = getIconId(name1);
const iconId2 = getIconId(name2);
const iconId3 = getIconId(name3);
const iconId4 = getIconId(name4);
if (iconId1 === 'metro' && iconId2 === 'metro' && iconId3 === 'metro') {
const width4 = getIconWidth(name4);
return wrapperLink(wrapperIcon(`${iconMetroTriple({color1, color2, color3})}${iconMetroSingle({ color: color4, iconId: iconId4, width: width4 })} ${name}`), name);
} else if (iconId1 === 'metro' && iconId2 === 'metro') {
const width3 = getIconWidth(name3);
const width4 = getIconWidth(name4);
return wrapperLink(wrapperIcon(`${iconMetroDouble({color1, color2})}${iconMetroSingle({ color: color3, iconId: iconId3, width: width3 })}${iconMetroSingle({ color: color4, iconId: iconId4, width: width4 })} ${name}`), name);
} else {
const width1 = getIconWidth(name1);
const width2 = getIconWidth(name2);
const width3 = getIconWidth(name3);
const width4 = getIconWidth(name4);
return wrapperLink(wrapperIcon(`${iconMetroSingle({ color: color1, iconId: iconId1, width: width1 })}${iconMetroSingle({ color: color2, iconId: iconId2, width: width2 })}${iconMetroSingle({ color: color3, iconId: iconId3, width: width3 })}${iconMetroSingle({ color: color4, iconId: iconId4, width: width4 })} ${name}`), name);
}
}
return wrapperLink(name,name);
}
function generateTagList(hasApartPrice, hasTakeoutPricing, services) {
let tags = [];
if (hasApartPrice && !hasTakeoutPricing) {
tags.push('Апарты');
}
if (!hasApartPrice && hasTakeoutPricing) {
tags.push('Выезд');
}
if (hasApartPrice && hasTakeoutPricing) {
tags.push('Апарты и выезд');
}
services.forEach((service, i) => {
switch (service.name.ru.toLowerCase()) {
case 'секс классический':
tags.push('Классика');
break;
case 'секс анальный':
tags.push('Анал');
break;
case 'минет без резинки':
tags.push('МБР');
break;
case 'куннилингус':
tags.push('Куни');
break;
case 'окончание в рот':
tags.push('ОВР');
break;
case 'массаж':
tags.push('Массаж');
break;
}
if (service.name.ru.includes('Массаж') && !tags.includes('Массаж')) {
tags.push('Массаж');
}
});
let tagsHtml = tags.length > 0 ? '<div class="profile-card__tags d-flex">' : '';
tags.forEach((service, i) => {
tagsHtml += `<div class="profile-card__tags-item clr-main-text">${service}</div>`
});
tagsHtml += tags.length > 0 ? '</div>' : '';
return tagsHtml;
}
function fetchRecommendations() {
{% set gender = 'profile_list.list_by_gender' in app.request.get('_route') ? app.request.get('gender')|gender_value_by_uri : gender_female() %}
let url = '{{ path('recommendations.get', {city:app.request.get('city').uriIdentity, count: 6, imageSize: '357x500', exclude: (excludeRecommendationProfileIds is iterable ? excludeRecommendationProfileIds : [])|join(','), gender: gender }) }}';
let filter = JSON.parse('{{ recommendationSpec is defined and recommendationSpec ? recommendationSpec.spec.toEsQueryObject|json_encode|raw : {}|json_encode|raw }}');
const profileContainer = document.getElementById('profileRecommendations');
window.Recommendation.updateSettings({
rootId: 'profileRecommendations',
url,
filter,
callback: (response) => {
let template = '';
const container = document.getElementById('profileRecommendationsContainer');
container.innerHTML = '';
response.profiles.forEach(function(profile) {
const {station, price, phone, name, age, id, image, has_comments, has_selfie, has_video, height, breast_size, weight, description, services} = profile;
let metroHtml = '';
if (station) {
metroHtml = `<div class="profile-card__bio">
<div class="profile-card__metro">
<div class="card__metro-link metro-link">
<span class="metro-icons d-flex-c">
${iconGen2({name: station.name, dataLines: station.lines})}
</span>
</div>
</div>
</div>`;
}
const prices = {
h1: Math.min(profile.prices.in['1h'] || 999999, profile.prices.out['1h'] || 999999),
h2: Math.min(profile.prices.in['2h'] || 999999, profile.prices.out['2h'] || 999999),
night: Math.min(profile.prices.in.night || 999999, profile.prices.out.night || 999999),
}
const hasApartPrice = profile.prices.in['1h'] || profile.prices.in['2h'] || profile.prices.in.night;
const hasTakeoutPricing = profile.prices.out['1h'] || profile.prices.out['2h'] || profile.prices.out.night;
let tagsHtml = generateTagList(hasApartPrice, hasTakeoutPricing, services);
/**
lines: [
{name: 'Калининская', color: 'FFD702'}
{name: 'Большая Кольцевая', color: '82C0C0'}
{name: 'МЦД-3', color: 'E15D29'}
]
name: "Авиамоторная"
*/
template = `
<a class="card-link" href="${profile.url}" target="_blank"><span class="visually-hidden">${name}</span></a>
<div class="card-layout d-grid">
<div class="card__avatar profile-card__avatar">
<div class="profile-card__avatar-link">
<img class="card__avatar-image profile-card__avatar-image" src="${image}" alt="Эскортница ${name}, ${age} лет, Алексеевская, снять, ${id}" width="220" height="308">
</div>
<div class="profile-card__icons d-flex-c">
<div data-tippy-icon="${has_selfie ? 'Есть' : 'Нет'} селфи" ${has_selfie ? '' : ' data-tippy-instance'}>
<svg class="profile-card__icon${has_selfie ? '' : ' off'}" width="20" height="20"><use href="#selfie"></use></svg>
</div>
<div data-tippy-icon="${has_video ? 'Есть' : 'Нет'} видео" ${has_video ? '' : ' data-tippy-instance'}>
<svg class="profile-card__icon${has_video ? '' : ' off'}" width="20" height="20"><use href="#video"></use></svg>
</div>
<div data-tippy-icon="${has_comments ? 'Есть' : 'Нет'} отзывы" ${has_comments ? '' : ' data-tippy-instance'}>
<svg class="profile-card__icon${has_comments ? '' : ' off'}" width="20" height="20"><use href="#comment"></use></svg>
</div>
</div>
</div>
<div class="profile-card__info">
<div class="profile-card__personal clr-text-base">
<div class="profile-card__personal-item d-flex">
<span class="profile-card__personal-title">Грудь</span>
<span class="profile-card__personal-value fw-600 ml-auto">${breast_size ? breast_size : '-'}</span>
</div>
<div class="profile-card__personal-item d-flex">
<span class="profile-card__personal-title">Рост</span>
<span class="profile-card__personal-value fw-600 ml-auto">${height ? height : '-'}</span>
</div>
<div class="profile-card__personal-item d-flex">
<span class="profile-card__personal-title">Вес</span>
<span class="profile-card__personal-value fw-600 ml-auto">${weight ? weight : '-'}</span>
</div>
</div>
<div class="card-time profile-card-time">
<div class="card-time-item d-flex clr-pre-white-bg">
<span class="card-time-title">Час</span>
<span class="card-time-value fw-700 ml-auto clr-main-text">${prices.h1 === 999999 ? '-' : prices.h1.toLocaleString('ru') + 'р'}</span>
</div>
<div class="card-time-item d-flex clr-pre-white-bg">
<span class="card-time-title">2 часа</span>
<span class="card-time-value fw-700 ml-auto clr-main-text">${prices.h2 === 999999 ? '-' : prices.h2.toLocaleString('ru') + 'р'}</span>
</div>
<div class="card-time-item d-flex clr-pre-white-bg">
<span class="card-time-title">Ночь</span>
<span class="card-time-value fw-700 ml-auto clr-main-text">${prices.night === 999999 ? '-' : prices.night.toLocaleString('ru') + 'р'}</span>
</div>
</div>
${tagsHtml}
</div>
</div>
<div class="card__bio-name profile-card__bio-name">
<div class="profile-card__bio-link fw-700">
<span class="profile-card__bio-text mr-1">${name}</span>
<span class="profile-card__bio-age mr-1">${age}</span>
</div>
</div>
${metroHtml}
<div class="profile-card__bio profile-card__bio-with-text">
<p class="profile-card__bio-desc mb-2">
${description}
</p>
</div>
`;
/*
<div class="profile-card__bio">
<button class="card__phone profile-card__phone btn btn-main-border btn-fluid fw-600" type="button" onclick="this.classList.add('d-none');this.nextElementSibling.classList.remove('d-none')">
<svg class="btn-icon" width="21" height="20" fill="none"><path d="M6.583 2.5H3.666a.836.836 0 0 0-.833.834C2.833 11.159 9.175 17.5 17 17.5a.836.836 0 0 0 .833-.833v-2.908a.836.836 0 0 0-.833-.834 9.503 9.503 0 0 1-2.975-.475.7.7 0 0 0-.259-.041.854.854 0 0 0-.591.241l-1.834 1.834A12.625 12.625 0 0 1 5.85 8.992l1.833-1.833a.836.836 0 0 0 .208-.85 9.467 9.467 0 0 1-.475-2.975.836.836 0 0 0-.833-.834Z"></path></svg>
<span class="btn-text">Показать телефон</span>
</button><!--noindex-->
<a href="tel:${phone}" rel="nofollow" class="card__phone profile-card__phone btn btn-main-border btn-fluid fw-600 is-active d-none">
<svg class="btn-icon" width="21" height="20" fill="none">
<path d="M6.583 2.5H3.666a.836.836 0 0 0-.833.834C2.833 11.159 9.175 17.5 17 17.5a.836.836 0 0 0 .833-.833v-2.908a.836.836 0 0 0-.833-.834 9.503 9.503 0 0 1-2.975-.475.7.7 0 0 0-.259-.041.854.854 0 0 0-.591.241l-1.834 1.834A12.625 12.625 0 0 1 5.85 8.992l1.833-1.833a.836.836 0 0 0 .208-.85 9.467 9.467 0 0 1-.475-2.975.836.836 0 0 0-.833-.834Z"></path>
</svg>
<span class="btn-text">${phone}</span>
</a><!--/noindex-->
</div>
*/
const node = document.createElement('div');
node.className = 'recommendation-item d-flex swiper-slide card profile-card white-round';
node.dataset.profileId = id;
node.innerHTML = template;
container.appendChild(node);
});
profileContainer.style.display = 'block';
document.dispatchEvent(new CustomEvent('recommendations:loaded', {detail: {id: 'recommendations'}}));
document.dispatchEvent(new Event('tippy:render'));
}
});
window.Recommendation.loadRecommendations();
}
window.ObserverJakka({
id: 'recommendations',
callback: () => {
fetchRecommendations();
},
options: {
rootMargin: '150px'
}
});
{#// iconGen2({
// "name": "просто метро",
// "dataLines": [
// {
// "name": "Калужско-Рижская",
// "color": "ED9121"
// }
// ]
// });
// iconGen2({
// "name": "мцд3",
// "dataLines": [
// {
// "name": "МЦД-3",
// "color": "E15D29"
// }
// ]
// });
// iconGen2({
// "name": "мцк",
// "dataLines": [
// {
// "name": "МЦК",
// "color": "E15D29"
// }
// ]
// });
// iconGen2({
// "name": "мцд+ мцк",
// "dataLines": [
// {
// "name": "МЦД-3",
// "color": "E15D29"
// },
// {
// "name": "МЦК",
// "color": "FFA8AF"
// }
// ]
// })
// iconGen2({
// "name": "Только мцд",
// "dataLines": [
// {
// "name": "МЦД-3",
// "color": "E15D29"
// },
// {
// "name": "МЦД-2",
// "color": "FFA8AF"
// }
// ]
// })
// iconGen2({
// "name": "Метро и мцк",
// "dataLines": [
// {
// "name": "Замоскворецкая",
// "color": "2DBE2C"
// },
// {
// "name": "МЦК",
// "color": "FFA8AF"
// }
// ]
// })
// iconGen2({
// "name": "Два метро",
// "dataLines": [
// {
// "name": "Замоскворецкая2",
// "color": "2DBE2C"
// },
// {
// "name": "Замороченская2",
// "color": "FFA8AF"
// }
// ]
// })
// iconGen2({
// "name": "2 метро + мцк",
// "dataLines": [
// {
// "name": "Солнцевская",
// "color": "FFD702"
// },
// {
// "name": "Большая Кольцевая",
// "color": "82C0C0"
// },
// {
// "name": "МЦК",
// "color": "FFA8AF"
// }
// ]
// })
// iconGen2({
// "name": "2 метро + мцд3",
// "dataLines": [
// {
// "name": "Калининская",
// "color": "FFD702"
// },
// {
// "name": "Большая Кольцевая",
// "color": "82C0C0"
// },
// {
// "name": "МЦД-3",
// "color": "E15D29"
// }
// ]
// });
// iconGen2({
// "name": "Метро + мцд2 + метро",
// "dataLines": [
// {
// "name": "Калининская",
// "color": "FFD702"
// },
// {
// "name": "МЦД-2",
// "color": "82C0C0"
// },
// {
// "name": "Большая Кольцевая 2",
// "color": "00C0C0"
// },
// ]
// });
// iconGen2({
// "name": "Три метро",
// "dataLines": [
// {
// "name": "Калининская",
// "color": "FFD702"
// },
// {
// "name": "Большая Кольцевая",
// "color": "82C0C0"
// },
// {
// "name": "Большая Кольцевая 2",
// "color": "00C0C0"
// },
// ]
// });
// iconGen2({
// "name": "Белорусская",
// "dataLines": [
// {
// "name": "Замоскворецкая",
// "color": "2DBE2C"
// },
// {
// "name": "Кольцевая",
// "color": "8D5B2D"
// },
// {
// "name": "МЦД-4",
// "color": "3CB183"
// },
// {
// "name": "МЦД-1",
// "color": "FAA400"
// }
// ]
// });#}
});
</script>