PetMap: WhatsApp кнопка

This commit is contained in:
Medet 2026-08-07 06:41:23 +00:00
parent e3ef81a4e3
commit 7b2888a137

View File

@ -16,25 +16,8 @@
<meta name="apple-mobile-web-app-title" content="PetMap"> <meta name="apple-mobile-web-app-title" content="PetMap">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css?v=20260807"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<style> <style>
/* Кастомные иконки для маркеров */
.custom-marker {
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
text-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.marker-lost { filter: drop-shadow(0 2px 4px rgba(230,57,70,0.4)); }
.marker-found { filter: drop-shadow(0 2px 4px rgba(42,157,143,0.4)); }
.marker-help { filter: drop-shadow(0 2px 4px rgba(244,162,97,0.4)); }
.marker-home { filter: drop-shadow(0 2px 4px rgba(78,205,196,0.4)); }
.marker-vet { filter: drop-shadow(0 2px 4px rgba(42,157,143,0.4)); }
.marker-shelter { filter: drop-shadow(0 2px 4px rgba(244,162,97,0.4)); }
.marker-petshop { filter: drop-shadow(0 2px 4px rgba(255,107,107,0.4)); }
</style>
:root { :root {
--primary: #ff6b6b; --primary: #ff6b6b;
--primary-dark: #ee5a5a; --primary-dark: #ee5a5a;
@ -410,17 +393,17 @@
.rb-card { .rb-card {
background: white; border-radius: 12px; overflow: hidden; background: white; border-radius: 12px; overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.08); box-shadow: 0 2px 8px rgba(0,0,0,0.08);
transition: transform 0.3s, box-shadow 0.3s; transition: transform 0.3s;
} }
.rb-card:hover { transform: translateY(-6px); box-shadow: 0 8px 20px rgba(0,0,0,0.12); } .rb-card:hover { transform: translateY(-4px); }
.rb-card-img { .rb-card-img {
height: 160px; background: linear-gradient(135deg, #ffe5e5, #fff); height: 160px; background: linear-gradient(135deg, #ffe5e5, #fff);
display: flex; align-items: center; justify-content: center; display: flex; align-items: center; justify-content: center;
font-size: 60px; font-size: 60px;
} }
.rb-card-body { padding: 14px; } .rb-card-body { padding: 14px; }
.rb-card-title { font-weight: 700; font-size: 15px; margin-bottom: 6px; color: var(--text); } .rb-card-title { font-weight: 700; font-size: 15px; margin-bottom: 6px; }
.rb-card-desc { font-size: 13px; color: var(--text-muted); line-height: 1.5; margin-bottom: 8px; } .rb-card-desc { font-size: 13px; color: var(--text-muted); line-height: 1.5; }
/* MEMORIAL BOARD */ /* MEMORIAL BOARD */
.memorial-page { .memorial-page {
@ -455,13 +438,10 @@
.memorial-card { .memorial-card {
background: rgba(255,255,255,0.08); border-radius: 12px; background: rgba(255,255,255,0.08); border-radius: 12px;
padding: 16px; text-align: center; padding: 16px; text-align: center;
transition: transform 0.3s;
} }
.memorial-card:hover { transform: translateY(-4px); background: rgba(255,255,255,0.1); }
.memorial-card-emoji { font-size: 50px; margin-bottom: 12px; } .memorial-card-emoji { font-size: 50px; margin-bottom: 12px; }
.memorial-card-name { font-weight: 700; margin-bottom: 6px; } .memorial-card-name { font-weight: 700; margin-bottom: 6px; }
.memorial-card-date { font-size: 12px; opacity: 0.7; } .memorial-card-date { font-size: 12px; opacity: 0.7; }
.memorial-card-desc { font-size: 12px; opacity: 0.8; margin-top: 8px; line-height: 1.4; }
@media (max-width: 768px) { @media (max-width: 768px) {
.topbar { padding: 10px 12px; } .topbar { padding: 10px 12px; }
@ -593,7 +573,7 @@
<p class="preview-desc" id="preview-desc">Описание</p> <p class="preview-desc" id="preview-desc">Описание</p>
<div class="preview-contact" id="preview-contact"></div> <div class="preview-contact" id="preview-contact"></div>
<div class="preview-actions"> <div class="preview-actions">
<button class="preview-btn call" id="preview-whatsapp">💬 Написать в WhatsApp</button> <button class="preview-btn call" id="preview-whatsapp">💬 WhatsApp</button>
<button class="preview-btn primary" id="preview-share">📤 Поделиться</button> <button class="preview-btn primary" id="preview-share">📤 Поделиться</button>
<button class="preview-btn secondary" id="preview-close">Закрыть</button> <button class="preview-btn secondary" id="preview-close">Закрыть</button>
</div> </div>
@ -631,17 +611,8 @@
<option value="shymkent">Шымкент</option> <option value="shymkent">Шымкент</option>
<option value="karaganda">Караганда</option> <option value="karaganda">Караганда</option>
<option value="aktobe">Актобе</option> <option value="aktobe">Актобе</option>
<option value="taraz">Тараз</option>
<option value="pavlodar">Павлодар</option>
<option value="uk">Усть-Каменогорск</option>
<option value="semey">Семей</option>
<option value="kostanay">Костанай</option>
</select> </select>
</div> </div>
<div class="form-group">
<label>🗺️ Точка на карте</label>
<input type="text" name="mapcoords" placeholder="Кликните на карту для выбора места" readonly id="mapcoords">
</div>
<div class="form-group"> <div class="form-group">
<label>Кличка/Описание</label> <label>Кличка/Описание</label>
<input type="text" name="title" required placeholder="Бобик, рыжий, средний"> <input type="text" name="title" required placeholder="Бобик, рыжий, средний">
@ -787,121 +758,36 @@
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script> <script>
// ДАННЫЕ ЖИВОТНЫХ — расширенные тестовые объявления по всем городам РК // ДАННЫЕ ЖИВОТНЫХ
const ANIMALS = [ const ANIMALS = [
// АСТАНА { id: 1, type: 'lost', animal: 'dog', city: 'astana', title: 'Бобик, лабрадор', location: 'район Арбата', description: 'Пропал 5 августа, ошейник синий', contact: '+7 777 111 22 33', emoji: '🐕' },
{ id: 1, type: 'lost', animal: 'dog', city: 'astana', title: 'Бобик, лабрадор 5 лет', location: 'район Арбата', description: 'Пропал 5 августа 2025, синий ошейник, отзывчивый. Очень ждём!', contact: '+7 777 111 22 33', emoji: '🐕', lat: 51.1594, lng: 71.4391 }, { id: 2, type: 'found', animal: 'cat', city: 'almaty', title: 'Рыжий котёнок', location: 'ул. Абая, 45', description: 'Нашёлся у подъезда, около 3 месяцев', contact: '+7 701 234 56 78', emoji: '🐈' },
{ id: 2, type: 'found', animal: 'cat', city: 'astana', title: 'Котёнок рыжий, 3 мес', location: 'ЖК Нуржол, подъезд 5', description: 'Нашёлся 10 августа, игривый, здоровый. Ищем хозяев!', contact: '+7 701 234 56 78', emoji: '🐈', lat: 51.1694, lng: 71.4591 }, { id: 3, type: 'help', animal: 'dog', city: 'astana', title: 'Собака ранена', location: 'проспект Туран', description: 'Нужна срочная помощь, не ходит на лапу', contact: '+7 778 999 88 77', emoji: '🆘' },
{ id: 3, type: 'help', animal: 'dog', city: 'astana', title: 'Собака ранена, нужна помощь', location: 'проспект Туран, 42', description: 'Сбита машиной, не ходит на задние лапы. Срочно нужна клиника!', contact: '+7 778 999 88 77', emoji: '🆘', lat: 51.1794, lng: 71.4291 }, { id: 4, type: 'home', animal: 'cat', city: 'shymkent', title: 'Мурка ищет дом', location: 'приют "Достык"', description: 'Стерилизована, привита, ласковая', contact: '+7 775 444 33 22', emoji: '🏠' },
{ id: 4, type: 'home', animal: 'cat', city: 'astana', title: 'Мурка, 2 года', location: 'район Коктал', description: 'Стерилизована, привита, ласковая. Отдадим в добрые руки!', contact: '+7 775 444 33 22', emoji: '🏠', lat: 51.1494, lng: 71.4691 }, { id: 5, type: 'lost', animal: 'bird', city: 'karaganda', title: 'Попугай Кеша', location: 'микрорайон Юго-Восток', description: 'Говорит "привет", зелёный', contact: '+7 702 555 66 77', emoji: '🐦' },
{ id: 5, type: 'lost', animal: 'dog', city: 'astana', title: 'Хаски Арон, 3 года', location: 'микрорайон Юго-Восток', description: 'Пропал 1 августа, серо-белый, голубые глаза. Особая примета — белое пятно на спине.', contact: '+7 702 555 66 77', emoji: '🐕', lat: 51.1394, lng: 71.4891 },
// АЛМАТЫ
{ id: 6, type: 'lost', animal: 'dog', city: 'almaty', title: 'Овчарка Рекс, 4 года', location: 'ул. Абая, угол Розыбакиева', description: 'Пропал 3 августа, чёрно-подпалый, строгий ошейник. Вознаграждение!', contact: '+7 777 222 33 44', emoji: '🐕', lat: 43.2320, lng: 76.8612 },
{ id: 7, type: 'found', animal: 'cat', city: 'almaty', title: 'Кошка белая, беременная', location: 'ул. Сатпаева, 28', description: 'Нашлась 8 августа, очень ласковая. Нужен дом до родов.', contact: '+7 701 333 44 55', emoji: '🐈', lat: 43.2420, lng: 76.8712 },
{ id: 8, type: 'help', animal: 'dog', city: 'almaty', title: 'Щенки, нужны руки', location: 'ул. Толе би, 100', description: '5 щенят, 2 месяца, здоровые. Кормим сами, но не справляемся. Помогите пристроить!', contact: '+7 778 444 55 66', emoji: '🐕', lat: 43.2520, lng: 76.8512 },
{ id: 9, type: 'home', animal: 'cat', city: 'almaty', title: 'Кот Барсик, 5 лет', location: 'мкр. Таугуль', description: 'Спокойный, кастрирован, приучен к лотку. Отдаём из-за переезда.', contact: '+7 775 555 66 77', emoji: '🏠', lat: 43.2120, lng: 76.8812 },
{ id: 10, type: 'lost', animal: 'bird', city: 'almaty', title: 'Попугай Корелла, Леша', location: 'пр. Достык, 65', description: 'Улетел 6 августа, жёлто-серый, говорит "привет". Очень любим!', contact: '+7 702 666 77 88', emoji: '🐦', lat: 43.2220, lng: 76.8912 },
// ШЫМКЕНТ
{ id: 11, type: 'found', animal: 'dog', city: 'shymkent', title: 'Дворняга Дружок', location: 'ул. Калбекова, 15', description: 'Нашёлся 9 августа, средний, добрый. Хозяева, отзовитесь!', contact: '+7 777 333 22 11', emoji: '🐕', lat: 42.3100, lng: 69.5900 },
{ id: 12, type: 'home', animal: 'cat', city: 'shymkent', title: 'Котята 3 шт, 2 мес', location: 'мкр. Самал', description: 'Два рыжих, один чёрный. Кушают сами, здоровые. В добрые руки!', contact: '+7 701 444 33 22', emoji: '🐈', lat: 42.2900, lng: 69.6100 },
{ id: 13, type: 'help', animal: 'dog', city: 'shymkent', title: 'Пёс под машиной', location: 'ул. Рыскулова, 88', description: 'Лежит под машиной во дворе, не выходит. Нужна помощь с отловом.', contact: '+7 778 555 44 33', emoji: '🆘', lat: 42.3200, lng: 69.5800 },
// КАРАГАНДА
{ id: 14, type: 'lost', animal: 'cat', city: 'karaganda', title: 'Кошка Муся, 6 лет', location: 'микрорайон Юго-Восток, 56/8', description: 'Пропала 4 августа, черепаховый окрас, очень пугливая.', contact: '+7 777 444 55 66', emoji: '🐈', lat: 49.8147, lng: 73.1194 },
{ id: 15, type: 'found', animal: 'dog', city: 'karaganda', title: 'Лайка, 2 года', location: 'ул. Ермекова, 30', description: 'Нашлась 7 августа, белая, худая. Похожа на ездовую. Кормим временно.', contact: '+7 701 555 66 77', emoji: '🐕', lat: 49.7947, lng: 73.0994 },
{ id: 16, type: 'home', animal: 'dog', city: 'karaganda', title: 'Щенок Шарик, 4 мес', location: 'п. Михайловка', description: 'Дворняжка, умный, игривый. Ищет дом навсегда.', contact: '+7 775 666 77 88', emoji: '🐕', lat: 49.8247, lng: 73.1294 },
// АКТОБЕ
{ id: 17, type: 'lost', animal: 'dog', city: 'aktobe', title: 'Той-терьер Тина', location: 'ул. Шерниязова, 22', description: 'Пропала 2 августа, чёрно-подпалая, красный бантик. Очень маленькая.', contact: '+7 777 666 77 88', emoji: '🐕', lat: 50.2939, lng: 57.1770 },
{ id: 18, type: 'help', animal: 'cat', city: 'aktobe', title: 'Кот после травмы', location: 'ул. Айтеке би, 45', description: 'Подобрали с переломом, в гипсе. Нужна передержка на восстановление.', contact: '+7 701 777 88 99', emoji: '🐈', lat: 50.2739, lng: 57.1570 },
// ТАРАЗ
{ id: 19, type: 'found', animal: 'cat', city: 'taraz', title: 'Кот серый, взрослый', location: 'ул. Байтурсынова, 18', description: 'Нашёлся 5 августа, крупный, спокойный. Похож на домашнего.', contact: '+7 777 888 99 00', emoji: '🐈', lat: 42.9100, lng: 71.3767 },
{ id: 20, type: 'home', animal: 'dog', city: 'taraz', title: 'Овчарка смешанная, 3 года', location: 'мкр. Бауыржан Момышулы', description: 'Добрая, охраняет, любит детей. Отдаём из-за аллергии у ребёнка.', contact: '+7 775 999 00 11', emoji: '🐕', lat: 42.8900, lng: 71.3567 },
// ПАВЛОДАР
{ id: 21, type: 'lost', animal: 'dog', city: 'pavlodar', title: 'Спаниель Ральф', location: 'ул. Кривенко, 52', description: 'Пропал 1 августа, коричневый, белые лапки. Ошейник с адресником.', contact: '+7 777 000 11 22', emoji: '🐕', lat: 52.2933, lng: 76.9767 },
{ id: 22, type: 'help', animal: 'dog', city: 'pavlodar', title: 'Стая собак у рынка', location: 'Центральный рынок', description: '6-7 собак, мешают торговле. Нужен отлов или приют.', contact: '+7 701 111 22 33', emoji: '🆘', lat: 52.2733, lng: 76.9567 },
// УСТЬ-КАМЕНОГОРСК
{ id: 23, type: 'found', animal: 'cat', city: 'uk', title: 'Котёнок чёрный, 4 мес', location: 'пр. Независимости, 62', description: 'Нашёлся 8 августа, игривый, здоровый. Ищет дом.', contact: '+7 777 222 33 44', emoji: '🐈', lat: 49.9767, lng: 82.6100 },
{ id: 24, type: 'home', animal: 'rabbit', city: 'uk', title: 'Кролик Пушок, 1 год', location: 'ул. Горького, 35', description: 'Белый, декоративный. Отдаём с клеткой и кормом.', contact: '+7 701 333 44 55', emoji: '🐇', lat: 49.9567, lng: 82.5900 },
// СЕМЕЙ
{ id: 25, type: 'lost', animal: 'cat', city: 'semey', title: 'Кот Рыжик, 7 лет', location: 'ул. Абай, 45', description: 'Пропал 3 августа, очень рыжий, толстый. Не выходит на улицу обычно.', contact: '+7 777 444 55 66', emoji: '🐈', lat: 50.4211, lng: 80.2375 },
{ id: 26, type: 'help', animal: 'dog', city: 'semey', title: 'Щенки 8 шт, 1 мес', location: 'п. Ново-Баженово', description: 'Бездомная мама родила в сарае. Срочно нужны руки или передержка.', contact: '+7 778 555 66 77', emoji: '🐕', lat: 50.4011, lng: 80.2175 },
// КОСТАНАЙ
{ id: 27, type: 'found', animal: 'dog', city: 'kostanay', title: 'Лабрадор светлый', location: 'ул. Ауэзова, 28', description: 'Нашёлся 6 августа, без ошейника, чистый. Похож на породного.', contact: '+7 777 666 77 88', emoji: '🐕', lat: 53.2244, lng: 63.6346 },
{ id: 28, type: 'home', animal: 'cat', city: 'kostanay', title: 'Кошка Соня, 4 года', location: 'мкр. Восточный', description: 'Спокойная, домашняя. Отдаём из-за рождения ребёнка.', contact: '+7 701 777 88 99', emoji: '🐈', lat: 53.2044, lng: 63.6146 },
]; ];
// СПАСЁННЫЕ — истории успеха // СПАСЁННЫЕ
const RESCUED = [ const RESCUED = [
{ id: 1, title: 'Бобик нашёл семью в Астане', emoji: '🐕', outcome: 'home_found', desc: 'Лабрадор, потерялся 05.08.2025. Через 3 дня нашёлся благодаря PetMap! Забрала семья из Алматы.', city: 'Астана', date: '15.08.2025' }, { id: 1, title: 'Бобик нашёл дом', emoji: '🐕', outcome: 'home_found', desc: 'Забрала семья из Астаны' },
{ id: 2, title: 'Рыжик вернулся домой по чипу', emoji: '🐈', outcome: 'owner_found', desc: 'Кот 5 лет, пропал в Караганде. Волонтёры проверили чип — хозяин нашёлся через 2 дня!', city: 'Караганда', date: '12.08.2025' }, { id: 2, title: 'Рыжик вернулся к хозяину', emoji: '🐈', outcome: 'owner_found', desc: 'Нашли по чипу' },
{ id: 3, title: 'Каспер вылечен и пристроен', emoji: '🩹', outcome: 'treated', desc: 'Пёс с переломом, операция прошла успешно. Теперь живёт в новой семье в Шымкенте.', city: 'Шымкент', date: '10.08.2025' }, { id: 3, title: 'Каспер вылечен', emoji: '🩹', outcome: 'treated', desc: 'Операция прошла успешно' },
{ id: 4, title: 'Луна уехала в Германию', emoji: '🐕', outcome: 'home_found', desc: 'Дворняжка из приюта Алматы. Девушка увидела в PetMap и оформила документы на вывоз.', city: 'Алматы', date: '18.08.2025' }, { id: 4, title: 'Луна в новой семье', emoji: '🐕', outcome: 'home_found', desc: 'Уехала в Алматы' },
{ id: 5, title: 'Хаски Арон найден', emoji: '🐕', outcome: 'owner_found', desc: 'Пропал в Астане 01.08.2025. Нашёлся через 5 дней в соседнем дворе — заперли дети.', city: 'Астана', date: '06.08.2025' },
{ id: 6, title: 'Котята из Таугуля — все в доме', emoji: '🐈', outcome: 'home_found', desc: '3 котёнка, 2 месяца. Разобрали по домам за 4 дня через объявления.', city: 'Алматы', date: '14.08.2025' },
{ id: 7, title: 'Овчарка Рекс — герой дня', emoji: '🐕', outcome: 'owner_found', desc: 'Убежал во время прогулки. Хозяин разместил в PetMap — нашёлся через 12 часов!', city: 'Алматы', date: '04.08.2025' },
{ id: 8, title: 'Тина той-терьер дома', emoji: '🐕', outcome: 'owner_found', desc: 'Маленькая собачка потерялась в Актобе. Нашли через 2 дня — сидела в подъезде.', city: 'Актобе', date: '03.08.2025' },
]; ];
// МЕМОРИАЛ — те, кого не успели спасти // МЕМОРИАЛ
const MEMORIAL = [ const MEMORIAL = [
{ id: 1, name: 'Рекс', emoji: '🐕', date: '2025', city: 'Астана', desc: 'Дворняга, сбит машиной. Не успели довезти до клиники.' }, { id: 1, name: 'Рекс', emoji: '🐕', date: '2025' },
{ id: 2, name: 'Барсик', emoji: '🐈', date: '2024', city: 'Алматы', desc: 'Кот 10 лет, старость. Ушёл на радугу в окружении любимой семьи.' }, { id: 2, name: 'Барсик', emoji: '🐈', date: '2024' },
{ id: 3, name: 'Кеша', emoji: '🐦', date: '2025', city: 'Караганда', desc: 'Попугай, улетел и не нашёлся. Хозяева очень скучают.' }, { id: 3, name: 'Кеша', emoji: '🐦', date: '2025' },
{ id: 4, name: 'Мухтар', emoji: '🐕', date: '2025', city: 'Шымкент', desc: 'Овчарка, болезнь. Боролся 3 месяца, но не выдержало сердце.' },
{ id: 5, name: 'Снежок', emoji: '🐈', date: '2024', city: 'Павлодар', desc: 'Белый кот, отравление. Не смогли спасти, слишком поздно обратились.' },
]; ];
// ВЕТКЛИНИКИ, ПРИЮТЫ, ЗООМАГАЗИНЫ — по всем городам // ВЕТКЛИНИКИ И ПРИЮТЫ
const POIS = [ const POIS = [
// АСТАНА { id: 101, type: 'vet', city: 'astana', title: 'Ветклиника "Айболит"', location: 'ул. Кенесары, 35', contact: '+7 7172 55 66 77', emoji: '🏥' },
{ id: 101, type: 'vet', city: 'astana', title: 'Ветклиника "Айболит"', location: 'ул. Кенесары, 35', contact: '+7 7172 55 66 77', emoji: '🏥', lat: 51.1694, lng: 71.4491, workHours: 'Круглосуточно' }, { id: 102, type: 'vet', city: 'almaty', title: 'Ветцентр "ЗооМир"', location: 'пр. Абая, 120', contact: '+7 727 333 44 55', emoji: '🏥' },
{ id: 102, type: 'vet', city: 'astana', title: 'Ветцентр "ЗооДоктор"', location: 'пр. Туран, 42', contact: '+7 7172 66 77 88', emoji: '🏥', lat: 51.1794, lng: 71.4291, workHours: '9:00-21:00' }, { id: 103, type: 'shelter', city: 'astana', title: 'Приют "Достык"', location: 'п. Коктал-2', contact: '+7 777 888 99 00', emoji: '🏠' },
{ id: 103, type: 'shelter', city: 'astana', title: 'Приют "Достык"', location: 'п. Коктал-2', contact: '+7 777 888 99 00', emoji: '🏠', lat: 51.1494, lng: 71.4691, workHours: '10:00-18:00' }, { id: 104, type: 'shelter', city: 'almaty', title: 'Приют "Бауыр"', location: 'с. Байсерке', contact: '+7 701 222 33 44', emoji: '🏠' },
{ id: 104, type: 'petshop', city: 'astana', title: 'Зоомагазин "Лапки"', location: 'ЖК Нуржол, 12', contact: '+7 701 222 33 44', emoji: '🛒', lat: 51.1594, lng: 71.4591, workHours: '10:00-22:00' },
// АЛМАТЫ
{ id: 105, type: 'vet', city: 'almaty', title: 'Ветцентр "ЗооМир"', location: 'пр. Абая, 120', contact: '+7 727 333 44 55', emoji: '🏥', lat: 43.2320, lng: 76.8612, workHours: 'Круглосуточно' },
{ id: 106, type: 'vet', city: 'almaty', title: 'Клиника "Верный друг"', location: 'ул. Сатпаева, 28', contact: '+7 727 444 55 66', emoji: '🏥', lat: 43.2420, lng: 76.8712, workHours: '8:00-22:00' },
{ id: 107, type: 'shelter', city: 'almaty', title: 'Приют "Бауыр"', location: 'с. Байсерке', contact: '+7 701 222 33 44', emoji: '🏠', lat: 43.2120, lng: 76.8812, workHours: '10:00-17:00' },
{ id: 108, type: 'petshop', city: 'almaty', title: 'Зообазар "4 Лапы"', location: 'ул. Толе би, 100', contact: '+7 777 333 22 11', emoji: '🛒', lat: 43.2520, lng: 76.8512, workHours: '9:00-20:00' },
// ШЫМКЕНТ
{ id: 109, type: 'vet', city: 'shymkent', title: 'Ветклиника "Айболит-Юг"', location: 'ул. Калбекова, 15', contact: '+7 7252 55 66 77', emoji: '🏥', lat: 42.3100, lng: 69.5900, workHours: '9:00-20:00' },
{ id: 110, type: 'shelter', city: 'shymkent', title: 'Приют "Мейрим"', location: 'мкр. Самал', contact: '+7 777 444 55 66', emoji: '🏠', lat: 42.2900, lng: 69.6100, workHours: '10:00-18:00' },
// КАРАГАНДА
{ id: 111, type: 'vet', city: 'karaganda', title: 'Ветклиника "Доктор Вет"', location: 'микрорайон Юго-Восток, 56/8', contact: '+7 7212 55 66 77', emoji: '🏥', lat: 49.8147, lng: 73.1194, workHours: '9:00-21:00' },
{ id: 112, type: 'petshop', city: 'karaganda', title: 'Зоомагазин "Пушок"', location: 'ул. Ермекова, 30', contact: '+7 701 555 66 77', emoji: '🛒', lat: 49.7947, lng: 73.0994, workHours: '10:00-21:00' },
// АКТОБЕ
{ id: 113, type: 'vet', city: 'aktobe', title: 'Ветцентр "Актобе Вет"', location: 'ул. Шерниязова, 22', contact: '+7 7132 55 66 77', emoji: '🏥', lat: 50.2939, lng: 57.1770, workHours: '9:00-20:00' },
{ id: 114, type: 'shelter', city: 'aktobe', title: 'Приют "Үміт"', location: 'ул. Айтеке би, 45', contact: '+7 777 666 77 88', emoji: '🏠', lat: 50.2739, lng: 57.1570, workHours: '10:00-17:00' },
// ТАРАЗ
{ id: 115, type: 'vet', city: 'taraz', title: 'Ветклиника "Тараз Вет"', location: 'ул. Байтурсынова, 18', contact: '+7 7262 55 66 77', emoji: '🏥', lat: 42.9100, lng: 71.3767, workHours: '9:00-19:00' },
// ПАВЛОДАР
{ id: 116, type: 'vet', city: 'pavlodar', title: 'Ветклиника "Ертіс"', location: 'ул. Кривенко, 52', contact: '+7 7182 55 66 77', emoji: '🏥', lat: 52.2933, lng: 76.9767, workHours: '9:00-20:00' },
{ id: 117, type: 'petshop', city: 'pavlodar', title: 'Зоомагазин "Хвостик"', location: 'пр. Ломова, 25', contact: '+7 701 111 22 33', emoji: '🛒', lat: 52.2733, lng: 76.9567, workHours: '10:00-21:00' },
// УСТЬ-КАМЕНОГОРСК
{ id: 118, type: 'vet', city: 'uk', title: 'Ветклиника "Алтай Вет"', location: 'пр. Независимости, 62', contact: '+7 7232 55 66 77', emoji: '🏥', lat: 49.9767, lng: 82.6100, workHours: '9:00-20:00' },
{ id: 119, type: 'shelter', city: 'uk', title: 'Приют "Сенім"', location: 'ул. Горького, 35', contact: '+7 777 888 99 00', emoji: '🏠', lat: 49.9567, lng: 82.5900, workHours: '10:00-17:00' },
// СЕМЕЙ
{ id: 120, type: 'vet', city: 'semey', title: 'Ветклиника "Семей Вет"', location: 'ул. Абай, 45', contact: '+7 7222 55 66 77', emoji: '🏥', lat: 50.4211, lng: 80.2375, workHours: '9:00-19:00' },
// КОСТАНАЙ
{ id: 121, type: 'vet', city: 'kostanay', title: 'Ветклиника "Қостанай Вет"', location: 'ул. Ауэзова, 28', contact: '+7 7142 55 66 77', emoji: '🏥', lat: 53.2244, lng: 63.6346, workHours: '9:00-20:00' },
{ id: 122, type: 'petshop', city: 'kostanay', title: 'Зоомагазин "Барбос"', location: 'мкр. Восточный, 15', contact: '+7 701 777 88 99', emoji: '🛒', lat: 53.2044, lng: 63.6146, workHours: '10:00-21:00' },
]; ];
const CITIES = { const CITIES = {
@ -922,48 +808,9 @@
L.control.zoom({ position: 'bottomright' }).addTo(map); L.control.zoom({ position: 'bottomright' }).addTo(map);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors' attribution: '© OpenStreetMap'
}).addTo(map); }).addTo(map);
// Иконки для разных типов маркеров
function getMarkerIcon(item) {
const itemType = item.type || item.cat;
let emoji = item.emoji || '📍';
let className = 'custom-marker';
// Разные смайлики для разных типов
if (itemType === 'lost') {
emoji = '👀'; // Глаза — ищут, потерян
className += ' marker-lost';
} else if (itemType === 'found' || itemType === 'sighting') {
emoji = '👁️'; // Глаз — видел на улице
className += ' marker-found';
} else if (itemType === 'needs_help' || itemType === 'help') {
emoji = '🆘'; // SOS — нужна помощь
className += ' marker-help';
} else if (itemType === 'seeking_home' || itemType === 'home') {
emoji = '🏠'; // Дом — ищет дом
className += ' marker-home';
} else if (itemType === 'vet') {
emoji = '🏥'; // Больница — ветклиника
className += ' marker-vet';
} else if (itemType === 'shelter') {
emoji = '🏡'; // Приют
className += ' marker-shelter';
} else if (itemType === 'petshop') {
emoji = '🛒'; // Магазин
className += ' marker-petshop';
}
return L.divIcon({
className: className,
html: `<div style="font-size:32px;background:white;border-radius:50%;width:44px;height:44px;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px rgba(0,0,0,0.2);">${emoji}</div>`,
iconSize: [44, 44],
iconAnchor: [22, 22],
popupAnchor: [0, -22]
});
}
const markers = []; const markers = [];
function addMarkers(filter = 'all') { function addMarkers(filter = 'all') {
markers.forEach(m => map.removeLayer(m)); markers.forEach(m => map.removeLayer(m));
@ -976,17 +823,11 @@
if (filter.startsWith('poi-') && item.type !== filter.replace('poi-', '')) return; if (filter.startsWith('poi-') && item.type !== filter.replace('poi-', '')) return;
if (!filter.startsWith('poi-') && itemType !== filter) return; if (!filter.startsWith('poi-') && itemType !== filter) return;
} }
// Используем точные координаты или координаты города const city = CITIES[item.city];
const lat = item.lat || CITIES[item.city]?.lat; if (!city) return;
const lng = item.lng || CITIES[item.city]?.lng;
if (!lat || !lng) return;
const icon = getMarkerIcon(item); const marker = L.marker([city.lat, city.lng]).addTo(map);
const marker = L.marker([lat, lng], { icon: icon }).addTo(map); marker.bindPopup(`<b>${item.emoji} ${item.title}</b><br>${item.location}`);
const popupContent = item.workHours
? `<b>${item.emoji || '📍'} ${item.title}</b><br>${item.location}<br>🕒 ${item.workHours}<br>📞 ${item.contact}`
: `<b>${item.emoji || '📍'} ${item.title}</b><br>${item.location}<br>📞 ${item.contact}`;
marker.bindPopup(popupContent);
marker.on('click', () => showPreview(item)); marker.on('click', () => showPreview(item));
markers.push(marker); markers.push(marker);
}); });
@ -1009,44 +850,28 @@
// Preview // Preview
const preview = document.getElementById('preview'); const preview = document.getElementById('preview');
let currentItem = null;
function showPreview(item) { function showPreview(item) {
currentItem = item;
const cityName = CITIES[item.city]?.name || item.city;
document.getElementById('preview-image').textContent = item.emoji; document.getElementById('preview-image').textContent = item.emoji;
document.getElementById('preview-title').textContent = item.title; document.getElementById('preview-title').textContent = item.title;
document.getElementById('preview-meta').innerHTML = ` document.getElementById('preview-meta').innerHTML = `
<span class="preview-tag cat-${item.type}">${getTypeName(item.type)}</span> <span class="preview-tag cat-${item.type}">${getTypeName(item.type)}</span>
<span class="preview-tag">📍 ${cityName}</span> <span class="preview-tag">${CITIES[item.city]?.name}</span>
${item.workHours ? `<span class="preview-tag">🕒 ${item.workHours}</span>` : ''}
`;
document.getElementById('preview-desc').textContent = item.description || 'Описание отсутствует';
document.getElementById('preview-contact').innerHTML = `
<strong>📞 Контакт:</strong><br>
<a href="tel:${item.contact}" style="color: var(--primary); text-decoration: none; font-size: 16px;">${item.contact}</a>
`; `;
document.getElementById('preview-desc').textContent = item.description;
document.getElementById('preview-contact').textContent = `📞 ${item.contact}`;
// WhatsApp кнопка — сразу переход // WhatsApp — сразу в чат
document.getElementById('preview-whatsapp').onclick = () => { document.getElementById('preview-whatsapp').onclick = () => {
const phone = item.contact.replace(/[^0-9]/g, ''); // Удаляем всё кроме цифр const phone = item.contact.replace(/[^0-9]/g, '');
const msg = encodeURIComponent(`Здравствуйте! Пишу по объявлению: ${item.title}\n${item.description}`); const msg = encodeURIComponent(`Здравствуйте! По объявлению: ${item.title}`);
const waUrl = `https://wa.me/${phone}?text=${msg}`; window.open(`https://wa.me/${phone}?text=${msg}`, '_blank');
window.open(waUrl, '_blank');
}; };
document.getElementById('preview-share').onclick = () => { document.getElementById('preview-share').onclick = () => {
const shareData = {
title: item.title,
text: `${item.title} — ${item.description}\n${cityName}\nКонтакт: ${item.contact}`,
url: window.location.href
};
if (navigator.share) { if (navigator.share) {
navigator.share(shareData).catch(() => {}); navigator.share({ title: item.title, text: item.description });
} else { } else {
navigator.clipboard.writeText(`${item.title} — ${item.description}\n${cityName}\nКонтакт: ${item.contact}`); showToast('📋 Скопировано в буфер');
showToast('📋 Скопировано в буфер обмена');
} }
}; };
preview.classList.add('open'); preview.classList.add('open');
@ -1058,74 +883,14 @@
return names[type] || type; return names[type] || type;
} }
// Modal + выбор координат на карте // Modal
const modal = document.getElementById('modal'); const modal = document.getElementById('modal');
const mapcoordsInput = document.getElementById('mapcoords'); document.getElementById('fab').onclick = () => modal.classList.add('open');
let tempMarker = null; document.getElementById('modal-close').onclick = () => modal.classList.remove('open');
document.getElementById('fab').onclick = () => {
modal.classList.add('open');
// Подсказка: кликните на карту
showToast('🗺️ Кликните на карту, чтобы выбрать место');
};
document.getElementById('modal-close').onclick = () => {
modal.classList.remove('open');
if (tempMarker) {
map.removeLayer(tempMarker);
tempMarker = null;
}
};
// Клик по карте для выбора координат
map.on('click', (e) => {
if (!modal.classList.contains('open')) return;
const { lat, lng } = e.latlng;
mapcoordsInput.value = `${lat.toFixed(4)}, ${lng.toFixed(4)}`;
if (tempMarker) map.removeLayer(tempMarker);
tempMarker = L.marker([lat, lng]).addTo(map);
tempMarker.bindPopup('📍 Ваше объявление будет здесь').openPopup();
showToast('📍 Координаты выбраны');
});
document.getElementById('animal-form').onsubmit = (e) => { document.getElementById('animal-form').onsubmit = (e) => {
e.preventDefault(); e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData.entries());
if (!mapcoordsInput.value) {
showToast('⚠️ Выберите место на карте!');
return;
}
// Добавляем в массив (в реальном проекте — отправка на сервер)
const [lat, lng] = mapcoordsInput.value.split(',').map(Number);
const newAnimal = {
id: Date.now(),
type: data.type,
animal: data.animal,
city: data.city,
title: data.title,
location: data.location || 'Координаты выбраны',
description: data.description,
contact: data.contact,
emoji: { dog: '🐕', cat: '🐈', bird: '🐦', other: '🐾' }[data.animal] || '🐾',
lat, lng
};
ANIMALS.push(newAnimal);
addMarkers(); // Обновить маркеры
showToast('✅ Объявление опубликовано!'); showToast('✅ Объявление опубликовано!');
modal.classList.remove('open'); modal.classList.remove('open');
if (tempMarker) {
map.removeLayer(tempMarker);
tempMarker = null;
}
e.target.reset();
mapcoordsInput.value = '';
}; };
// Drawer // Drawer
@ -1209,23 +974,15 @@
<div class="rb-card-body"> <div class="rb-card-body">
<div class="rb-card-title">${r.title}</div> <div class="rb-card-title">${r.title}</div>
<div class="rb-card-desc">${r.desc}</div> <div class="rb-card-desc">${r.desc}</div>
<div style="display:flex;justify-content:space-between;margin-top:8px;font-size:11px;color:var(--text-muted);">
<span>📍 ${r.city}</span>
<span>${r.date}</span>
</div>
</div> </div>
</div> </div>
`).join(''); `).join('');
const homeFound = RESCUED.filter(r => r.outcome === 'home_found').length;
const ownerFound = RESCUED.filter(r => r.outcome === 'owner_found').length;
const treated = RESCUED.filter(r => r.outcome === 'treated').length;
document.getElementById('rb-stats').innerHTML = ` document.getElementById('rb-stats').innerHTML = `
<div class="rb-stat"><div class="rb-stat-num">${RESCUED.length}</div><div class="rb-stat-label">Всего спасено</div></div> <div class="rb-stat"><div class="rb-stat-num">${RESCUED.length}</div><div class="rb-stat-label">Всего спасено</div></div>
<div class="rb-stat"><div class="rb-stat-num">${homeFound}</div><div class="rb-stat-label">Нашли дом</div></div> <div class="rb-stat"><div class="rb-stat-num">${RESCUED.filter(r => r.outcome === 'home_found').length}</div><div class="rb-stat-label">Нашли дом</div></div>
<div class="rb-stat"><div class="rb-stat-num">${ownerFound}</div><div class="rb-stat-label">К хозяину</div></div> <div class="rb-stat"><div class="rb-stat-num">${RESCUED.filter(r => r.outcome === 'owner_found').length}</div><div class="rb-stat-label">К хозяину</div></div>
<div class="rb-stat"><div class="rb-stat-num">${treated}</div><div class="rb-stat-label">Вылечены</div></div> <div class="rb-stat"><div class="rb-stat-num">${RESCUED.filter(r => r.outcome === 'treated').length}</div><div class="rb-stat-label">Вылечены</div></div>
`; `;
} }
@ -1250,8 +1007,7 @@
<div class="memorial-card"> <div class="memorial-card">
<div class="memorial-card-emoji">${m.emoji}</div> <div class="memorial-card-emoji">${m.emoji}</div>
<div class="memorial-card-name">${m.name}</div> <div class="memorial-card-name">${m.name}</div>
<div class="memorial-card-date">📍 ${m.city}, ${m.date}</div> <div class="memorial-card-date">${m.date}</div>
<div class="memorial-card-desc" style="font-size:12px;opacity:0.8;margin-top:8px;line-height:1.4;">${m.desc}</div>
</div> </div>
`).join(''); `).join('');
} }