круги с иконками
All checks were successful
Deploy hotel / deploy-kdo (push) Successful in 34s

This commit is contained in:
2026-07-19 16:36:15 +05:00
parent e23d94f3b7
commit dc3ca7fcd0
4 changed files with 192 additions and 38 deletions

View File

@@ -9,7 +9,14 @@ const DEFAULT_SETTINGS = {
review_ip_cooldown_minutes: '5',
hotel_phone_primary: '89409270080',
hotel_phone_additional: '',
hotel_max_link: 'kalugin66'
hotel_whatsapp_num: '89409270080',
hotel_whatsapp_active: 'true',
hotel_telegram_id: '+89409270080',
hotel_telegram_active: 'true',
hotel_max_link: 'kalugin66',
hotel_max_active: 'true',
hotel_instagram_id: '',
hotel_instagram_active: 'true'
};
function init(database) {
@@ -211,20 +218,34 @@ function setupRoutes(app, authenticateToken, requireAdmin) {
res.json({
primary: settings.hotel_phone_primary || '',
additional: settings.hotel_phone_additional || '',
maxLink: settings.hotel_max_link || ''
whatsappNum: settings.hotel_whatsapp_num || '',
whatsappActive: settings.hotel_whatsapp_active || 'true',
telegramId: settings.hotel_telegram_id || '',
telegramActive: settings.hotel_telegram_active || 'true',
maxLink: settings.hotel_max_link || '',
maxActive: settings.hotel_max_active || 'true',
instagramId: settings.hotel_instagram_id || '',
instagramActive: settings.hotel_instagram_active || 'true'
});
});
});
app.put('/api/admin/settings/phones', authenticateToken, requireAdmin, (req, res) => {
const { primary, additional, maxLink } = req.body;
const { primary, additional, whatsappNum, whatsappActive, telegramId, telegramActive, maxLink, maxActive, instagramId, instagramActive } = req.body;
if (!primary || primary.length < 5) {
return res.status(400).json({ error: 'Основной номер должен содержать минимум 5 цифр' });
}
const updates = [];
updates.push(['hotel_phone_primary', primary]);
updates.push(['hotel_phone_additional', additional || '']);
updates.push(['hotel_whatsapp_num', whatsappNum || '']);
updates.push(['hotel_whatsapp_active', whatsappActive || 'true']);
updates.push(['hotel_telegram_id', telegramId || '']);
updates.push(['hotel_telegram_active', telegramActive || 'true']);
updates.push(['hotel_max_link', maxLink || '']);
updates.push(['hotel_max_active', maxActive || 'true']);
updates.push(['hotel_instagram_id', instagramId || '']);
updates.push(['hotel_instagram_active', instagramActive || 'true']);
let processed = 0;
updates.forEach(([key, value]) => {
set(key, value, (err) => {
@@ -243,7 +264,14 @@ function setupRoutes(app, authenticateToken, requireAdmin) {
res.json({
phone_primary: settings.hotel_phone_primary || '89409270080',
phone_additional: settings.hotel_phone_additional || '',
max_link: settings.hotel_max_link || 'kalugin66'
whatsapp_num: settings.hotel_whatsapp_num || '89409270080',
whatsapp_active: settings.hotel_whatsapp_active || 'true',
telegram_id: settings.hotel_telegram_id || '+89409270080',
telegram_active: settings.hotel_telegram_active || 'true',
max_link: settings.hotel_max_link || 'kalugin66',
max_active: settings.hotel_max_active || 'true',
instagram_id: settings.hotel_instagram_id || '',
instagram_active: settings.hotel_instagram_active || 'true'
});
});
});

View File

@@ -477,20 +477,60 @@ tr.row-checkout-today { background: #fef2f2 !important; border-left: 4px solid #
<div class="card-body-custom">
<p style="color: #64748b; margin-bottom: 20px;">
<i class="fas fa-info-circle me-2"></i>
Основной номер используется для звонков, WhatsApp и Telegram. Дополнительный отображается через запятую рядом с основным.
Основной номер используется для звонков. Дополнительный отображается через запятую. Для мессенджеров можно указать отдельные номера или username.
</p>
<div class="row g-3">
<div class="col-md-4">
<div class="col-md-6">
<label class="form-label">Основной номер</label>
<input type="text" class="form-control" id="phonePrimary" placeholder="89409270080">
</div>
<div class="col-md-4">
<div class="col-md-6">
<label class="form-label">Дополнительный номер</label>
<input type="text" class="form-control" id="phoneAdditional" placeholder="Необязательно">
</div>
</div>
<div class="row g-3 mt-1">
<div class="col-md-4">
<label class="form-label">Ссылка Max (username)</label>
<input type="text" class="form-control" id="phoneMaxLink" placeholder="kalugin66">
<label class="form-label">WhatsApp (номер)</label>
<div class="d-flex gap-2">
<input type="text" class="form-control" id="phoneWhatsappNum" placeholder="89409270080" style="flex:1">
<div class="form-check form-switch d-flex align-items-center" style="margin:0; padding-left:2.5em; white-space:nowrap;">
<input class="form-check-input" type="checkbox" id="phoneWhatsappActive" style="width:40px;height:20px;cursor:pointer;">
<label class="form-check-label ms-1" for="phoneWhatsappActive" style="font-size:0.75rem;">Активна</label>
</div>
</div>
</div>
<div class="col-md-4">
<label class="form-label">Telegram (username или +номер)</label>
<div class="d-flex gap-2">
<input type="text" class="form-control" id="phoneTelegramId" placeholder="+89409270080" style="flex:1">
<div class="form-check form-switch d-flex align-items-center" style="margin:0; padding-left:2.5em; white-space:nowrap;">
<input class="form-check-input" type="checkbox" id="phoneTelegramActive" style="width:40px;height:20px;cursor:pointer;">
<label class="form-check-label ms-1" for="phoneTelegramActive" style="font-size:0.75rem;">Активна</label>
</div>
</div>
</div>
<div class="col-md-4">
<label class="form-label">Max (username)</label>
<div class="d-flex gap-2">
<input type="text" class="form-control" id="phoneMaxLink" placeholder="kalugin66" style="flex:1">
<div class="form-check form-switch d-flex align-items-center" style="margin:0; padding-left:2.5em; white-space:nowrap;">
<input class="form-check-input" type="checkbox" id="phoneMaxActive" style="width:40px;height:20px;cursor:pointer;">
<label class="form-check-label ms-1" for="phoneMaxActive" style="font-size:0.75rem;">Активна</label>
</div>
</div>
</div>
</div>
<div class="row g-3 mt-1">
<div class="col-md-4">
<label class="form-label">Instagram (username)</label>
<div class="d-flex gap-2">
<input type="text" class="form-control" id="phoneInstagramId" placeholder="hotel777abkhazia" style="flex:1">
<div class="form-check form-switch d-flex align-items-center" style="margin:0; padding-left:2.5em; white-space:nowrap;">
<input class="form-check-input" type="checkbox" id="phoneInstagramActive" style="width:40px;height:20px;cursor:pointer;">
<label class="form-check-label ms-1" for="phoneInstagramActive" style="font-size:0.75rem;">Активна</label>
</div>
</div>
</div>
</div>
<div class="mt-3">
@@ -2505,7 +2545,14 @@ async function loadPhoneSettings() {
const data = await api('/api/admin/settings/phones');
document.getElementById('phonePrimary').value = data.primary || '';
document.getElementById('phoneAdditional').value = data.additional || '';
document.getElementById('phoneWhatsappNum').value = data.whatsappNum || '';
document.getElementById('phoneWhatsappActive').checked = data.whatsappActive === 'true';
document.getElementById('phoneTelegramId').value = data.telegramId || '';
document.getElementById('phoneTelegramActive').checked = data.telegramActive === 'true';
document.getElementById('phoneMaxLink').value = data.maxLink || '';
document.getElementById('phoneMaxActive').checked = data.maxActive === 'true';
document.getElementById('phoneInstagramId').value = data.instagramId || '';
document.getElementById('phoneInstagramActive').checked = data.instagramActive === 'true';
} catch(e) {}
}
@@ -2513,7 +2560,14 @@ async function savePhoneSettings() {
const data = {
primary: document.getElementById('phonePrimary').value.trim(),
additional: document.getElementById('phoneAdditional').value.trim(),
maxLink: document.getElementById('phoneMaxLink').value.trim()
whatsappNum: document.getElementById('phoneWhatsappNum').value.trim(),
whatsappActive: document.getElementById('phoneWhatsappActive').checked ? 'true' : 'false',
telegramId: document.getElementById('phoneTelegramId').value.trim(),
telegramActive: document.getElementById('phoneTelegramActive').checked ? 'true' : 'false',
maxLink: document.getElementById('phoneMaxLink').value.trim(),
maxActive: document.getElementById('phoneMaxActive').checked ? 'true' : 'false',
instagramId: document.getElementById('phoneInstagramId').value.trim(),
instagramActive: document.getElementById('phoneInstagramActive').checked ? 'true' : 'false'
};
if (!data.primary) {
showToast('Основной номер обязателен', 'error');

View File

@@ -302,63 +302,92 @@ h1, h2, h3, h4 {
background: #25D366;
color: #fff;
border: none;
padding: clamp(10px, 2vw, 15px) clamp(20px, 4vw, 40px);
border-radius: 50px;
width: 44px;
height: 44px;
border-radius: 50%;
font-weight: 700;
font-size: clamp(0.85rem, 1.2vw, 1rem);
letter-spacing: 0.5px;
font-size: 0.85rem;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
justify-content: center;
gap: 4px;
padding: 0;
}
.btn-whatsapp:hover {
background: #1ebe57;
transform: translateY(-3px);
box-shadow: 0 10px 30px rgba(37,211,102,0.4);
box-shadow: 0 8px 20px rgba(37,211,102,0.4);
color: #fff;
}
.btn-telegram {
background: #0088cc;
color: #fff;
border: none;
padding: clamp(10px, 2vw, 15px) clamp(20px, 4vw, 40px);
border-radius: 50px;
width: 44px;
height: 44px;
border-radius: 50%;
font-weight: 700;
font-size: clamp(0.85rem, 1.2vw, 1rem);
letter-spacing: 0.5px;
font-size: 0.85rem;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
justify-content: center;
gap: 4px;
padding: 0;
}
.btn-telegram:hover {
background: #0077b5;
transform: translateY(-3px);
box-shadow: 0 10px 30px rgba(0,136,204,0.4);
box-shadow: 0 8px 20px rgba(0,136,204,0.4);
color: #fff;
}
.btn-max {
background: #471AFF;
color: #fff;
border: none;
padding: clamp(10px, 2vw, 15px) clamp(20px, 4vw, 40px);
border-radius: 50px;
width: 44px;
height: 44px;
border-radius: 50%;
font-weight: 700;
font-size: clamp(0.85rem, 1.2vw, 1rem);
letter-spacing: 0.5px;
font-size: 0.85rem;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
justify-content: center;
gap: 4px;
padding: 0;
}
.btn-max:hover {
background: #3b15d9;
transform: translateY(-3px);
box-shadow: 0 10px 30px rgba(71,26,255,0.4);
box-shadow: 0 8px 20px rgba(71,26,255,0.4);
color: #fff;
}
.btn-instagram {
background: #E4405F;
color: #fff;
border: none;
width: 44px;
height: 44px;
border-radius: 50%;
font-weight: 700;
font-size: 0.85rem;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 4px;
padding: 0;
}
.btn-instagram:hover {
background: #d12e4e;
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(228,64,95,0.4);
color: #fff;
}
.max-icon-circle {
@@ -375,6 +404,25 @@ h1, h2, h3, h4 {
line-height: 1;
flex-shrink: 0;
}
.max-icon-circle-footer {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.2em;
height: 1.2em;
border-radius: 50%;
background: rgba(255,255,255,0.15);
color: rgba(255,255,255,0.6);
font-weight: 800;
font-size: 0.7em;
line-height: 1;
flex-shrink: 0;
transition: all 0.3s ease;
}
.footer-social a:hover .max-icon-circle-footer {
background: #471AFF;
color: #fff;
}
.hero-stats {
position: absolute;
bottom: clamp(20px, 5vw, 60px);
@@ -1533,10 +1581,16 @@ h1, h2, h3, h4 {
font-size: 0.65rem;
padding: 5px 12px;
}
.btn-gold, .btn-outline-white, .btn-whatsapp, .btn-telegram, .btn-max {
.btn-gold, .btn-outline-white {
padding: 10px 18px;
font-size: 0.8rem;
}
.btn-whatsapp, .btn-telegram, .btn-max, .btn-instagram {
width: 38px;
height: 38px;
font-size: 0.75rem;
padding: 0;
}
.float-phone {
width: 45px;
height: 45px;

View File

@@ -61,9 +61,10 @@
<div class="hero-buttons">
<a href="#rooms" class="btn-gold"><i class="fas fa-bed"></i> <span data-i18n="hero.btn_rooms">Выбрать номер</span></a>
<a href="tel:89409270080" class="btn-outline-white" data-phone="tel"><i class="fas fa-phone"></i> <span data-i18n="hero.btn_call">Позвонить</span></a>
<a href="https://wa.me/89409270080" class="btn-whatsapp" target="_blank" title="Написать в WhatsApp" data-phone="wa"><i class="fab fa-whatsapp"></i> W</a>
<a href="https://t.me/+89409270080" class="btn-telegram" target="_blank" title="Написать в Telegram" data-phone="tg"><i class="fab fa-telegram"></i> T</a>
<a href="https://max.ru/kalugin66" class="btn-max" target="_blank" title="Написать в Max" data-phone="max"><span class="max-icon-circle">M</span> M</a>
<a href="https://wa.me/89409270080" class="btn-whatsapp" target="_blank" title="Написать в WhatsApp" data-phone="wa"><i class="fab fa-whatsapp"></i></a>
<a href="https://t.me/+89409270080" class="btn-telegram" target="_blank" title="Написать в Telegram" data-phone="tg"><i class="fab fa-telegram"></i></a>
<a href="https://max.ru/kalugin66" class="btn-max" target="_blank" title="Написать в Max" data-phone="max"><span class="max-icon-circle">M</span></a>
<a href="#" data-phone="ig" class="btn-instagram" target="_blank" title="Instagram"><i class="fab fa-instagram"></i></a>
</div>
</div>
</div>
@@ -680,9 +681,10 @@
<div class="footer-brand">HOTEL <span>777</span></div>
<p class="footer-desc" data-i18n="footer.desc">Гостиница на берегу Чёрного моря в Абхазии. Комфортные номера, домашняя кухня Рауфа Алексеевича и настоящее абхазское гостеприимство.</p>
<div class="footer-social">
<a href="#"><i class="fab fa-whatsapp"></i></a>
<a href="#"><i class="fab fa-telegram"></i></a>
<a href="#"><i class="fab fa-instagram"></i></a>
<a href="#" data-phone="wa"><i class="fab fa-whatsapp"></i></a>
<a href="#" data-phone="tg"><i class="fab fa-telegram"></i></a>
<a href="#" data-phone="max"><span class="max-icon-circle-footer">M</span></a>
<a href="#" data-phone="ig"><i class="fab fa-instagram"></i></a>
<a href="tel:89409270080" data-phone="tel"><i class="fas fa-phone"></i></a>
</div>
</div>
@@ -857,18 +859,34 @@
.then(function(cfg) {
var primary = cfg.phone_primary || '89409270080';
var additional = cfg.phone_additional || '';
var whatsappNum = cfg.whatsapp_num || primary;
var whatsappActive = cfg.whatsapp_active || 'true';
var telegramId = cfg.telegram_id || ('+' + primary);
var telegramActive = cfg.telegram_active || 'true';
var maxLink = cfg.max_link || 'kalugin66';
var maxActive = cfg.max_active || 'true';
var instagramId = cfg.instagram_id || '';
var instagramActive = cfg.instagram_active || 'true';
var displayText = formatPhone(primary);
if (additional) displayText += ', ' + formatPhone(additional);
document.querySelectorAll('[data-phone]').forEach(function(el) {
var type = el.getAttribute('data-phone');
var href = '#';
var active = true;
if (type === 'tel') href = 'tel:' + primary;
else if (type === 'wa') href = 'https://wa.me/' + primary;
else if (type === 'tg') href = 'https://t.me/+' + primary;
else if (type === 'max') href = 'https://max.ru/' + maxLink;
else if (type === 'wa') { href = 'https://wa.me/' + whatsappNum; active = whatsappActive === 'true'; }
else if (type === 'tg') {
href = 'https://t.me/' + telegramId;
active = telegramActive === 'true';
}
else if (type === 'max') { href = 'https://max.ru/' + maxLink; active = maxActive === 'true'; }
else if (type === 'ig') {
if (instagramId) href = 'https://instagram.com/' + instagramId;
active = instagramActive === 'true';
}
el.setAttribute('href', href);
if (!active) el.style.display = 'none';
});
document.querySelectorAll('[data-phone-text]').forEach(function(el) {