This commit is contained in:
2025-09-09 00:10:53 +03:00
parent 38f2a05107
commit 204fc092d7
239 changed files with 22447 additions and 9536 deletions

View File

@@ -0,0 +1,181 @@
<div class="page-constructor">
<details id="details-info" open>
<summary>
<span>Крок 1.</span> Інформація про будинок, територію, точки на карті
</summary>
<form id="info-form">
<div id="details-info-type">
<div class="tabs">
<input
type="radio"
id="info-type-house"
value="house"
name="info-type"
checked
/>
<label class="tab" for="info-type-house">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<path
d="M 14.5 6 A 1.50015 1.50015 0 0 0 13 7.5 L 13 25 L 7.5 25 A 1.50015 1.50015 0 0 0 6 26.5 L 6 42.5 A 1.50015 1.50015 0 1 0 9 42.5 L 9 28 L 14.253906 28 A 1.50015 1.50015 0 0 0 14.740234 28 L 19 28 L 19 42.5 A 1.50015 1.50015 0 1 0 22 42.5 L 22 26.746094 A 1.50015 1.50015 0 0 0 22 26.259766 L 22 22 L 33.253906 22 A 1.50015 1.50015 0 0 0 33.740234 22 L 39 22 L 39 42.5 A 1.50015 1.50015 0 1 0 42 42.5 L 42 20.5 A 1.50015 1.50015 0 0 0 40.5 19 L 35 19 L 35 7.5 A 1.50015 1.50015 0 0 0 33.5 6 L 14.5 6 z M 16 9 L 32 9 L 32 19 L 20.5 19 A 1.50015 1.50015 0 0 0 19 20.5 L 19 25 L 16 25 L 16 9 z M 20 12 C 19.448 12 19 12.448 19 13 L 19 15 C 19 15.552 19.448 16 20 16 L 22 16 C 22.552 16 23 15.552 23 15 L 23 13 C 23 12.448 22.552 12 22 12 L 20 12 z M 26 12 C 25.448 12 25 12.448 25 13 L 25 15 C 25 15.552 25.448 16 26 16 L 28 16 C 28.552 16 29 15.552 29 15 L 29 13 C 29 12.448 28.552 12 28 12 L 26 12 z M 26 25 C 25.448 25 25 25.448 25 26 L 25 28 C 25 28.552 25.448 29 26 29 L 28 29 C 28.552 29 29 28.552 29 28 L 29 26 C 29 25.448 28.552 25 28 25 L 26 25 z M 33 25 C 32.448 25 32 25.448 32 26 L 32 28 C 32 28.552 32.448 29 33 29 L 35 29 C 35.552 29 36 28.552 36 28 L 36 26 C 36 25.448 35.552 25 35 25 L 33 25 z M 13 31 C 12.448 31 12 31.448 12 32 L 12 34 C 12 34.552 12.448 35 13 35 L 15 35 C 15.552 35 16 34.552 16 34 L 16 32 C 16 31.448 15.552 31 15 31 L 13 31 z M 26 31 C 25.448 31 25 31.448 25 32 L 25 34 C 25 34.552 25.448 35 26 35 L 28 35 C 28.552 35 29 34.552 29 34 L 29 32 C 29 31.448 28.552 31 28 31 L 26 31 z M 33 31 C 32.448 31 32 31.448 32 32 L 32 34 C 32 34.552 32.448 35 33 35 L 35 35 C 35.552 35 36 34.552 36 34 L 36 32 C 36 31.448 35.552 31 35 31 L 33 31 z M 13 37 C 12.448 37 12 37.448 12 38 L 12 40 C 12 40.552 12.448 41 13 41 L 15 41 C 15.552 41 16 40.552 16 40 L 16 38 C 16 37.448 15.552 37 15 37 L 13 37 z M 26 37 C 25.448 37 25 37.448 25 38 L 25 40 C 25 40.552 25.448 41 26 41 L 28 41 C 28.552 41 29 40.552 29 40 L 29 38 C 29 37.448 28.552 37 28 37 L 26 37 z M 33 37 C 32.448 37 32 37.448 32 38 L 32 40 C 32 40.552 32.448 41 33 41 L 35 41 C 35.552 41 36 40.552 36 40 L 36 38 C 36 37.448 35.552 37 35 37 L 33 37 z"
/>
</svg>
<span>Багатоквартирний будинок</span>
</label>
<input
type="radio"
id="info-type-homestead"
value="homestead"
name="info-type"
/>
<label class="tab" for="info-type-homestead">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<path
d="M 24 5.015625 C 22.851301 5.015625 21.70304 5.3892757 20.753906 6.1367188 A 1.50015 1.50015 0 0 0 20.751953 6.1367188 L 8.859375 15.509766 C 7.0558128 16.931133 6 19.102989 6 21.400391 L 6 39.488281 C 6 41.403236 7.5850452 42.988281 9.5 42.988281 L 38.5 42.988281 C 40.414955 42.988281 42 41.403236 42 39.488281 L 42 21.400391 C 42 19.102989 40.944187 16.931133 39.140625 15.509766 L 39 15.396484 L 39 7.5 A 1.50015 1.50015 0 0 0 37.5 6 L 32.5 6 A 1.50015 1.50015 0 0 0 31 7.5 L 31 9.09375 L 27.246094 6.1367188 C 26.29696 5.3892758 25.148699 5.015625 24 5.015625 z M 24 8.0078125 C 24.489801 8.0078125 24.979759 8.1705836 25.390625 8.4941406 L 31.572266 13.363281 A 1.50015 1.50015 0 0 0 34 12.185547 L 34 9 L 36 9 L 36 16.125 A 1.50015 1.50015 0 0 0 36.572266 17.302734 L 37.285156 17.865234 C 38.369594 18.719867 39 20.019792 39 21.400391 L 39 39.488281 C 39 39.783326 38.795045 39.988281 38.5 39.988281 L 9.5 39.988281 C 9.2049548 39.988281 9 39.783326 9 39.488281 L 9 21.400391 C 9 20.019792 9.6304058 18.719867 10.714844 17.865234 L 22.609375 8.4941406 C 23.020241 8.1705836 23.510199 8.0078125 24 8.0078125 z M 14.5 23.988281 A 1.50015 1.50015 0 0 0 13 25.488281 L 13 33.488281 A 1.50015 1.50015 0 0 0 14.5 34.988281 L 20.5 34.988281 A 1.50015 1.50015 0 0 0 22 33.488281 L 22 25.488281 A 1.50015 1.50015 0 0 0 20.5 23.988281 L 14.5 23.988281 z M 27.5 23.988281 A 1.50015 1.50015 0 0 0 26 25.488281 L 26 33.488281 A 1.50015 1.50015 0 0 0 27.5 34.988281 L 33.5 34.988281 A 1.50015 1.50015 0 0 0 35 33.488281 L 35 25.488281 A 1.50015 1.50015 0 0 0 33.5 23.988281 L 27.5 23.988281 z M 16 26.988281 L 19 26.988281 L 19 31.988281 L 16 31.988281 L 16 26.988281 z M 29 26.988281 L 32 26.988281 L 32 31.988281 L 29 31.988281 L 29 26.988281 z"
/>
</svg>
<span>Житловий район</span>
</label>
<input
type="radio"
id="info-type-points"
value="points"
name="info-type"
/>
<label class="tab" for="info-type-points">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<path
d="M 24 4 C 16.285455 4 10 10.285455 10 18 C 10 21.46372 11.272608 24.643548 13.359375 27.085938 L 13.359375 27.087891 L 13.361328 27.087891 C 13.361328 27.087891 19.149094 33.866566 21.298828 35.917969 C 22.798087 37.348278 25.199464 37.347492 26.699219 35.917969 C 29.129083 33.600994 34.636721 27.090553 34.640625 27.085938 L 34.642578 27.082031 C 36.728766 24.639939 38 21.462159 38 18 C 38 10.285455 31.714545 4 24 4 z M 24 7 C 30.093455 7 35 11.906545 35 18 C 35 20.73228 34.005417 23.211194 32.359375 25.136719 L 32.359375 25.138672 L 32.357422 25.138672 C 32.357422 25.138672 26.632181 31.83589 24.628906 33.746094 C 24.258577 34.099392 23.73947 34.099392 23.369141 33.746094 C 21.715477 32.16807 15.643092 25.141834 15.638672 25.136719 L 15.636719 25.132812 C 13.99327 23.20762 13 20.730712 13 18 C 13 11.906545 17.906545 7 24 7 z M 24 12 C 22.125 12 20.528815 12.757133 19.503906 13.910156 C 18.478997 15.063179 18 16.541667 18 18 C 18 19.458333 18.478997 20.936821 19.503906 22.089844 C 20.528815 23.242867 22.125 24 24 24 C 25.875 24 27.471185 23.242867 28.496094 22.089844 C 29.521003 20.936821 30 19.458333 30 18 C 30 16.541667 29.521003 15.063179 28.496094 13.910156 C 27.471185 12.757133 25.875 12 24 12 z M 24 15 C 25.124999 15 25.778816 15.367867 26.253906 15.902344 C 26.728997 16.436821 27 17.208333 27 18 C 27 18.791667 26.728997 19.563179 26.253906 20.097656 C 25.778816 20.632133 25.124999 21 24 21 C 22.875001 21 22.221184 20.632133 21.746094 20.097656 C 21.271003 19.563179 21 18.791667 21 18 C 21 17.208333 21.271003 16.436821 21.746094 15.902344 C 22.221184 15.367867 22.875001 15 24 15 z M 12.771484 29.441406 C 8.2264844 30.754406 5 32.953 5 36 C 5 41.252 14.558 44 24 44 C 33.442 44 43 41.252 43 36 C 43 32.954 39.775422 30.757359 35.232422 29.443359 C 34.654422 30.099359 33.863187 30.993844 32.992188 31.964844 C 37.418188 33.005844 40 34.691 40 36 C 40 38.039 33.767 41 24 41 C 14.233 41 8 38.039 8 36 C 8 34.69 10.586531 33.001938 15.019531 31.960938 C 14.152531 30.995938 13.355484 30.100406 12.771484 29.441406 z"
/>
</svg>
<span>Точки на карті</span>
</label>
<span class="glider"></span>
</div>
</div>
<div id="details-info-address" class="details-info-input">
<label for="info-address-title">Назва вулиці</label>
<input
type="text"
id="info-address-title"
name="address"
required
value=""
/>
</div>
<div id="details-info-number" class="details-info-input">
<label for="info-number-title">Номер будинку</label>
<input
type="text"
id="info-number-title"
name="number"
required
value=""
/>
</div>
<div id="details-info-settlement" class="details-info-input">
<label for="info-settlement-title">Місто</label>
<input
type="text"
id="info-settlement-title"
name="settlement"
required
value="Тернопіль"
/>
</div>
<div id="details-info-osm" class="details-info-input">
<label for="info-settlement-title">OSM iD</label>
<div>
<input
type="text"
id="info-osm-title"
name="osm"
placeholder="123, 345, 678"
required
value=""
/>
<a href="https://www.openstreetmap.org/#map=19/49.561725/25.604458" target="_blank" title="Де знайти OSM iD ?"
><svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48"
width="100px"
height="100px"
>
<path
d="M 24 4 C 12.972066 4 4 12.972074 4 24 C 4 35.027926 12.972066 44 24 44 C 35.027934 44 44 35.027926 44 24 C 44 12.972074 35.027934 4 24 4 z M 24 7 C 33.406615 7 41 14.593391 41 24 C 41 33.406609 33.406615 41 24 41 C 14.593385 41 7 33.406609 7 24 C 7 14.593391 14.593385 7 24 7 z M 24 14 A 2 2 0 0 0 24 18 A 2 2 0 0 0 24 14 z M 23.976562 20.978516 A 1.50015 1.50015 0 0 0 22.5 22.5 L 22.5 33.5 A 1.50015 1.50015 0 1 0 25.5 33.5 L 25.5 22.5 A 1.50015 1.50015 0 0 0 23.976562 20.978516 z"
/></svg
></a>
</div>
</div>
<button id="info-form-button" type="submit">Далі</button>
</form>
</details>
<details id="details-map" disabled>
<summary id="details-map-title">
<span>Крок 2.</span> Створення підїздів
</summary>
<form id="map-form">
<div class="editor-buttons" id="details-map-buttons-entranse">
<button type="button" onclick="Constructor.editor.drawEntranse()">
Створити новий під'їзд
</button>
<div>
<button type="button" id="ruler" onclick="Constructor.editor.drawRectangle()">
Лінійка
</button>
<button
type="button"
id="ruler_divide"
onclick="Constructor.editor.ruler()"
style="display: none"
>
Поділити
</button>
</div>
</div>
<div
class="editor-buttons"
id="details-map-buttons-homestead"
style="display: none"
>
<div>
<button type="button" id="ruler" onclick="Constructor.editor.drawRectangle()">
Лінійка
</button>
<button
type="button"
id="ruler_divide"
onclick="Constructor.editor.ruler()"
style="display: none"
>
Поділити
</button>
</div>
</div>
<div id="list-entranse" style="display: none"></div>
<div id="list-homestead" style="display: none"></div>
<div class="block-map">
<div id="map"></div>
</div>
<button id="map-form-button" type="submit">Далі</button>
</form>
</details>
<details id="details-area" disabled>
<summary><span>Крок 3.</span> Конструктор квартир <input type="number" value="1" id="next-apartment-title" onchange="Constructor.apartments.editNum(this)" title="Авто-номер наступної квартири"></summary>
<form id="area-form">
<div id="list-area"></div>
<button id="area-form-button" type="submit">Зберегти</button>
</form>
</details>
</div>

View File

@@ -0,0 +1,731 @@
let map, houseGroup, entransePolygonsGroup, entranseNumPolygonsGroup, splitPolygonsGroup, RectangleGroup;
let numApartments = 1;
let mode = '';
const Constructor = {
info: {
type: null,
title: null,
number: null,
points: [],
points_number: [],
point_icons: [],
geo: [],
osm_id: [],
settlement: [],
description: null,
entrance: [],
apartments: {},
zoom: null
},
init: async () => {
let html = await fetch('/lib/pages/constructor/index.html').then((response) => response.text());
app.innerHTML = html;
map = "";
map = "";
houseGroup = "";
entransePolygonsGroup = "";
entranseNumPolygonsGroup = "";
splitPolygonsGroup = "";
RectangleGroup = "";
numApartments = 1;
Constructor.apartments.init();
document.querySelectorAll('input[name="info-type"]').forEach(radio => {
radio.addEventListener('change', event => {
console.log(`Выбран: ${event.target.value}`);
Constructor.info.type = event.target.value;
let detailsInfo_number = document.getElementById('details-info-number');
let detailsInfo_osm = document.getElementById('details-info-osm');
let detailsInfo_number_title = document.getElementById('info-number-title');
let detailsInfo_osm_title = document.getElementById('info-osm-title');
let detailsMap_title = document.getElementById('details-map-title');
let detailsMap_buttons_entranse = document.getElementById('details-map-buttons-entranse');
let detailsMap_buttons_homestead = document.getElementById('details-map-buttons-homestead');
let detailsMap_button = document.getElementById('map-form-button');
let detailsArea = document.getElementById('details-area');
switch (event.target.value) {
case 'points':
detailsInfo_number.style.display = "none";
detailsInfo_osm.style.display = "none";
detailsInfo_number_title.removeAttribute("required");
detailsInfo_osm_title.removeAttribute("required");
detailsMap_title.innerHTML = "<span>Крок 2.</span> Створення точок на карті"
detailsMap_buttons_entranse.style.display = "none";
detailsMap_buttons_homestead.style.display = "none";
detailsMap_button.innerText = "Зберегти";
detailsArea.style.display = "none";
break;
case 'homestead':
detailsInfo_number.style.display = "";
detailsInfo_osm.style.display = "";
detailsInfo_number_title.setAttribute("required", "");
detailsInfo_osm_title.setAttribute("required", "");
detailsMap_title.innerHTML = "<span>Крок 2.</span> Створення житлових територій"
detailsMap_buttons_entranse.style.display = "none";
detailsMap_buttons_homestead.style.display = "";
detailsMap_button.innerText = "Зберегти";
detailsArea.style.display = "none";
break;
default:
detailsInfo_number.style.display = "";
detailsInfo_osm.style.display = "";
detailsInfo_number_title.setAttribute("required", "");
detailsInfo_osm_title.setAttribute("required", "");
detailsMap_title.innerHTML = "<span>Крок 2.</span> Створення підʼїздів"
detailsMap_buttons_entranse.style.display = "";
detailsMap_buttons_homestead.style.display = "none";
detailsMap_button.innerText = "Далі";
detailsArea.style.display = "";
break;
}
});
});
document.getElementById("info-form").addEventListener("submit", function (event) {
event.preventDefault();
let details_map = document.getElementById("details-map");
details_map.removeAttribute("disabled");
details_map.open = true;
const infoForm = document.getElementById("info-form");
let osm = () => {
const a = document.getElementById("info-osm-title").value;
const b = a.replace(/\s+/g, "").split(',')
return b;
}
Constructor.info.type = infoForm.querySelector('input[name="info-type"]:checked').value;
Constructor.info.title = document.getElementById("info-address-title").value;
Constructor.info.number = document.getElementById("info-number-title").value;
Constructor.info.settlement = document.getElementById("info-settlement-title").value;
Constructor.info.osm_id = osm();
Constructor.osm.init();
Constructor.osm.setMap();
})
document.getElementById("map-form").addEventListener("submit", async function (event) {
event.preventDefault();
let details_area = document.getElementById("details-area");
details_area.removeAttribute("disabled");
details_area.open = true;
switch (Constructor.info.type) {
case 'points':
break;
case 'homestead':
await Constructor.api.setPack();
break;
default:
let details_area = document.getElementById("details-area");
details_area.removeAttribute("disabled");
details_area.open = true;
break;
}
})
document.getElementById("area-form").addEventListener("submit", async function (event) {
event.preventDefault();
await Constructor.api.setPack();
})
},
apartments: {
init: () => {
let listArea = document.getElementById('list-area');
listArea.innerHTML = ``;
for (const key in Constructor.info.apartments) {
const element = Constructor.info.apartments[key];
const pos = Constructor.info.entrance.map(e => e.editor_id).indexOf(key);
console.log(element);
let listArea = document.getElementById('list-area');
listArea.innerHTML += `
<div class="block-area" id="block-area-${key}">
<h3>${Constructor.info.entrance[pos].title}</h3>
<button class="addFloors" title="Додати поверх" type="button" onclick="Constructor.apartments.addFloors('${key}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
<div id="area-${key}"></div>
</div>
`;
element.sort((a, b) => a.floors_number - b.floors_number);
let uniqueFloors = [...new Set(element.map(obj => obj.floors_number))];
for (let i = 0; i < uniqueFloors.length; i++) {
let num = uniqueFloors[i];
let areaBlock = document.getElementById(`area-${key}`);
let div = document.createElement('div');
div.className = "block-apartments-floors";
div.id = `floors-${key}-${num}`
div.innerHTML = `
<button class="addApartment" id="buttonApartment-${key}-${num}" title="Додати квартиру" type="button" onclick="Constructor.apartments.addApartment('${key}', '${num}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
`;
areaBlock.prepend(div);
}
element.sort((a, b) => b.title - a.title);
for (let i = 0; i < element.length; i++) {
const apartment = element[i];
let num = apartment.floors_number;
let floorsBlock = document.getElementById(`floors-${key}-${apartment.floors_number}`);
let div = document.createElement('div');
div.className = "block-apartments-number";
div.id = `block-apartments-${key}-${apartment.editor_id}`
div.innerHTML = `
<input type="text" value="${apartment.title}" id="apartament-${key}-${apartment.editor_id}" onchange="Constructor.apartments.editApartment('${key}','${apartment.editor_id}')">
<button type="button" onclick="Constructor.apartments.deleteApartment('${key}','${apartment.editor_id}')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
</button>
`;
floorsBlock.prepend(div);
}
element.sort((a, b) => b.floors_number - a.floors_number);
}
},
editNum: (element) => {
numApartments = Number(element.value);
},
addFloors: (area) => {
let areaBlock = document.getElementById(`area-${area}`);
let uniqueFloors = [...new Set(Constructor.info.apartments[area].map(obj => obj.floors_number))];
let new_floors = uniqueFloors.length + 1;
let new_id = makeid(5);
let div = document.createElement('div');
div.className = "block-apartments-floors";
div.id = `floors-${area}-${new_floors}`
div.innerHTML = `
<h2>Поверх ${new_floors}</h2>
<div class="block-apartments-number" id="block-apartments-${area}-${new_id}">
<input type="text" value="${numApartments}" id="apartament-${area}-${new_id}" onchange="Constructor.apartments.editApartment('${area}', '${new_id}')">
<button type="button" onclick="Constructor.apartments.deleteApartment('${area}', '${new_id}')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
</button>
</div>
<button class="addApartment" id="buttonApartment-${area}-${new_floors}" title="Додати квартиру" type="button" onclick="Constructor.apartments.addApartment('${area}', '${new_floors}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
`
areaBlock.prepend(div);
Constructor.info.apartments[area].push({
editor_id: new_id,
entrance_id: null,
apartment_number: Constructor.info.apartments[area].length,
title: numApartments,
floors_number: new_floors
});
numApartments++;
let next_apartment_title = document.getElementById('next-apartment-title');
next_apartment_title.value = numApartments;
},
addApartment: (area, floors) => {
let new_id = makeid(5);
Constructor.info.apartments[area].push({
editor_id: new_id,
entrance_id: null,
apartment_number: Constructor.info.apartments[area].length,
title: numApartments,
floors_number: Number(floors)
})
let floorsBlock = document.getElementById(`floors-${area}-${floors}`);
document.getElementById(`buttonApartment-${area}-${floors}`).remove();
floorsBlock.innerHTML += `
<div class="block-apartments-number" id="block-apartments-${area}-${new_id}">
<input type="text" value="${numApartments}" id="apartament-${area}-${new_id}" onchange="Constructor.apartments.editApartment('${area}', '${new_id}')">
<button type="button" onclick="Constructor.apartments.deleteApartment('${area}', '${new_id}')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
</button>
</div>
`;
floorsBlock.innerHTML += `<button class="addApartment" id="buttonApartment-${area}-${floors}" title="Додати квартиру" type="button" onclick="Constructor.apartments.addApartment('${area}', '${floors}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>`
numApartments++;
let next_apartment_title = document.getElementById('next-apartment-title');
next_apartment_title.value = numApartments;
},
editApartment: (area, apartament) => {
let input = document.getElementById(`apartament-${area}-${apartament}`);
input.setAttribute("value", input.value);
const pos = Constructor.info.apartments[area].map(e => e.editor_id).indexOf(apartament);
info.apartments[area][pos].title = input.value;
},
deleteApartment: (area, apartament) => {
document.getElementById(`block-apartments-${area}-${apartament}`).remove();
const pos = Constructor.info.apartments[area].map(e => e.editor_id).indexOf(apartament);
Constructor.info.apartments[area].splice(pos, 1);
numApartments--;
let next_apartment_title = document.getElementById('next-apartment-title');
next_apartment_title.value = numApartments;
}
},
osm: {
init: () => {
let center = { lat: 49.5629016, lng: 25.6145625 };
let zoom = 19;
let googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
maxZoom: 20,
minZoom: 15,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
});
let osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
minZoom: 15
});
let mytile = L.tileLayer('https://sheep-service.com/map/{z}/{x}/{y}.webp', {
maxZoom: 20,
minZoom: 15,
tms: true
});
if (!map) {
houseGroup = new L.FeatureGroup();
splitPolygonsGroup = new L.FeatureGroup();
RectangleGroup = new L.FeatureGroup();
entransePolygonsGroup = new L.FeatureGroup();
entranseNumPolygonsGroup = new L.FeatureGroup();
map = L.map('map', {
renderer: L.canvas(),
center,
zoom,
layers: [
googleHybrid,
osm,
mytile,
houseGroup,
entransePolygonsGroup,
entranseNumPolygonsGroup,
splitPolygonsGroup,
RectangleGroup,
],
zoomControl: false
});
let baseMaps = {
"Google Hybrid": googleHybrid,
"OpenStreetMap": osm,
"Territory Map": mytile
};
let overlayMaps = {
"Будинки": houseGroup,
"Під'їзди": entransePolygonsGroup,
"Номера під'їздів": entranseNumPolygonsGroup,
"Слой редактирования": splitPolygonsGroup,
"Слой линейки": RectangleGroup,
};
L.control.layers(baseMaps, overlayMaps, { position: 'bottomright' }).addTo(map);
map.pm.setLang("ua");
map.pm.addControls({
position: 'bottomright',
drawCircleMarker: false,
drawPolyline: false,
drawPolygon: false,
drawRectangle: false,
drawCircle: false,
drawText: false,
drawMarker: false,
cutPolygon: false,
tooltips: false
});
map.pm.toggleControls()
map.pm.setGlobalOptions({
layerGroup: splitPolygonsGroup
})
}
Constructor.editor.init();
},
getOSM: async (wayId) => {
const overpassUrl = `https://overpass-api.de/api/interpreter?data=[out:json];way(${wayId});(._;>;);out;`;
return await fetch(overpassUrl)
.then(response => response.json())
.then(data => {
const nodes = new Map();
data.elements.forEach(el => {
if (el.type === "node") {
nodes.set(el.id, { lat: el.lat, lng: el.lon });
}
});
const way = data.elements.find(el => el.type === "way");
if (way) {
const coordinates = way.nodes.map(nodeId => nodes.get(nodeId));
console.log("Координаты точек:", coordinates);
return [coordinates];
} else {
console.log("Way не найден!");
}
})
.catch(error => console.error("Ошибка запроса:", error));
},
setMap: async () => {
houseGroup.clearLayers();
if (!Constructor.info.osm_id) {
let osm = () => {
const a = document.getElementById("info-osm-title").value;
const b = a.replace(/\s+/g, "").split(',')
return b;
}
Constructor.info.osm_id = osm();
}
for (let i = 0; i < Constructor.info.osm_id.length; i++) {
const element = await Constructor.osm.getOSM(Constructor.info.osm_id[i]);
let coords = [];
element[0].forEach((feature) => coords.push([feature.lat, feature.lng]));
let centerPoint = turf.centerOfMass(turf.polygon([coords]));
if (Constructor.info.type == "homestead") {
map.setView([centerPoint.geometry.coordinates[0], centerPoint.geometry.coordinates[1]], 17);
L.polygon(element, {
color: "#f2bd53",
radius: 500,
fillOpacity: 0.3,
dashArray: '20, 15',
dashOffset: '20',
}).addTo(houseGroup);
} else if (Constructor.info.type == "house") {
map.setView([centerPoint.geometry.coordinates[0], centerPoint.geometry.coordinates[1]], 18);
Constructor.info.points.push(element);
Constructor.info.points_number.push(element[0][0]);
L.polygon(element, {
color: "#585858",
fillColor: "#f2bd53",
fillOpacity: 0.8,
tm_id: `house_${i}`
}).addTo(houseGroup);
}
}
console.log(Constructor.info);
}
},
api: {
setPack: async () => {
let area_form_button = document.getElementById('area-form-button');
area_form_button.innerText = "Зачекайте...";
Constructor.info.geo = await map.getCenter();
Constructor.info.zoom = await map.getZoom();
console.log(Constructor.info);
const uuid = localStorage.getItem('uuid');
const URL = `${CONFIG.api}constructor`;
await fetch(URL, {
method: 'POST',
headers: {
"Content-Type": "application/json",
"Authorization": uuid
},
body: JSON.stringify(Constructor.info)
})
.then(response => {
if (response.status == 200) {
console.log({ 'setPack': 'ok' });
area_form_button.innerText = "Запис додано";
return response.json()
} else {
console.log('err');
area_form_button.innerText = "Помилка запису";
return
}
})
.then(data => {
console.log(data);
Territory.house.list = [];
Territory.homestead.list = [];
Router.navigate(`/territory/manager/${Constructor.info.type}/${data.id}`);
setTimeout(() => {
area_form_button.innerText = "Зберегти";
}, 3000);
})
.catch(err => {
console.log(err);
area_form_button.innerText = "Помилка запису";
})
}
},
editor: {
init: () => {
map.on('pm:create', function (event) {
let layer = event.layer;
let newCoords = layer.getLatLngs()[0].map(function (coords) {
return [coords.lng, coords.lat];
});
newCoords.push(newCoords[0]);
let turfNew = turf.polygon([newCoords]);
if (mode == 'entranse') {
console.log(L.PM.Utils.findLayers(houseGroup));
for (let i = 0; i < L.PM.Utils.findLayers(houseGroup).length; i++) {
const polygon = L.PM.Utils.findLayers(houseGroup)[i]._latlngs;
let polygonCoords = polygon[0].map(function (coords) {
return [coords.lng, coords.lat];
});
polygonCoords.push(polygonCoords[0]); // Замикаємо полігон
let turfPolygon = turf.polygon([polygonCoords]);
// Пошук точки перехрестя
let intersections = turf.intersect(turfNew, turfPolygon);
if (intersections) {
let points = [];
let coords = [];
intersections.geometry.coordinates[0].forEach(function (feature) {
coords.push([feature[1], feature[0]])
points.push({ lat: feature[1], lng: feature[0] })
});
let centerPoint = turf.centerOfMass(turf.polygon([coords]));
let points_number = { lat: centerPoint.geometry.coordinates[0], lng: centerPoint.geometry.coordinates[1] }
let newID = makeid(6);
Constructor.info.entrance.push({
editor_id: newID,
house_id: null,
entrance_number: Constructor.info.entrance.length,
title: `Під'їзд ${Constructor.info.entrance.length + 1}`,
points: points,
points_number: points_number,
floors_quantity: null,
apartments_quantity: null,
created_at: null
})
Constructor.info.apartments[newID] = [];
Constructor.apartments.init();
let listEntranse = document.getElementById('list-entranse');
listEntranse.style.display = "";
listEntranse.innerHTML += `
<div class="house" style="align-items: center;" id="Entranse_${newID}">
<input type="number" value="${Constructor.info.entrance.length}" id="Entranse_input_${newID}" onchange="Constructor.editor.editEntranse('${newID}')">
<button type="button" onclick="Constructor.editor.dellEntranse('${newID}')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
</button>
</div>
`;
L.polygon(coords, { color: 'red' }).addTo(entransePolygonsGroup);
let myIcon = L.divIcon({ className: 'entranse_number', html: `<div class="markerEntranse">${Constructor.info.entrance.length}</div>` });
L.marker(centerPoint.geometry.coordinates, { icon: myIcon }).addTo(entranseNumPolygonsGroup);
}
}
}
});
},
drawEntranse: () => {
mode = 'entranse';
map.pm.setGlobalOptions({
layerGroup: splitPolygonsGroup
})
map.pm.setPathOptions({
color: '#f2bd53',
fillColor: '#f2bd53',
fillOpacity: 0.5,
radius: 500
});
if (map.pm.globalDragModeEnabled()) {
map.pm.disableDraw();
} else {
map.pm.enableDraw("Polygon", {
snappable: true,
snapDistance: 20,
tooltips: false,
templineStyle: { color: '#f2bd53' },
hintlineStyle: { color: '#f2bd53', dashArray: [5, 5] }
});
}
},
drawRectangle: () => {
mode = 'rectangle';
document.getElementById('ruler_divide').style.display = 'block'
document.getElementById('ruler').style.width = "calc(50% - 5px)"
document.getElementById('ruler_divide').style.width = "calc(50% - 5px)"
document.getElementById('ruler').innerHTML = 'Лінійка'
map.pm.toggleControls()
RectangleGroup.clearLayers();
RectangleGroup.addTo(map);
map.pm.setGlobalOptions({
layerGroup: RectangleGroup
})
map.pm.setPathOptions({
color: '#b645ef',
fillColor: '#b645ef',
fillOpacity: 0.5,
radius: 500
});
if (map.pm.globalDragModeEnabled()) {
map.pm.disableDraw();
} else {
map.pm.enableDraw("Rectangle", {
snappable: true,
snapDistance: 20,
tooltips: false,
templineStyle: { color: '#b645ef' },
hintlineStyle: { color: '#b645ef', dashArray: [5, 5] }
});
}
},
ruler: (n) => {
n = prompt('На сколько поделить линейку ?', 2);
const polygon = L.PM.Utils.findLayers(RectangleGroup)[0]._latlngs;
let newCoords = polygon[0].map(function (coords) {
return [coords.lng, coords.lat];
});
newCoords.push(newCoords[0]);
let turfNew = turf.polygon([newCoords]);
console.log(turfNew);
var line = turf.polygonToLine(turfNew);
console.log(line.geometry.coordinates);
coords = line.geometry.coordinates;
for (let i = 1; i < n; i++) {
let a1 = (((coords[2][1] - coords[1][1]) / n) * i + coords[1][1])
let b1 = (((coords[2][0] - coords[1][0]) / n) * i + coords[1][0])
let a2 = (((coords[3][1] - coords[0][1]) / n) * i + coords[0][1])
let b2 = (((coords[3][0] - coords[0][0]) / n) * i + coords[0][0])
let c1 = (((coords[1][1] - coords[0][1]) / n) * i + coords[0][1])
let d1 = (((coords[1][0] - coords[0][0]) / n) * i + coords[0][0])
let c2 = (((coords[2][1] - coords[3][1]) / n) * i + coords[3][1])
let d2 = (((coords[2][0] - coords[3][0]) / n) * i + coords[3][0])
L.circleMarker([a1, b1], { radius: 2, color: 'red' }).addTo(RectangleGroup);
L.circleMarker([a2, b2], { radius: 2, color: 'red' }).addTo(RectangleGroup);
L.circleMarker([c1, d1], { radius: 2, color: 'red' }).addTo(RectangleGroup);
L.circleMarker([c2, d2], { radius: 2, color: 'red' }).addTo(RectangleGroup);
}
coords.forEach(function (feature) {
L.circleMarker([feature[1], feature[0]], { radius: 2, color: 'red' }).addTo(RectangleGroup);
});
},
dellEntranse: (id) => {
delete Constructor.info.apartments[id];
const pos = Constructor.info.entrance.map(e => e.editor_id).indexOf(id);
console.log(pos);
Constructor.info.entrance.splice(pos, 1);
console.log(id);
document.getElementById(`Entranse_${id}`).remove();
let Entranse = Object.keys(entransePolygonsGroup._layers);
let numsEntranse = Object.keys(entranseNumPolygonsGroup._layers);
console.log(Entranse, Entranse[pos]);
console.log(numsEntranse, numsEntranse[pos]);
entransePolygonsGroup.removeLayer(entransePolygonsGroup._layers[Entranse[pos]]);
entranseNumPolygonsGroup.removeLayer(entranseNumPolygonsGroup._layers[numsEntranse[pos]]);
Constructor.apartments.init();
},
editEntranse: (id) => {
const input = document.getElementById(`Entranse_input_${id}`);
const pos = Constructor.info.entrance.map(e => e.editor_id).indexOf(id);
Constructor.info.entrance[pos].entrance_number = Number(input.value) - 1;
Constructor.info.entrance[pos].title = `Під'їзд ${input.value}`;
let numsEntranse = Object.keys(entranseNumPolygonsGroup._layers);
let newIcon = L.divIcon({ className: 'entranse_number', html: `<div class="markerEntranse">${input.value}</div>` });
entranseNumPolygonsGroup._layers[numsEntranse[pos]].setIcon(newIcon);
input.setAttribute("value", input.value);
Constructor.apartments.init();
}
}
}

View File

@@ -0,0 +1,495 @@
.page-constructor {
width: calc(100% - 40px);
display: flex;
flex-direction: column;
align-items: center;
margin: 20px 20px 0 20px;
}
.page-constructor form>button {
border-radius: 6px;
background: var(--PrimaryColor);
color: var(--PrimaryColorText);
width: 100%;
height: 40px;
font-size: var(--FontSize3);
font-weight: 400;
margin: 20px 0;
text-transform: uppercase;
}
.page-constructor details {
border-radius: 10px;
width: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
margin-bottom: 20px;
background: var(--ColorThemes1);
color: var(--ColorThemes3);
border: 1px solid var(--ColorThemes2);
box-shadow: var(--shadow-l1);
}
.page-constructor>details[disabled] summary,
.page-constructor>details.disabled summary {
pointer-events: none;
user-select: none;
}
.page-constructor>details summary::-webkit-details-marker,
.page-constructor>details summary::marker {
display: none;
content: "";
}
.page-constructor summary {
width: calc(100% - 40px);
cursor: pointer;
color: var(--ColorThemes3);
border-radius: var(--border-radius);
font-size: var(--FontSize5);
font-weight: 300;
padding: 20px;
position: relative;
}
.page-constructor summary span {
font-weight: 500;
}
.page-constructor summary input {
font-weight: 500;
position: absolute;
right: 0;
top: 0;
padding: 10px;
margin: 13px;
font-size: var(--FontSize1);
background: var(--ColorThemes3);
color: var(--ColorThemes0);
border-radius: 6px;
width: 40px;
}
.page-constructor #info-form,
.page-constructor #map-form,
.page-constructor #area-form {
padding: 0 20px;
}
#details-info-type {
display: flex;
align-items: center;
justify-content: center;
}
#details-info-type>.tabs {
display: flex;
position: relative;
background-color: var(--ColorThemes0);
padding: 4px;
border-radius: 6px;
width: calc(100% - 8px);
z-index: 2;
}
#details-info-type>.tabs>input[type="radio"] {
display: none;
}
#details-info-type>.tabs>.tab {
display: flex;
align-items: center;
justify-content: center;
height: 40px;
width: calc(100% / 3);
cursor: pointer;
padding: 0 15px;
transition: 0.15s ease-in;
color: var(--ColorThemes3);
fill: var(--ColorThemes3);
flex-direction: row;
z-index: 2;
}
#details-info-type>.tabs>.tab>svg {
width: 20px;
height: 20px;
}
#details-info-type>.tabs>.tab>span {
margin-left: 6px;
font-size: var(--FontSize1);
font-weight: 400;
}
#details-info-type>.tabs>input[type="radio"]:checked+label {
color: var(--PrimaryColorText);
fill: var(--PrimaryColorText);
}
#details-info-type>.tabs>.glider {
position: absolute;
display: flex;
height: 40px;
width: calc((100% - 8px) / 3);
background-color: var(--PrimaryColor);
z-index: 1;
border-radius: 4px;
transition: 0.25s ease-out;
}
@media (min-width: 601px) {
#details-info-type>.tabs>input[id="info-type-house"]:checked~.glider {
transform: translateX(0);
}
#details-info-type>.tabs>input[id="info-type-homestead"]:checked~.glider {
transform: translateX(100%);
}
#details-info-type>.tabs>input[id="info-type-points"]:checked~.glider {
transform: translateX(200%);
}
}
@media (max-width: 600px) {
#details-info-type>.tabs {
flex-direction: column;
}
#details-info-type>.tabs>.tab {
width: calc(100% - 8px);
padding: 0 4px;
}
#details-info-type>.tabs>.glider {
width: calc(100% - 8px);
}
#details-info-type>.tabs>input[id="info-type-house"]:checked~.glider {
transform: translateY(0);
}
#details-info-type>.tabs>input[id="info-type-homestead"]:checked~.glider {
transform: translateY(100%);
}
#details-info-type>.tabs>input[id="info-type-points"]:checked~.glider {
transform: translateY(200%);
}
}
.page-constructor .details-info-input {
width: 100%;
display: flex;
margin: 20px 0;
align-items: flex-start;
flex-direction: column;
}
.page-constructor .details-info-input label {
display: flex;
justify-content: center;
flex-direction: column;
font-size: var(--FontSize1);
font-weight: 500;
margin-bottom: 5px;
}
.page-constructor .details-info-input input {
width: calc(100% - 10px);
min-width: 140px;
padding: 0 5px;
border-radius: 6px;
height: 30px;
background: var(--ColorThemes0);
color: var(--ColorThemes3);
font-size: var(--FontSize2);
}
.page-constructor #details-info-osm div {
display: flex;
align-items: center;
width: 100%;
}
.page-constructor #details-info-osm input {
width: calc(100% - 10px);
min-width: 140px;
padding: 0 5px;
border-radius: 6px;
height: 30px;
}
.page-constructor .details-info-input a {
height: 26px;
width: 26px;
margin-left: 10px;
}
.page-constructor .details-info-input a>svg {
height: 26px;
width: 26px;
fill: var(--ColorThemes3)
}
.page-constructor #list-area {
margin-top: 15px;
display: flex;
overflow: auto;
}
.page-constructor #list-area h3 {
text-align: center;
font-size: var(--FontSize5);
font-weight: 400;
margin: 10px;
padding: 7px;
color: var(--ColorThemes0);
background: var(--ColorThemes3);
border-radius: 4px;
}
.block-area {
min-height: 200px;
border: 1px solid var(--ColorThemes3);
border-style: dashed;
border-radius: 6px;
margin: 0 10px 10px 0;
}
.addFloors,
.addApartment {
display: flex;
position: relative;
width: 34px;
height: 34px;
background: var(--PrimaryColor);
color: var(--PrimaryColorText);
margin: 25px;
border-radius: 50%;
align-items: center;
justify-content: center;
font-size: 30px;
cursor: pointer;
}
.addFloors>svg,
.addApartment>svg {
width: 20px;
height: 20px;
fill: var(--PrimaryColorText);
transform: rotate(45deg);
}
.block-apartments-floors {
position: relative;
display: flex;
width: calc(100% - 22px);
border: 1px solid var(--ColorThemes3);
margin: 10px;
border-radius: 4px;
}
.block-apartments-floors h2 {
position: absolute;
width: 65px;
right: -1px;
top: -1px;
margin: 0;
background: var(--ColorThemes3);
color: var(--ColorThemes2);
border-radius: 0 4px 0 4px;
font-size: var(--FontSize1);
padding: 2px 4px;
text-align: center;
}
.block-apartments-number {
display: flex;
position: relative;
width: 60px;
height: 60px;
background: var(--ColorThemes1);
border: 2px solid var(--PrimaryColor);
margin: 10px;
border-radius: 4px;
align-items: center;
justify-content: center;
}
.block-apartments-number input {
width: 50px;
height: 50px;
font-size: var(--FontSize5);
font-weight: 400;
text-align: center;
color: var(--ColorThemes3);
background: 0;
}
.block-apartments-number button {
position: absolute;
top: 0;
right: 0;
width: 20px;
height: 20px;
border-radius: 0 4px 0 4px;
background: var(--PrimaryColor);
font-size: var(--FontSize5);
margin: -2px;
border: 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.block-apartments-number button>svg {
width: 16px;
height: 16px;
fill: var(--PrimaryColorText);
}
.block-map {
width: 100%;
height: 500px;
border-radius: 6px;
overflow: hidden;
}
#map {
width: 100%;
height: 100%;
}
.entranse_number {
left: -10px !important;
top: -10px !important;
}
.markerEntranse {
background: hsl(0deg 0% 52.12% / 90%);
font-size: 24px;
border: 2px solid #676767;
border-radius: 2px;
display: flex !important;
justify-content: center;
align-items: center;
color: #fff;
min-width: 30px;
min-height: 30px;
height: 30px;
width: 30px;
}
.editor-buttons {
margin-top: 15px;
}
.editor-buttons>button {
width: 100%;
min-height: 30px;
margin: 5px 0;
border: 0;
color: var(--PrimaryColorText);
display: flex;
align-items: center;
justify-content: center;
background: var(--PrimaryColor);
text-transform: uppercase;
cursor: pointer;
border-radius: 6px;
font-weight: 400;
font-size: var(--FontSize1);
}
.editor-buttons>div {
display: flex;
width: 100%;
margin: 10px 0;
height: 30px;
justify-content: space-between;
}
.editor-buttons>div>button {
background: var(--ColorThemes3);
color: var(--ColorThemes1);
width: 100%;
margin: 0;
border-radius: 6px;
text-transform: uppercase;
font-weight: 400;
font-size: var(--FontSize1);
}
.page-constructor #list-entranse,
.page-constructor #list-homestead {
width: 100%;
min-height: 86px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
overflow-x: initial;
overflow-y: auto;
border: 1px solid var(--ColorThemes3);
background: 0;
border-radius: 6px;
border-style: dashed;
margin: 10px 0;
}
.page-constructor #list-entranse>.house,
.page-constructor #list-homestead>.house {
display: flex;
position: relative;
width: 60px;
height: 60px;
background: var(--ColorThemes1);
border: 2px solid var(--PrimaryColor);
margin: 10px;
border-radius: 4px;
align-items: center;
justify-content: center;
}
.page-constructor #list-entranse>.house>input,
.page-constructor #list-homestead>.house>input {
width: 50px;
height: 50px;
font-size: var(--FontSize5);
font-weight: 400;
text-align: center;
color: var(--ColorThemes3);
background: 0;
}
.page-constructor #list-entranse>.house>button,
.page-constructor #list-homestead>.house>button {
position: absolute;
top: 0;
right: 0;
width: 20px;
height: 20px;
border-radius: 0 4px 0 4px;
background: var(--PrimaryColor);
font-size: var(--FontSize5);
margin: -2px;
border: 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.page-constructor #list-entranse>.house>button>svg,
.page-constructor #list-homestead>.house>button>svg {
width: 16px;
height: 16px;
fill: var(--PrimaryColorText);
}