Переработаны роутеры приложения
Переписано APi WebSocket для работы с новыми роутерами
This commit is contained in:
74
README.md
74
README.md
@@ -68,19 +68,10 @@ cd /home/username/webapps/sheep-service.com
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose pull
|
docker-compose pull
|
||||||
docker-compose -p sheep-service up --build -d api ws web
|
docker-compose -p sheep-service up --build -d
|
||||||
|
docker-compose -p sheep-service up --build -d --scale api=5 --scale ws=5 --scale web=2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Запуск з вбудованим NGINX
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose --profile with-nginx -p sheep-service up --build -d
|
|
||||||
```
|
|
||||||
|
|
||||||
💡 **Важливо:** Команду `docker-compose --profile with-nginx ...` використовують тільки якщо на сервері **не встановлений та не планується встановлення NGINX**. В цьому випадку буде запущений **вбудований NGINX на порті 80**, і **не потрібно встановлювати окремо NGINX та Certbot**.
|
|
||||||
|
|
||||||
💡 **Порада:** Перевірте, що порти 4000, 4001, 4002 відкриті або перенаправлені на сервері.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Встановлення NGINX
|
## 5. Встановлення NGINX
|
||||||
@@ -156,71 +147,14 @@ server {
|
|||||||
|
|
||||||
server_name sheep-service.com www.sheep-service.com;
|
server_name sheep-service.com www.sheep-service.com;
|
||||||
|
|
||||||
error_log /home/username/webapps/log/sheep-service.com.error.log error;
|
|
||||||
access_log /home/username/webapps/log/sheep-service.com.access.log;
|
|
||||||
|
|
||||||
root /home/username/webapps/sheep-service.com;
|
|
||||||
index index.html;
|
|
||||||
error_page 404 /404.html;
|
|
||||||
|
|
||||||
# Захист службових файлів
|
|
||||||
location ~ /\.(git|env) {
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Загальні CORS-заголовки
|
|
||||||
map $request_method $cors_preflight {
|
|
||||||
OPTIONS 1;
|
|
||||||
default 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# API
|
|
||||||
location /api/ {
|
|
||||||
proxy_pass http://127.0.0.1:4000;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
|
|
||||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
||||||
|
|
||||||
if ($cors_preflight) {
|
|
||||||
add_header 'Access-Control-Max-Age' 1728000;
|
|
||||||
add_header 'Content-Type' 'text/plain; charset=utf-8';
|
|
||||||
add_header 'Content-Length' 0;
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# WebSocket
|
|
||||||
location /ws {
|
|
||||||
proxy_pass http://127.0.0.1:4001;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Frontend
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://127.0.0.1:4002;
|
proxy_pass http://127.0.0.1:4000$request_uri;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
if ($request_method = 'GET') {
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
|
|
||||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
12
api/app.js
12
api/app.js
@@ -2,11 +2,17 @@ const express = require('express');
|
|||||||
const app = express();
|
const app = express();
|
||||||
const routes = require('./routes/index');
|
const routes = require('./routes/index');
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
// const cors = require('cors');
|
const cors = require('cors');
|
||||||
|
|
||||||
const port = process.env.API_PORT || 4000;
|
const port = 4003;
|
||||||
|
|
||||||
// app.use(cors())
|
app.use(cors({
|
||||||
|
origin: "*",
|
||||||
|
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
||||||
|
allowedHeaders: ["DNT","User-Agent","X-Requested-With","If-Modified-Since","Cache-Control","Content-Type","Range","Authorization"],
|
||||||
|
credentials: true,
|
||||||
|
maxAge: 1728000
|
||||||
|
}));
|
||||||
app.use(express.json({ limit: '50mb' }));
|
app.use(express.json({ limit: '50mb' }));
|
||||||
app.use(express.urlencoded({ limit: '50mb' }));
|
app.use(express.urlencoded({ limit: '50mb' }));
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
services:
|
services:
|
||||||
|
web:
|
||||||
|
image: sheep-service/web
|
||||||
|
build: ./web
|
||||||
|
restart: always
|
||||||
|
expose:
|
||||||
|
- "4002"
|
||||||
|
volumes:
|
||||||
|
- "${CARDS_PATH:-./data}:/app/data/cards"
|
||||||
|
- "${MAP_PATH:-./data}:/app/data/map"
|
||||||
|
environment:
|
||||||
|
- CARDS_PATH=/app/data/cards/
|
||||||
|
- MAP_PATH=/app/data/map/
|
||||||
|
networks:
|
||||||
|
- network
|
||||||
|
|
||||||
api:
|
api:
|
||||||
container_name: sheep-service-api
|
|
||||||
image: sheep-service/api
|
image: sheep-service/api
|
||||||
build: ./api
|
build: ./api
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
expose:
|
||||||
- "4000:4000"
|
- "4003"
|
||||||
volumes:
|
volumes:
|
||||||
- "${DB_PATH:-./data}:/app/data"
|
- "${DB_PATH:-./data}:/app/data"
|
||||||
- "${CARDS_PATH:-./data}:/app/data/cards"
|
- "${CARDS_PATH:-./data}:/app/data/cards"
|
||||||
@@ -21,12 +35,11 @@ services:
|
|||||||
- network
|
- network
|
||||||
|
|
||||||
ws:
|
ws:
|
||||||
container_name: sheep-service-ws
|
|
||||||
image: sheep-service/ws
|
image: sheep-service/ws
|
||||||
build: ./ws
|
build: ./ws
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
expose:
|
||||||
- "4001:4001"
|
- "4004"
|
||||||
volumes:
|
volumes:
|
||||||
- "${DB_PATH:-./data}:/app/data"
|
- "${DB_PATH:-./data}:/app/data"
|
||||||
environment:
|
environment:
|
||||||
@@ -34,30 +47,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- network
|
- network
|
||||||
|
|
||||||
web:
|
|
||||||
container_name: sheep-service-web
|
|
||||||
image: sheep-service/web
|
|
||||||
build: ./web
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "4002:4002"
|
|
||||||
volumes:
|
|
||||||
- "${CARDS_PATH:-./data}:/app/data/cards"
|
|
||||||
- "${MAP_PATH:-./data}:/app/data/map"
|
|
||||||
environment:
|
|
||||||
- CARDS_PATH=/app/data/cards/
|
|
||||||
- MAP_PATH=/app/data/map/
|
|
||||||
networks:
|
|
||||||
- network
|
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
profiles: ["with-nginx"]
|
|
||||||
image: nginx:latest
|
image: nginx:latest
|
||||||
container_name: sheep-service-nginx
|
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "${HTTP_PORT}:80"
|
||||||
- "443:443"
|
- "${HTTPS_PORT}:443"
|
||||||
volumes:
|
volumes:
|
||||||
- ./nginx/default.conf.template:/etc/nginx/templates/default.conf.template:ro
|
- ./nginx/default.conf.template:/etc/nginx/templates/default.conf.template:ro
|
||||||
- ./nginx/certs:/etc/letsencrypt/live
|
- ./nginx/certs:/etc/letsencrypt/live
|
||||||
@@ -74,4 +69,4 @@ volumes:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
network:
|
network:
|
||||||
external: false
|
driver: bridge
|
||||||
@@ -1,3 +1,21 @@
|
|||||||
|
upstream frontend {
|
||||||
|
server web:4002;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream api_backend {
|
||||||
|
server api:4003;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream ws_backend {
|
||||||
|
server ws:4004;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Загальні CORS-заголовки
|
||||||
|
map $request_method $cors_preflight {
|
||||||
|
OPTIONS 1;
|
||||||
|
default 0;
|
||||||
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
@@ -16,38 +34,20 @@ server {
|
|||||||
deny all;
|
deny all;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Загальні CORS-заголовки
|
|
||||||
map $request_method $cors_preflight {
|
|
||||||
OPTIONS 1;
|
|
||||||
default 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# API
|
# API
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://api:4000;
|
proxy_pass http://api_backend$request_uri;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
|
|
||||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
||||||
|
|
||||||
if ($cors_preflight) {
|
|
||||||
add_header 'Access-Control-Max-Age' 1728000;
|
|
||||||
add_header 'Content-Type' 'text/plain; charset=utf-8';
|
|
||||||
add_header 'Content-Length' 0;
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# WebSocket
|
# WebSocket
|
||||||
location /ws {
|
location /ws {
|
||||||
proxy_pass http://ws:4001;
|
proxy_pass http://ws_backend$request_uri;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
@@ -56,18 +56,11 @@ server {
|
|||||||
|
|
||||||
# Frontend
|
# Frontend
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://web:4002;
|
proxy_pass http://frontend$request_uri;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
if ($request_method = 'GET') {
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
|
|
||||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,35 +73,38 @@
|
|||||||
<script src="/lib/pages/home/script.js" defer></script>
|
<script src="/lib/pages/home/script.js" defer></script>
|
||||||
<link href="/lib/pages/home/style.css" rel="stylesheet" />
|
<link href="/lib/pages/home/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/territory/script.js" defer></script>
|
<script src="/lib/pages/territory/list/script.js" defer></script>
|
||||||
<link href="/lib/pages/territory/style.css" rel="stylesheet" />
|
<link href="/lib/pages/territory/list/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/territory_manager/script.js" defer></script>
|
<script src="/lib/pages/territory/manager/script.js" defer></script>
|
||||||
<link href="/lib/pages/territory_manager/style.css" rel="stylesheet" />
|
<link href="/lib/pages/territory/manager/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/territory_history/script.js" defer></script>
|
<script src="/lib/pages/territory/history/script.js" defer></script>
|
||||||
<link href="/lib/pages/territory_history/style.css" rel="stylesheet" />
|
<link href="/lib/pages/territory/history/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/card/script.js" defer></script>
|
<script src="/lib/pages/territory/constructor/script.js" defer></script>
|
||||||
<link href="/lib/pages/card/style.css" rel="stylesheet" />
|
<link href="/lib/pages/territory/constructor/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script src="/lib/pages/territory/editor/script.js" defer></script>
|
||||||
|
<link href="/lib/pages/territory/editor/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script src="/lib/pages/territory/card/script.js" defer></script>
|
||||||
|
<link href="/lib/pages/territory/card/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/options/script.js" defer></script>
|
<script src="/lib/pages/options/script.js" defer></script>
|
||||||
<link href="/lib/pages/options/style.css" rel="stylesheet" />
|
<link href="/lib/pages/options/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/schedule/script.js" defer></script>
|
|
||||||
<link href="/lib/pages/schedule/style.css" rel="stylesheet" />
|
|
||||||
|
|
||||||
<script src="/lib/pages/sheeps/script.js" defer></script>
|
<script src="/lib/pages/sheeps/script.js" defer></script>
|
||||||
<link href="/lib/pages/sheeps/style.css" rel="stylesheet" />
|
<link href="/lib/pages/sheeps/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/constructor/script.js" defer></script>
|
<script src="/lib/pages/stand/list/script.js" defer></script>
|
||||||
<link href="/lib/pages/constructor/style.css" rel="stylesheet" />
|
<link href="/lib/pages/stand/list/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/editor/script.js" defer></script>
|
<script src="/lib/pages/stand/card/script.js" defer></script>
|
||||||
<link href="/lib/pages/editor/style.css" rel="stylesheet" />
|
<link href="/lib/pages/stand/card/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/pages/stand/script.js" defer></script>
|
<script src="/lib/pages/schedule/script.js" defer></script>
|
||||||
<link href="/lib/pages/stand/style.css" rel="stylesheet" />
|
<link href="/lib/pages/schedule/style.css" rel="stylesheet" />
|
||||||
|
|
||||||
<script src="/lib/app.js" defer></script>
|
<script src="/lib/app.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -1,452 +0,0 @@
|
|||||||
|
|
||||||
const Card = {
|
|
||||||
socket: null,
|
|
||||||
reconnectTimeout: null,
|
|
||||||
reconnectNumber: 0,
|
|
||||||
username: null,
|
|
||||||
listEntrances: [],
|
|
||||||
listApartment: [],
|
|
||||||
color_status: [
|
|
||||||
["var(--ColorThemes2)", "var(--ColorThemes3)"],
|
|
||||||
["#fbf1e0", "#ff8300"],
|
|
||||||
["#fce3e2", "#ff0000"],
|
|
||||||
["#d7ddec", "#2919bd"],
|
|
||||||
["#d5e9dd", "#11a568"],
|
|
||||||
["#d7ebfa", "#3fb4fc"],
|
|
||||||
["#e8dbf5", "#b381eb"]
|
|
||||||
],
|
|
||||||
init: async (type, id) => {
|
|
||||||
let html = await fetch('/lib/pages/card/index.html').then((response) => response.text());
|
|
||||||
app.innerHTML = html;
|
|
||||||
|
|
||||||
house = id;
|
|
||||||
|
|
||||||
if (Card.socket) Card.socket.close(1000, "Перезапуск соединения");
|
|
||||||
|
|
||||||
Card.sort(localStorage.getItem('sort_mode'), false)
|
|
||||||
|
|
||||||
if (type == "house") {
|
|
||||||
Card.getEntrances({ update: false });
|
|
||||||
Card.cloud.start(makeid(6));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Закриття вікно popup при натисканні за його межі
|
|
||||||
const block_card = document.getElementById('card-new-date');
|
|
||||||
const mess = block_card.querySelector('.mess');
|
|
||||||
if (!block_card.dataset.listenerAdded) {
|
|
||||||
block_card.addEventListener('click', function (event) {
|
|
||||||
if (!mess.contains(event.target)) {
|
|
||||||
Card.dateEditor.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
block_card.dataset.listenerAdded = 'true';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cloud: {
|
|
||||||
status: (mode) => {
|
|
||||||
|
|
||||||
let cloud_1 = document.getElementById('cloud_1');
|
|
||||||
let cloud_2 = document.getElementById('cloud_2');
|
|
||||||
let cloud_3 = document.getElementById('cloud_3');
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case 'sync':
|
|
||||||
cloud_1.setAttribute('data-state', 'active');
|
|
||||||
cloud_2.setAttribute('data-state', '');
|
|
||||||
cloud_3.setAttribute('data-state', '');
|
|
||||||
break;
|
|
||||||
case 'ok':
|
|
||||||
cloud_1.setAttribute('data-state', '');
|
|
||||||
cloud_2.setAttribute('data-state', 'active');
|
|
||||||
cloud_3.setAttribute('data-state', '');
|
|
||||||
break;
|
|
||||||
case 'err':
|
|
||||||
cloud_1.setAttribute('data-state', '');
|
|
||||||
cloud_2.setAttribute('data-state', '');
|
|
||||||
cloud_3.setAttribute('data-state', 'active');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: (name) => {
|
|
||||||
if (!name) return;
|
|
||||||
|
|
||||||
Card.username = name;
|
|
||||||
|
|
||||||
let uuid = localStorage.getItem("uuid");
|
|
||||||
Card.socket = new WebSocket(`${CONFIG.wss}?uuid=${uuid}`);
|
|
||||||
|
|
||||||
Card.socket.onopen = function (e) {
|
|
||||||
console.log("[WebSocket | open] З'єднання встановлено");
|
|
||||||
Card.cloud.status('ok');
|
|
||||||
|
|
||||||
const message = {
|
|
||||||
event: 'connection',
|
|
||||||
id: getTimeInSeconds(),
|
|
||||||
date: getTimeInSeconds(),
|
|
||||||
uuid: uuid,
|
|
||||||
username: name,
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
entrance_id: 1,
|
|
||||||
apartment_number: 1,
|
|
||||||
title: "1",
|
|
||||||
group_number: 1,
|
|
||||||
status: 1,
|
|
||||||
description: "",
|
|
||||||
created_at: 1727541827,
|
|
||||||
updated_at: 1727541827
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Card.socket.send(JSON.stringify(message));
|
|
||||||
|
|
||||||
Card.reconnectNumber = 0;
|
|
||||||
clearTimeout(Card.reconnectTimeout);
|
|
||||||
};
|
|
||||||
|
|
||||||
Card.socket.onmessage = function (event) {
|
|
||||||
let data = JSON.parse(event.data)
|
|
||||||
|
|
||||||
if (data.event == 'connection') {
|
|
||||||
if (data.username == Card.username) return
|
|
||||||
|
|
||||||
console.log(`Доданий новий користувач на ім'я ${data.username}`);
|
|
||||||
} else if (data.event == 'message') {
|
|
||||||
Card.cloud.update(data);
|
|
||||||
|
|
||||||
if (data.username == Card.username) return
|
|
||||||
|
|
||||||
console.log(`${data.username} пише: `, data.data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Card.socket.onclose = function (event) {
|
|
||||||
if (event.wasClean) {
|
|
||||||
console.log(`[WebSocket | close] З'єднання закрито чисто, код =${event.code} причина=${event.reason}`);
|
|
||||||
Card.cloud.status('err');
|
|
||||||
} else {
|
|
||||||
console.log(`[WebSocket | close] З'єднання перервано`);
|
|
||||||
Card.cloud.status('err');
|
|
||||||
|
|
||||||
Card.reconnectTimeout = setTimeout(function () {
|
|
||||||
Card.reconnectNumber++;
|
|
||||||
if (Card.reconnectNumber > 5) {
|
|
||||||
Card.reconnectNumber = 0;
|
|
||||||
clearTimeout(Card.reconnectTimeout);
|
|
||||||
|
|
||||||
const result = confirm(`З'єднання розірвано! Перепідключитись?`);
|
|
||||||
if (result) {
|
|
||||||
Card.getEntrances({ update: true });
|
|
||||||
Card.cloud.start(Card.username);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Card.getEntrances({ update: true });
|
|
||||||
Card.cloud.start(Card.username);
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Card.socket.onerror = function (error) {
|
|
||||||
console.log(`[WebSocket | error]`);
|
|
||||||
Card.cloud.status('err');
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mess: ({ number, id, update, time }) => {
|
|
||||||
const pos = Card.listApartment[number].map(e => e.id).indexOf(id);
|
|
||||||
let apartment = Card.listApartment[number][pos];
|
|
||||||
|
|
||||||
|
|
||||||
let status = document.getElementById(`status_${id}`);
|
|
||||||
let description = document.getElementById(`description_${id}`);
|
|
||||||
|
|
||||||
let date = () => {
|
|
||||||
if (!update && !time) {
|
|
||||||
return apartment.updated_at;
|
|
||||||
} else if (update && !time) {
|
|
||||||
return getTimeInSeconds();
|
|
||||||
} else if (update && time) {
|
|
||||||
return getTimeInSeconds(time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apartment.description = description.value;
|
|
||||||
apartment.status = Number(status.value);
|
|
||||||
apartment.updated_at = date();
|
|
||||||
|
|
||||||
status.style.backgroundColor = Card.color_status[status.value][0];
|
|
||||||
status.style.color = Card.color_status[status.value][1];
|
|
||||||
status.style.border = `1px solid ${Card.color_status[status.value][1]}`;
|
|
||||||
|
|
||||||
let message = {
|
|
||||||
event: 'message',
|
|
||||||
id: getTimeInSeconds(),
|
|
||||||
date: getTimeInSeconds(),
|
|
||||||
|
|
||||||
username: Card.username,
|
|
||||||
data: {
|
|
||||||
id: apartment.id,
|
|
||||||
entrance_id: apartment.entrance_id,
|
|
||||||
apartment_number: apartment.apartment_number,
|
|
||||||
title: apartment.title,
|
|
||||||
group_number: apartment.group_number,
|
|
||||||
status: apartment.status,
|
|
||||||
description: apartment.description,
|
|
||||||
updated_at: apartment.updated_at,
|
|
||||||
sheep_id: USER.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Card.socket && Card.socket.readyState === WebSocket.OPEN) {
|
|
||||||
Card.socket.send(JSON.stringify(message));
|
|
||||||
} else {
|
|
||||||
console.warn("WebSocket не підключено. Повідомлення не надіслано.");
|
|
||||||
const result = confirm(`З'єднання розірвано! Перепідключитись?`);
|
|
||||||
if (result) {
|
|
||||||
Card.getEntrances({ update: true });
|
|
||||||
Card.start(Card.username);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update) {
|
|
||||||
let sort_mode = localStorage.getItem('sort_mode') ?? '1';
|
|
||||||
|
|
||||||
if (sort_mode == '3') {
|
|
||||||
let child = document.getElementById(`card_${apartment.id}`);
|
|
||||||
document.getElementById(`apartments_${apartment.entrance_id}`).removeChild(child);
|
|
||||||
document.getElementById(`apartments_${apartment.entrance_id}`).append(child);
|
|
||||||
child.style.border = "1px solid var(--PrimaryColor)";
|
|
||||||
} else if (sort_mode == '4') {
|
|
||||||
let child = document.getElementById(`card_${apartment.id}`);
|
|
||||||
document.getElementById(`apartments_${apartment.entrance_id}`).removeChild(child);
|
|
||||||
document.getElementById(`apartments_${apartment.entrance_id}`).prepend(child);
|
|
||||||
child.style.border = "1px solid var(--PrimaryColor)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
update: (message) => {
|
|
||||||
if (!document.getElementById(`status_${message.data.id}`)) return;
|
|
||||||
|
|
||||||
document.getElementById(`card_${message.data.id}`).style.backgroundColor = Card.color_status[message.data.status][0];
|
|
||||||
document.getElementById(`card_${message.data.id}`).style.color = Card.color_status[message.data.status][1];
|
|
||||||
document.getElementById(`card_${message.data.id}`).style.border = `1px solid ${Card.color_status[message.data.status][1]}`;
|
|
||||||
|
|
||||||
document.getElementById(`status_${message.data.id}`).style.backgroundColor = Card.color_status[message.data.status][0];
|
|
||||||
document.getElementById(`status_${message.data.id}`).style.color = Card.color_status[message.data.status][1];
|
|
||||||
document.getElementById(`status_${message.data.id}`).style.border = `1px solid ${Card.color_status[message.data.status][1]}`;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById(`status_${message.data.id}`).value = message.data.status;
|
|
||||||
document.getElementById(`description_${message.data.id}`).value = message.data.description;
|
|
||||||
document.getElementById(`date_text_${message.data.id}`).innerText = formattedDateTime(message.data.updated_at);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getEntrances: ({ house_id = house, update = false }) => {
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}/house/${house_id}/entrances`;
|
|
||||||
fetch(URL, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(function (response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function (data) {
|
|
||||||
Card.listEntrances = data;
|
|
||||||
|
|
||||||
const element_list = document.getElementById('list');
|
|
||||||
|
|
||||||
if (update) {
|
|
||||||
for (let i = 0; i < Card.listEntrances.length; i++) {
|
|
||||||
const element = Card.listEntrances[i];
|
|
||||||
Card.getApartment({ id: element.id, number: element.entrance_number, update: update });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
element_list.innerHTML = "";
|
|
||||||
for (let i = 0; i < Card.listEntrances.length; i++) {
|
|
||||||
const element = Card.listEntrances[i];
|
|
||||||
|
|
||||||
let status = () => {
|
|
||||||
if ((element.history.name == "Групова" || element.history.name == USER.name) && element.working) return "open";
|
|
||||||
else if (USER.mode == 2 || (USER.mode == 1 && USER.possibilities.can_manager_territory)) return "close";
|
|
||||||
else return "style='display: none;'"
|
|
||||||
}
|
|
||||||
|
|
||||||
let statusIcon = () => {
|
|
||||||
if ((element.history.name == "Групова" || element.history.name == USER.name) && element.working) return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M 12 1 C 9.1277778 1 6.7189086 3.0461453 6.1230469 5.7871094 L 8.078125 6.2128906 C 8.4822632 4.3538547 10.072222 3 12 3 C 14.27619 3 16 4.7238095 16 7 L 16 8 L 6 8 C 4.9069372 8 4 8.9069372 4 10 L 4 20 C 4 21.093063 4.9069372 22 6 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 10 C 20 8.9069372 19.093063 8 18 8 L 18 7 C 18 3.6761905 15.32381 1 12 1 z M 6 10 L 18 10 L 18 20 L 6 20 L 6 10 z M 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 z"/></svg>'
|
|
||||||
else return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 12 1 C 8.6761905 1 6 3.6761905 6 7 L 6 8 C 4.9069372 8 4 8.9069372 4 10 L 4 20 C 4 21.093063 4.9069372 22 6 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 10 C 20 8.9069372 19.093063 8 18 8 L 18 7 C 18 3.6761905 15.32381 1 12 1 z M 12 3 C 14.27619 3 16 4.7238095 16 7 L 16 8 L 8 8 L 8 7 C 8 4.7238095 9.7238095 3 12 3 z M 6 10 L 18 10 L 18 20 L 6 20 L 6 10 z M 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 z"/></svg>'
|
|
||||||
}
|
|
||||||
|
|
||||||
element_list.innerHTML += `
|
|
||||||
<details ${status()}>
|
|
||||||
<summary>
|
|
||||||
<p>${element.title}</p>
|
|
||||||
${statusIcon()}
|
|
||||||
</summary>
|
|
||||||
<div id="apartments_${element.id}" class="apartments_list">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
`;
|
|
||||||
Card.getApartment({ id: element.id, number: element.entrance_number, update: false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
getApartment: ({ id, number, update }) => {
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}/apartment/${id}`;
|
|
||||||
fetch(URL, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(function (response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function (data) {
|
|
||||||
Card.listApartment[number] = data;
|
|
||||||
|
|
||||||
if (update) {
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
const element = data[i];
|
|
||||||
|
|
||||||
let now = new Date(element.updated_at);
|
|
||||||
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
|
|
||||||
now = now.toISOString().slice(0, 16)
|
|
||||||
|
|
||||||
document.getElementById(`card_${element.id}`).setAttribute('style', `border: 1px solid ${Card.color_status[element.status][1]};background: ${Card.color_status[element.status][0]};color: ${Card.color_status[element.status][1]};`);
|
|
||||||
document.getElementById(`status_${element.id}`).value = element.status;
|
|
||||||
document.getElementById(`status_${element.id}`).setAttribute('style', `background-color: ${Card.color_status[element.status][0]}; color: ${Card.color_status[element.status][1]}; border: 1px solid ${Card.color_status[element.status][1]};`);
|
|
||||||
document.getElementById(`date_${element.id}`).setAttribute('onclick', `Card.dateEditor.open({id: ${element.id}, number: ${number}, updated_at: ${element.updated_at}})`);
|
|
||||||
document.getElementById(`date_text_${element.id}`).innerText = element.updated_at ? formattedDateTime(element.updated_at) : "0.0.0000 00:00";
|
|
||||||
document.getElementById(`description_${element.id}`).innerText = element.description ?? "";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let sort_mode = localStorage.getItem('sort_mode') ?? 1;
|
|
||||||
|
|
||||||
if (sort_mode == "1")
|
|
||||||
data.sort((a, b) => a.apartment_number - b.apartment_number);
|
|
||||||
else if (sort_mode == "2")
|
|
||||||
data.sort((a, b) => b.apartment_number - a.apartment_number);
|
|
||||||
else if (sort_mode == "3")
|
|
||||||
data.sort((a, b) => a.updated_at - b.updated_at);
|
|
||||||
else if (sort_mode == "4")
|
|
||||||
data.sort((a, b) => b.updated_at - a.updated_at);
|
|
||||||
else
|
|
||||||
data.sort((a, b) => a.apartment_number - b.apartment_number);
|
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
const element = data[i];
|
|
||||||
|
|
||||||
let now = new Date(element.updated_at);
|
|
||||||
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
|
|
||||||
now = now.toISOString().slice(0, 16)
|
|
||||||
|
|
||||||
let disabled = () => {
|
|
||||||
if (USER.possibilities.can_manager_territory) return '';
|
|
||||||
else if (element.status == 2) return "disabled";
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById(`apartments_${id}`).innerHTML += `
|
|
||||||
<div id="card_${element.id}" style="border: 1px solid ${Card.color_status[element.status][1]};background: ${Card.color_status[element.status][0]};color: ${Card.color_status[element.status][1]};">
|
|
||||||
<div class="info">
|
|
||||||
<span>кв.${element.title}</span>
|
|
||||||
<select id="status_${element.id}" onchange="Card.cloud.mess({ number: ${number}, id: ${element.id}, update: true})" style="background-color: ${Card.color_status[element.status][0]}; color: ${Card.color_status[element.status][1]}; border: 1px solid ${Card.color_status[element.status][1]};" ${disabled()}>
|
|
||||||
<option value="0" ${element.status == 0 ? "selected" : ""}></option>
|
|
||||||
<option value="1" ${element.status == 1 ? "selected" : ""}>Не цікавить</option>
|
|
||||||
<option value="2" ${element.status == 2 ? "selected" : ""}>Не заходити (Груба відмова)</option>
|
|
||||||
<option value="3" ${element.status == 3 ? "selected" : ""}>Нема домофона</option>
|
|
||||||
<option value="4" ${element.status == 4 ? "selected" : ""}>Повторна відвідина</option>
|
|
||||||
<option value="5" ${element.status == 5 ? "selected" : ""}>Немає вдома</option>
|
|
||||||
<option value="6" ${element.status == 6 ? "selected" : ""}>Свідки Єгови</option>
|
|
||||||
</select>
|
|
||||||
<button placeholder="Дата" id="date_${element.id}" onclick="Card.dateEditor.open({id: ${element.id}, number: ${number}, updated_at: ${element.updated_at}})" ${disabled()}>
|
|
||||||
<p id="date_text_${element.id}">${element.updated_at ? formattedDateTime(element.updated_at) : "0.0.0000 00:00"}</p>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
|
|
||||||
<path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<textarea onchange="Card.cloud.mess({ number: ${number}, id: ${element.id}})" id="description_${element.id}" placeholder="Нотатки..." ${disabled()}}>${element.description ?? ""}</textarea>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
|
||||||
sort: (mode, load) => {
|
|
||||||
const sortIds = ['sort_1', 'sort_2', 'sort_3', 'sort_4'];
|
|
||||||
|
|
||||||
sortIds.forEach(id => {
|
|
||||||
const el = document.getElementById(id);
|
|
||||||
if (el) el.setAttribute('data-state', '');
|
|
||||||
});
|
|
||||||
|
|
||||||
let index = parseInt(mode, 10);
|
|
||||||
if (isNaN(index) || index < 1 || index > 4) index = 1;
|
|
||||||
|
|
||||||
const activeEl = document.getElementById(`sort_${index}`);
|
|
||||||
if (activeEl) activeEl.setAttribute('data-state', 'active');
|
|
||||||
|
|
||||||
localStorage.setItem('sort_mode', index.toString());
|
|
||||||
|
|
||||||
if (!load) Card.getEntrances({ update: false });
|
|
||||||
},
|
|
||||||
dateEditor: {
|
|
||||||
open: ({ id, number, updated_at }) => {
|
|
||||||
const block = document.getElementById('card-new-date');
|
|
||||||
const card_new_date_input = document.getElementById('card-new-date-input');
|
|
||||||
const card_new_date_button = document.getElementById('card-new-date-button');
|
|
||||||
|
|
||||||
let now = new Date(updated_at);
|
|
||||||
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
|
|
||||||
now = now.toISOString().slice(0, 16)
|
|
||||||
|
|
||||||
card_new_date_input.value = now;
|
|
||||||
card_new_date_input.setAttribute("onchange", `Card.dateEditor.edit({ id: ${id}, number: ${number} })`)
|
|
||||||
card_new_date_button.setAttribute("onclick", `Card.dateEditor.edit({ id: ${id}, number: ${number}, type: 'now'})`)
|
|
||||||
|
|
||||||
block.style.display = "";
|
|
||||||
setTimeout(() => {
|
|
||||||
block.style.opacity = "1";
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
},
|
|
||||||
close: () => {
|
|
||||||
const block = document.getElementById('card-new-date');
|
|
||||||
|
|
||||||
block.style.opacity = "0";
|
|
||||||
setTimeout(() => {
|
|
||||||
block.style.display = "none";
|
|
||||||
}, 200)
|
|
||||||
},
|
|
||||||
edit: ({ id, number, type }) => {
|
|
||||||
const card_new_date_input = document.getElementById('card-new-date-input');
|
|
||||||
|
|
||||||
if (type == "now") {
|
|
||||||
Card.cloud.mess({ number: number, id: id, update: true });
|
|
||||||
} else {
|
|
||||||
if (card_new_date_input.value) {
|
|
||||||
let date = new Date(card_new_date_input.value);
|
|
||||||
const timestamp = date.getTime();
|
|
||||||
Card.cloud.mess({ number: number, id: id, update: true, time: timestamp });
|
|
||||||
} else {
|
|
||||||
Card.cloud.mess({ number: number, id: id });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Card.dateEditor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
<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>
|
|
||||||
@@ -1,731 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,495 +0,0 @@
|
|||||||
.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);
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
<div class="page-editor">
|
|
||||||
<details id="details-info" open>
|
|
||||||
<summary>
|
|
||||||
<span>Крок 1.</span> Інформація про будинок, територію, точки на карті
|
|
||||||
</summary>
|
|
||||||
<form id="info-form">
|
|
||||||
<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>
|
|
||||||
</form>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details id="details-map" open>
|
|
||||||
<summary id="details-map-title"><span>Крок 2.</span> Перегляд</summary>
|
|
||||||
<form id="map-form">
|
|
||||||
<div
|
|
||||||
class="editor-buttons"
|
|
||||||
id="details-map-buttons-homestead"
|
|
||||||
style="display: none"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="block-map">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onclick="Editor.homestead.editing_mode()"
|
|
||||||
id="homestead-editing"
|
|
||||||
style="display: none;"
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
|
|
||||||
<path
|
|
||||||
d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<div id="map"></div>
|
|
||||||
</div>
|
|
||||||
<button id="map-form-button" type="submit" style="display: none">
|
|
||||||
Далі
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details id="details-area" open style="display: none">
|
|
||||||
<summary>
|
|
||||||
<span>Крок 3.</span> Конструктор квартир
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value="1"
|
|
||||||
id="next-apartment-title"
|
|
||||||
onchange="Editor.apartments.editNum(this)"
|
|
||||||
title="Авто-номер наступної квартири"
|
|
||||||
/>
|
|
||||||
</summary>
|
|
||||||
|
|
||||||
<form id="area-form">
|
|
||||||
<div id="list-area"></div>
|
|
||||||
</form>
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
@@ -1,636 +0,0 @@
|
|||||||
const Editor = {
|
|
||||||
async init(type, id) {
|
|
||||||
let html = await fetch('/lib/pages/editor/index.html').then((response) => response.text());
|
|
||||||
app.innerHTML = html;
|
|
||||||
|
|
||||||
map = "";
|
|
||||||
houseGroup = "";
|
|
||||||
entransePolygonsGroup = "";
|
|
||||||
entranseNumPolygonsGroup = "";
|
|
||||||
splitPolygonsGroup = "";
|
|
||||||
RectangleGroup = "";
|
|
||||||
numApartments = 1;
|
|
||||||
|
|
||||||
Editor.info.setHTML(type, id);
|
|
||||||
},
|
|
||||||
|
|
||||||
async loadAPI(URL) {
|
|
||||||
let uuid = localStorage.getItem("uuid");
|
|
||||||
return await fetch(URL, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
}
|
|
||||||
}).then((response) => response.json());
|
|
||||||
},
|
|
||||||
|
|
||||||
info: {
|
|
||||||
list: {
|
|
||||||
type: null, title: null, number: null,
|
|
||||||
points: [], points_number: [], point_icons: [],
|
|
||||||
geo: [], osm_id: [], settlement: [], description: null,
|
|
||||||
entrance: [], apartments: {}
|
|
||||||
},
|
|
||||||
|
|
||||||
async setHTML(type, id) {
|
|
||||||
const els = {
|
|
||||||
title: document.getElementById('info-address-title'),
|
|
||||||
number: document.getElementById('info-number-title'),
|
|
||||||
settlement: document.getElementById('info-settlement-title')
|
|
||||||
};
|
|
||||||
|
|
||||||
this.list = await Editor.loadAPI(`${CONFIG.api}${type}/${id}`);
|
|
||||||
Editor.info.list.type = type;
|
|
||||||
Editor.info.list.entrance = [];
|
|
||||||
Editor.info.list.apartments = {};
|
|
||||||
|
|
||||||
console.log(Editor.info.list);
|
|
||||||
|
|
||||||
els.title.value = this.list.title;
|
|
||||||
els.number.value = this.list.number;
|
|
||||||
els.settlement.value = this.list.settlement;
|
|
||||||
|
|
||||||
Editor.osm.init();
|
|
||||||
this.setMap();
|
|
||||||
|
|
||||||
if (type == "house") {
|
|
||||||
Editor.entrances.setHTML(id);
|
|
||||||
document.getElementById('details-area').style.display = "";
|
|
||||||
} else if (type == "homestead") {
|
|
||||||
Editor.homestead.init(id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setMap() {
|
|
||||||
houseGroup.clearLayers();
|
|
||||||
|
|
||||||
for (let i = 0; i < Editor.info.list.points.length; i++) {
|
|
||||||
const element = Editor.info.list.points[i];
|
|
||||||
|
|
||||||
if (Editor.info.list.type == "homestead") {
|
|
||||||
map.setView([this.list.geo.lat, this.list.geo.lng], this.list.zoom);
|
|
||||||
|
|
||||||
L.polygon(element, {
|
|
||||||
color: "#f2bd53",
|
|
||||||
radius: 500,
|
|
||||||
fillOpacity: 0.3,
|
|
||||||
dashArray: '20,15',
|
|
||||||
dashOffset: '20',
|
|
||||||
}).addTo(houseGroup);
|
|
||||||
} else if (Editor.info.list.type == "house") {
|
|
||||||
map.setView([this.list.geo.lat, this.list.geo.lng], this.list.zoom);
|
|
||||||
|
|
||||||
L.polygon(element, {
|
|
||||||
color: "#585858",
|
|
||||||
fillColor: "#f2bd53",
|
|
||||||
fillOpacity: 0.8,
|
|
||||||
tm_id: `house_${i}`
|
|
||||||
}).addTo(houseGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
osm: {
|
|
||||||
init() {
|
|
||||||
const googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
|
|
||||||
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
|
|
||||||
});
|
|
||||||
const osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
const 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(), zoom: 17,
|
|
||||||
layers: [googleHybrid, osm, mytile, houseGroup,
|
|
||||||
entransePolygonsGroup, entranseNumPolygonsGroup,
|
|
||||||
splitPolygonsGroup, RectangleGroup],
|
|
||||||
zoomControl: false
|
|
||||||
});
|
|
||||||
|
|
||||||
L.control.layers(
|
|
||||||
{ "Google Hybrid": googleHybrid, "OpenStreetMap": osm, "Territory Map": mytile },
|
|
||||||
{
|
|
||||||
"Будинки": houseGroup,
|
|
||||||
"Під'їзди": entransePolygonsGroup,
|
|
||||||
"Номера під'їздів": entranseNumPolygonsGroup,
|
|
||||||
"Слой редагування": splitPolygonsGroup,
|
|
||||||
"Слой лінійки": RectangleGroup
|
|
||||||
},
|
|
||||||
{ 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 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
entrances: {
|
|
||||||
list: [],
|
|
||||||
|
|
||||||
async setHTML(id) {
|
|
||||||
this.list = await Editor.loadAPI(`${CONFIG.api}house/${id}/entrances`);
|
|
||||||
|
|
||||||
entransePolygonsGroup.clearLayers();
|
|
||||||
entranseNumPolygonsGroup.clearLayers();
|
|
||||||
|
|
||||||
const listArea = document.getElementById('list-area');
|
|
||||||
if (!listArea) return;
|
|
||||||
|
|
||||||
listArea.innerHTML = "";
|
|
||||||
|
|
||||||
for (const element of this.list) {
|
|
||||||
// Блок area
|
|
||||||
const divArea = document.createElement('div');
|
|
||||||
divArea.className = "block-area";
|
|
||||||
divArea.id = `block-area-${element.id}`;
|
|
||||||
|
|
||||||
const h3 = document.createElement('h3');
|
|
||||||
h3.textContent = element.title;
|
|
||||||
|
|
||||||
const addBtn = document.createElement('button');
|
|
||||||
addBtn.className = "addFloors";
|
|
||||||
addBtn.type = "button";
|
|
||||||
addBtn.title = "Додати поверх";
|
|
||||||
addBtn.dataset.entranceId = element.id;
|
|
||||||
addBtn.innerHTML = `<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>`;
|
|
||||||
addBtn.setAttribute(`onclick`, `Editor.apartments.addFloors("${element.id}")`);
|
|
||||||
|
|
||||||
const innerArea = document.createElement('div');
|
|
||||||
innerArea.id = `area-${element.id}`;
|
|
||||||
|
|
||||||
divArea.append(h3, addBtn, innerArea);
|
|
||||||
listArea.appendChild(divArea);
|
|
||||||
|
|
||||||
// Завантажуємо квартири для ентрансів
|
|
||||||
Editor.apartments.setHTML(element.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
apartments: {
|
|
||||||
list: {},
|
|
||||||
|
|
||||||
async setHTML(id) {
|
|
||||||
this.list[id] = await Editor.loadAPI(`${CONFIG.api}apartments/${id}`);
|
|
||||||
const area = document.getElementById(`area-${id}`);
|
|
||||||
if (!area) return;
|
|
||||||
|
|
||||||
// Унікальні поверхи
|
|
||||||
const uniqueFloors = [...new Set(this.list[id].map(a => a.floors_number))].sort((a, b) => a - b);
|
|
||||||
|
|
||||||
// Створюємо блоки поверхів
|
|
||||||
for (const num of uniqueFloors) {
|
|
||||||
const div = document.createElement('div');
|
|
||||||
div.className = "block-apartments-floors";
|
|
||||||
div.id = `floors-${id}-${num}`;
|
|
||||||
|
|
||||||
const h2 = document.createElement('h2');
|
|
||||||
h2.textContent = `Поверх ${num}`;
|
|
||||||
div.appendChild(h2);
|
|
||||||
|
|
||||||
const addBtn = document.createElement('button');
|
|
||||||
addBtn.className = "addApartment";
|
|
||||||
addBtn.id = `buttonApartment-${id}-${num}`;
|
|
||||||
addBtn.type = "button";
|
|
||||||
addBtn.title = "Додати квартиру";
|
|
||||||
addBtn.dataset.area = id;
|
|
||||||
addBtn.dataset.floors = num;
|
|
||||||
addBtn.innerHTML = `<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>`;
|
|
||||||
addBtn.setAttribute(`onclick`, `Editor.apartments.addApartment("${id}", "${num}")`);
|
|
||||||
|
|
||||||
|
|
||||||
div.appendChild(addBtn);
|
|
||||||
area.prepend(div);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Сортуємо квартири за назвою
|
|
||||||
this.list[id].sort((a, b) => b.title - a.title);
|
|
||||||
|
|
||||||
// Створюємо блоки квартир
|
|
||||||
for (const apartment of this.list[id]) {
|
|
||||||
const floorsBlock = document.getElementById(`floors-${id}-${apartment.floors_number}`);
|
|
||||||
if (!floorsBlock) continue;
|
|
||||||
|
|
||||||
const div = document.createElement('div');
|
|
||||||
div.className = "block-apartments-number";
|
|
||||||
div.id = `block-apartments-${id}-${apartment.id}`;
|
|
||||||
|
|
||||||
const input = document.createElement('input');
|
|
||||||
input.type = "text";
|
|
||||||
input.value = apartment.title;
|
|
||||||
input.id = `apartament-${id}-${apartment.id}`;
|
|
||||||
input.dataset.area = id;
|
|
||||||
input.dataset.apartment = apartment.id;
|
|
||||||
input.setAttribute(`onclick`, `Editor.apartments.editApartment("${id}", "${apartment.id}")`);
|
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
|
||||||
delBtn.type = "button";
|
|
||||||
delBtn.dataset.area = id;
|
|
||||||
delBtn.dataset.apartment = apartment.id;
|
|
||||||
delBtn.innerHTML = `<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>`;
|
|
||||||
delBtn.setAttribute(`onclick`, `Editor.apartments.deleteApartment("${id}", "${apartment.id}")`);
|
|
||||||
|
|
||||||
div.append(input, delBtn);
|
|
||||||
floorsBlock.prepend(div);
|
|
||||||
|
|
||||||
numApartments++;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextApartmentTitle = document.getElementById('next-apartment-title');
|
|
||||||
if (nextApartmentTitle) nextApartmentTitle.value = numApartments;
|
|
||||||
},
|
|
||||||
|
|
||||||
async addFloors(area) {
|
|
||||||
const areaBlock = document.getElementById(`area-${area}`);
|
|
||||||
const uniqueFloors = [...new Set(this.list[area].map(obj => obj.floors_number))];
|
|
||||||
const newFloors = uniqueFloors.length + 1;
|
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(URL, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
apartment_number: this.list[area].length,
|
|
||||||
title: numApartments.toString(),
|
|
||||||
floors_number: newFloors
|
|
||||||
})
|
|
||||||
});
|
|
||||||
const data = await response.json();
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
// Створюємо блок поверху
|
|
||||||
const div = document.createElement('div');
|
|
||||||
div.className = "block-apartments-floors";
|
|
||||||
div.id = `floors-${area}-${newFloors}`;
|
|
||||||
|
|
||||||
// Заголовок поверху
|
|
||||||
const h2 = document.createElement('h2');
|
|
||||||
h2.textContent = `Поверх ${newFloors}`;
|
|
||||||
div.appendChild(h2);
|
|
||||||
|
|
||||||
// Блок квартири
|
|
||||||
const apartmentBlock = document.createElement('div');
|
|
||||||
apartmentBlock.className = "block-apartments-number";
|
|
||||||
apartmentBlock.id = `block-apartments-${area}-${data.id}`;
|
|
||||||
|
|
||||||
const input = document.createElement('input');
|
|
||||||
input.type = "text";
|
|
||||||
input.value = numApartments;
|
|
||||||
input.id = `apartament-${area}-${data.id}`;
|
|
||||||
input.onchange = () => Editor.apartments.editApartment(area, data.id);
|
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
|
||||||
delBtn.type = "button";
|
|
||||||
delBtn.innerHTML = `<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>`;
|
|
||||||
delBtn.onclick = () => Editor.apartments.deleteApartment(area, data.id);
|
|
||||||
|
|
||||||
apartmentBlock.append(input, delBtn);
|
|
||||||
div.appendChild(apartmentBlock);
|
|
||||||
|
|
||||||
// Кнопка додати квартиру
|
|
||||||
const addBtn = document.createElement('button');
|
|
||||||
addBtn.className = "addApartment";
|
|
||||||
addBtn.id = `buttonApartment-${area}-${newFloors}`;
|
|
||||||
addBtn.title = "Додати квартиру";
|
|
||||||
addBtn.type = "button";
|
|
||||||
addBtn.onclick = () => Editor.apartments.addApartment(area, newFloors);
|
|
||||||
addBtn.innerHTML = `<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>`;
|
|
||||||
div.appendChild(addBtn);
|
|
||||||
|
|
||||||
areaBlock.prepend(div);
|
|
||||||
|
|
||||||
// Оновлюємо список квартир
|
|
||||||
this.list[area].push({
|
|
||||||
id: data.id,
|
|
||||||
entrance_id: Number(area),
|
|
||||||
apartment_number: this.list[area].length,
|
|
||||||
title: numApartments.toString(),
|
|
||||||
floors_number: newFloors
|
|
||||||
});
|
|
||||||
|
|
||||||
numApartments++;
|
|
||||||
const nextApartmentTitle = document.getElementById('next-apartment-title');
|
|
||||||
if (nextApartmentTitle) nextApartmentTitle.value = numApartments;
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Помилка при додаванні поверху:", err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async addApartment(area, floors) {
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(URL, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
apartment_number: this.list[area].length,
|
|
||||||
title: numApartments.toString(),
|
|
||||||
floors_number: Number(floors)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
// Оновлюємо список квартир
|
|
||||||
this.list[area].push({
|
|
||||||
id: data.id,
|
|
||||||
entrance_id: Number(area),
|
|
||||||
apartment_number: this.list[area].length,
|
|
||||||
title: numApartments.toString(),
|
|
||||||
floors_number: Number(floors)
|
|
||||||
});
|
|
||||||
|
|
||||||
const floorsBlock = document.getElementById(`floors-${area}-${floors}`);
|
|
||||||
|
|
||||||
// Видаляємо стару кнопку додати квартиру
|
|
||||||
const oldButton = document.getElementById(`buttonApartment-${area}-${floors}`);
|
|
||||||
if (oldButton) oldButton.remove();
|
|
||||||
|
|
||||||
// Створюємо блок нової квартири
|
|
||||||
const apartmentDiv = document.createElement('div');
|
|
||||||
apartmentDiv.className = "block-apartments-number";
|
|
||||||
apartmentDiv.id = `block-apartments-${area}-${data.id}`;
|
|
||||||
|
|
||||||
const input = document.createElement('input');
|
|
||||||
input.type = "text";
|
|
||||||
input.value = numApartments;
|
|
||||||
input.id = `apartament-${area}-${data.id}`;
|
|
||||||
input.onchange = () => Editor.apartments.editApartment(area, data.id);
|
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
|
||||||
delBtn.type = "button";
|
|
||||||
delBtn.innerHTML = `<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>`;
|
|
||||||
delBtn.onclick = () => Editor.apartments.deleteApartment(area, data.id);
|
|
||||||
|
|
||||||
apartmentDiv.append(input, delBtn);
|
|
||||||
floorsBlock.appendChild(apartmentDiv);
|
|
||||||
|
|
||||||
// Додаємо кнопку "додати квартиру" знову
|
|
||||||
const addBtn = document.createElement('button');
|
|
||||||
addBtn.className = "addApartment";
|
|
||||||
addBtn.id = `buttonApartment-${area}-${floors}`;
|
|
||||||
addBtn.title = "Додати квартиру";
|
|
||||||
addBtn.type = "button";
|
|
||||||
addBtn.onclick = () => Editor.apartments.addApartment(area, floors);
|
|
||||||
addBtn.innerHTML = `<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>`;
|
|
||||||
floorsBlock.appendChild(addBtn);
|
|
||||||
|
|
||||||
numApartments++;
|
|
||||||
const nextApartmentTitle = document.getElementById('next-apartment-title');
|
|
||||||
if (nextApartmentTitle) nextApartmentTitle.value = numApartments;
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Помилка при додаванні квартири:", err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async editApartment(area, apartment) {
|
|
||||||
const input = document.getElementById(`apartament-${area}-${apartment}`);
|
|
||||||
if (!input) return;
|
|
||||||
|
|
||||||
const newTitle = input.value;
|
|
||||||
|
|
||||||
// Оновлюємо локальний список квартир
|
|
||||||
const pos = this.list[area].findIndex(e => e.id === Number(apartment));
|
|
||||||
if (pos === -1) return;
|
|
||||||
|
|
||||||
this.list[area][pos].title = newTitle;
|
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(URL, {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
id: this.list[area][pos].id,
|
|
||||||
title: this.list[area][pos].title,
|
|
||||||
status: this.list[area][pos].status,
|
|
||||||
description: this.list[area][pos].description
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Помилка при редагуванні квартири:", err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async deleteApartment(area, apartment) {
|
|
||||||
const pos = this.list[area].findIndex(e => e.id === Number(apartment));
|
|
||||||
if (pos === -1) return;
|
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(URL, {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ id: this.list[area][pos].id })
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
// Видаляємо елемент з DOM
|
|
||||||
const apartmentBlock = document.getElementById(`block-apartments-${area}-${apartment}`);
|
|
||||||
if (apartmentBlock) apartmentBlock.remove();
|
|
||||||
|
|
||||||
// Оновлюємо локальний список
|
|
||||||
this.list[area].splice(pos, 1);
|
|
||||||
|
|
||||||
// Оновлюємо номер наступної квартири
|
|
||||||
numApartments = Math.max(0, numApartments - 1);
|
|
||||||
const nextApartmentTitle = document.getElementById('next-apartment-title');
|
|
||||||
if (nextApartmentTitle) nextApartmentTitle.value = numApartments;
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Помилка при видаленні квартири:", err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
editNum(el) { numApartments = Number(el.value) },
|
|
||||||
},
|
|
||||||
|
|
||||||
homestead: {
|
|
||||||
id: null, list: [], editing: false,
|
|
||||||
|
|
||||||
async init(id) {
|
|
||||||
this.editing = false;
|
|
||||||
this.id = id;
|
|
||||||
setLeafletCursor('pointer');
|
|
||||||
|
|
||||||
document.getElementById('homestead-editing').style.display = "";
|
|
||||||
|
|
||||||
// Завантаження даних будівлі
|
|
||||||
this.list = await Editor.loadAPI(`${CONFIG.api}building/${id}`);
|
|
||||||
|
|
||||||
// Обробник кліку на карту
|
|
||||||
houseGroup.on('click', e => {
|
|
||||||
if (e.layer instanceof L.Marker || !this.editing) return;
|
|
||||||
|
|
||||||
const { lat, lng } = e.latlng;
|
|
||||||
console.log(`Координати: ${lat.toFixed(5)}, ${lng.toFixed(5)}`);
|
|
||||||
|
|
||||||
setLeafletCursor('progress');
|
|
||||||
this.editing.editing = false;
|
|
||||||
|
|
||||||
this.addBuilding({ geo: e.latlng, title: this.list.length + 1 });
|
|
||||||
this.list.push({});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Встановлюємо вид карти
|
|
||||||
const viewLatLng = Editor.info.list.geo?.lat
|
|
||||||
? [Editor.info.list.geo.lat, Editor.info.list.geo.lng]
|
|
||||||
: [Editor.info.list.points[0][0][0].lat, Editor.info.list.points[0][0][0].lng];
|
|
||||||
map.setView(viewLatLng, Editor.info.list.zoom);
|
|
||||||
|
|
||||||
|
|
||||||
for (const element of this.list) {
|
|
||||||
// Додаємо маркер на карту
|
|
||||||
const redDot = L.divIcon({
|
|
||||||
className: "leaflet_drop",
|
|
||||||
html: `<div id="redDot_${element.id}"></div>`,
|
|
||||||
iconSize: [16, 16],
|
|
||||||
iconAnchor: [8, 8]
|
|
||||||
});
|
|
||||||
|
|
||||||
L.marker(element.geo, { icon: redDot })
|
|
||||||
.addTo(houseGroup)
|
|
||||||
.bindPopup(`
|
|
||||||
Точка: ${element.id}<br>
|
|
||||||
Координати: ${element.geo.lat.toFixed(5)}, ${element.geo.lng.toFixed(5)}<br>
|
|
||||||
<button class="map_dell" onclick="Editor.homestead.delleteBuilding({id: ${element.id}})" type="button">Видалити</button>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async addBuilding({ geo, title }) {
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}building/${this.id}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(URL, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ title, geo })
|
|
||||||
});
|
|
||||||
const data = await response.json();
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
// Додаємо маркер на карту
|
|
||||||
const redDot = L.divIcon({
|
|
||||||
className: "leaflet_drop",
|
|
||||||
html: `<div id="redDot_${data.id}"></div>`,
|
|
||||||
iconSize: [16, 16],
|
|
||||||
iconAnchor: [8, 8]
|
|
||||||
});
|
|
||||||
|
|
||||||
const marker = L.marker(geo, { icon: redDot }).addTo(houseGroup);
|
|
||||||
marker.bindPopup(`
|
|
||||||
Точка: ${data.id}<br>
|
|
||||||
Координати: ${geo.lat.toFixed(5)}, ${geo.lng.toFixed(5)}<br>
|
|
||||||
<button class="map_dell" onclick="Editor.homestead.delleteBuilding({id: ${data.id}})" type="button">Видалити</button>
|
|
||||||
`);
|
|
||||||
|
|
||||||
setLeafletCursor('crosshair');
|
|
||||||
this.editing = true;
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Помилка при додаванні будівлі:", err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async delleteBuilding({ id }) {
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
|
||||||
const URL = `${CONFIG.api}building/${id}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(URL, {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": uuid
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
// Видаляємо елемент списку та маркер
|
|
||||||
const el = document.getElementById(`redDot_${id}`);
|
|
||||||
if (el) el.remove();
|
|
||||||
|
|
||||||
const block = document.getElementById(`Building_${id}`);
|
|
||||||
if (block) block.remove();
|
|
||||||
|
|
||||||
houseGroup.eachLayer(layer => {
|
|
||||||
if (layer instanceof L.Marker && layer.getPopup()?.getContent().includes(`Точка: ${id}`)) {
|
|
||||||
houseGroup.removeLayer(layer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Помилка при видаленні будівлі:", err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
editing_mode() {
|
|
||||||
const btn = document.getElementById('homestead-editing');
|
|
||||||
this.editing = !this.editing;
|
|
||||||
setLeafletCursor(this.editing ? 'crosshair' : 'pointer');
|
|
||||||
btn.innerHTML = this.editing
|
|
||||||
? `<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>`
|
|
||||||
: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> <path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z" ></path> </svg>`;
|
|
||||||
if (this.editing) alert("Натискаючи на карту будуть створюватись нові точки (будинки)");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,536 +0,0 @@
|
|||||||
.page-editor {
|
|
||||||
width: calc(100% - 40px);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin: 20px 20px 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor 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-editor 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-editor>details[disabled] summary,
|
|
||||||
.page-editor>details.disabled summary {
|
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor>details summary::-webkit-details-marker,
|
|
||||||
.page-editor>details summary::marker {
|
|
||||||
display: none;
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor 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-editor summary span {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor 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-editor #info-form,
|
|
||||||
.page-editor #map-form,
|
|
||||||
.page-editor #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-editor .details-info-input {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
margin: 20px 0;
|
|
||||||
align-items: flex-start;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor .details-info-input label {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
font-size: var(--FontSize1);
|
|
||||||
font-weight: 500;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor .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-editor #details-info-osm div {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor #details-info-osm input {
|
|
||||||
width: calc(100% - 10px);
|
|
||||||
min-width: 140px;
|
|
||||||
padding: 0 5px;
|
|
||||||
border-radius: 6px;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor .details-info-input a {
|
|
||||||
height: 26px;
|
|
||||||
width: 26px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor .details-info-input a>svg {
|
|
||||||
height: 26px;
|
|
||||||
width: 26px;
|
|
||||||
fill: var(--ColorThemes3)
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor #list-area {
|
|
||||||
display: flex;
|
|
||||||
overflow: auto;
|
|
||||||
margin: 15px 0 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor #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;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
background: var(--ColorThemes1);
|
|
||||||
color: var(--ColorThemes3);
|
|
||||||
border: 1px solid var(--ColorThemes2);
|
|
||||||
box-shadow: var(--shadow-l1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#homestead-editing {
|
|
||||||
position: absolute;
|
|
||||||
height: 40px;
|
|
||||||
background: var(--PrimaryColor);
|
|
||||||
font-size: var(--FontSize5);
|
|
||||||
margin: 10px;
|
|
||||||
border: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-weight: 500;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 6px;
|
|
||||||
width: 40px;
|
|
||||||
z-index: 999;
|
|
||||||
right: 0;
|
|
||||||
box-shadow: var(--shadow-l1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#homestead-editing>svg {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
fill: var(--PrimaryColorText);
|
|
||||||
}
|
|
||||||
|
|
||||||
#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-editor #list-entranse,
|
|
||||||
.page-editor #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;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor #list-entranse>.house,
|
|
||||||
.page-editor #list-homestead>.house {
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
min-width: 60px;
|
|
||||||
min-height: 60px;
|
|
||||||
background: var(--ColorThemes1);
|
|
||||||
border: 2px solid var(--PrimaryColor);
|
|
||||||
margin: 10px;
|
|
||||||
border-radius: 4px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.page-editor #list-entranse>.house>input,
|
|
||||||
.page-editor #list-homestead>.house>input,
|
|
||||||
.page-editor #list-entranse>.house>p,
|
|
||||||
.page-editor #list-homestead>.house>p {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
font-size: var(--FontSize5);
|
|
||||||
font-weight: 400;
|
|
||||||
text-align: center;
|
|
||||||
color: var(--ColorThemes3);
|
|
||||||
background: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-editor #list-entranse>.house>button,
|
|
||||||
.page-editor #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-editor #list-entranse>.house>button>svg,
|
|
||||||
.page-editor #list-homestead>.house>button>svg {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
fill: var(--PrimaryColorText);
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="page-stand">
|
<div class="page-stand-card">
|
||||||
<!-- <label for="dateSelect">Виберіть дату:</label>
|
<!-- <label for="dateSelect">Виберіть дату:</label>
|
||||||
<select id="dateSelect"></select> -->
|
<select id="dateSelect"></select> -->
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
const Stand = {
|
const Stand_card = {
|
||||||
schedule: [],
|
schedule: [],
|
||||||
init: async () => {
|
init: async (id) => {
|
||||||
let html = await fetch('/lib/pages/stand/index.html').then((response) => response.text());
|
let html = await fetch('/lib/pages/stand/card/index.html').then((response) => response.text());
|
||||||
app.innerHTML = html;
|
app.innerHTML = html;
|
||||||
|
|
||||||
let listDate = [1, 4];
|
let listDate = [1, 4];
|
||||||
@@ -35,7 +35,7 @@ const Stand = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generateAvailableDates();
|
// generateAvailableDates();
|
||||||
Stand.generator();
|
Stand_card.generator();
|
||||||
},
|
},
|
||||||
generator: () => {
|
generator: () => {
|
||||||
let block_schedule = document.getElementById('stand-schedule');
|
let block_schedule = document.getElementById('stand-schedule');
|
||||||
@@ -48,19 +48,19 @@ const Stand = {
|
|||||||
geo: { lat: 0, lng: 0 },
|
geo: { lat: 0, lng: 0 },
|
||||||
hour_start: 9,
|
hour_start: 9,
|
||||||
hour_end: 14,
|
hour_end: 14,
|
||||||
quantity_sheep: 4,
|
quantity_sheep: 2,
|
||||||
week_days: [0, 2, 4, 6],
|
week_days: [0, 2, 4, 6],
|
||||||
processing_time: 0.5,
|
processing_time: 0.5,
|
||||||
updated_at: null
|
updated_at: null
|
||||||
}
|
}
|
||||||
|
|
||||||
Stand.schedule = [];
|
Stand_card.schedule = [];
|
||||||
|
|
||||||
// Кількість годин служіння
|
// Кількість годин служіння
|
||||||
let stand_length = (stand.hour_end - stand.hour_start) / stand.processing_time;
|
let stand_length = (stand.hour_end - stand.hour_start) / stand.processing_time;
|
||||||
|
|
||||||
for (let z = 0; z < stand.week_days.length; z++) {
|
for (let z = 0; z < stand.week_days.length; z++) {
|
||||||
Stand.schedule.push([]);
|
Stand_card.schedule.push([]);
|
||||||
|
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
date.setDate(date.getDate() + stand.week_days[z]);
|
date.setDate(date.getDate() + stand.week_days[z]);
|
||||||
@@ -97,7 +97,7 @@ const Stand = {
|
|||||||
</select>
|
</select>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
Stand.schedule[z].push({
|
Stand_card.schedule[z].push({
|
||||||
id: (i + z) * stand.quantity_sheep + q,
|
id: (i + z) * stand.quantity_sheep + q,
|
||||||
hour: stand.hour_start + (stand.processing_time * i),
|
hour: stand.hour_start + (stand.processing_time * i),
|
||||||
number_sheep: q,
|
number_sheep: q,
|
||||||
@@ -114,7 +114,7 @@ const Stand = {
|
|||||||
html += `</div>`; // закриваємо day
|
html += `</div>`; // закриваємо day
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('stand-info-title').innerText = stand.title;
|
document.getElementById('stand-info-title').innerText = Stand_card.title;
|
||||||
document.getElementById('stand-info-geo').innerHTML = '';
|
document.getElementById('stand-info-geo').innerHTML = '';
|
||||||
document.getElementById('stand-info-image').setAttribute('src', '');
|
document.getElementById('stand-info-image').setAttribute('src', '');
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
.page-stand {
|
.page-stand-card {
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
margin: 20px 20px 0 20px;
|
margin: 20px 20px 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-stand details {
|
.page-stand-card details {
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
box-shadow: var(--shadow-l1);
|
box-shadow: var(--shadow-l1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-stand summary {
|
.page-stand-card summary {
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--ColorThemes3);
|
color: var(--ColorThemes3);
|
||||||
3
web/lib/pages/stand/list/index.html
Normal file
3
web/lib/pages/stand/list/index.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="page-stand-list">
|
||||||
|
|
||||||
|
</div>
|
||||||
6
web/lib/pages/stand/list/script.js
Normal file
6
web/lib/pages/stand/list/script.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const Stand_list = {
|
||||||
|
init: async () => {
|
||||||
|
let html = await fetch('/lib/pages/stand/list/index.html').then((response) => response.text());
|
||||||
|
app.innerHTML = html;
|
||||||
|
},
|
||||||
|
}
|
||||||
7
web/lib/pages/stand/list/style.css
Normal file
7
web/lib/pages/stand/list/style.css
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.page-stand-list {
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin: 20px 20px 0 20px;
|
||||||
|
}
|
||||||
@@ -200,21 +200,21 @@
|
|||||||
<div class="page-card">
|
<div class="page-card">
|
||||||
<div class="list-controls" id="page-card-controls" style="display: none">
|
<div class="list-controls" id="page-card-controls" style="display: none">
|
||||||
<div id="page-card-sort">
|
<div id="page-card-sort">
|
||||||
<button id="sort_1" onclick="Card.sort('2')" data-state="active">
|
<button id="sort_1" onclick="Territory_card.sort('2')" data-state="active">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
d="M 32.476562 5.9785156 A 1.50015 1.50015 0 0 0 31 7.5 L 31 37.878906 L 26.560547 33.439453 A 1.50015 1.50015 0 1 0 24.439453 35.560547 L 31.439453 42.560547 A 1.50015 1.50015 0 0 0 33.560547 42.560547 L 40.560547 35.560547 A 1.50015 1.50015 0 1 0 38.439453 33.439453 L 34 37.878906 L 34 7.5 A 1.50015 1.50015 0 0 0 32.476562 5.9785156 z M 14.375 8.0058594 C 14.257547 8.01575 14.139641 8.0379219 14.025391 8.0761719 L 11.025391 9.0761719 C 10.239391 9.3381719 9.8141719 10.188609 10.076172 10.974609 C 10.338172 11.760609 11.190609 12.188828 11.974609 11.923828 L 13 11.580078 L 13 20.5 C 13 21.329 13.671 22 14.5 22 C 15.329 22 16 21.329 16 20.5 L 16 9.5 C 16 9.018 15.767953 8.5652031 15.376953 8.2832031 C 15.082953 8.0717031 14.727359 7.9761875 14.375 8.0058594 z M 14 27 C 11.344 27 9.387625 28.682109 9.015625 31.287109 C 8.898625 32.107109 9.4671094 32.867375 10.287109 32.984375 C 11.106109 33.102375 11.867375 32.533891 11.984375 31.712891 C 12.096375 30.931891 12.537 30 14 30 C 15.103 30 16 30.897 16 32 C 16 33.103 15.103 34 14 34 C 11.592 34 9 35.721 9 39.5 C 9 40.329 9.672 41 10.5 41 L 17.5 41 C 18.329 41 19 40.329 19 39.5 C 19 38.671 18.329 38 17.5 38 L 12.308594 38 C 12.781594 37.093 13.664 37 14 37 C 16.757 37 19 34.757 19 32 C 19 29.243 16.757 27 14 27 z"
|
d="M 32.476562 5.9785156 A 1.50015 1.50015 0 0 0 31 7.5 L 31 37.878906 L 26.560547 33.439453 A 1.50015 1.50015 0 1 0 24.439453 35.560547 L 31.439453 42.560547 A 1.50015 1.50015 0 0 0 33.560547 42.560547 L 40.560547 35.560547 A 1.50015 1.50015 0 1 0 38.439453 33.439453 L 34 37.878906 L 34 7.5 A 1.50015 1.50015 0 0 0 32.476562 5.9785156 z M 14.375 8.0058594 C 14.257547 8.01575 14.139641 8.0379219 14.025391 8.0761719 L 11.025391 9.0761719 C 10.239391 9.3381719 9.8141719 10.188609 10.076172 10.974609 C 10.338172 11.760609 11.190609 12.188828 11.974609 11.923828 L 13 11.580078 L 13 20.5 C 13 21.329 13.671 22 14.5 22 C 15.329 22 16 21.329 16 20.5 L 16 9.5 C 16 9.018 15.767953 8.5652031 15.376953 8.2832031 C 15.082953 8.0717031 14.727359 7.9761875 14.375 8.0058594 z M 14 27 C 11.344 27 9.387625 28.682109 9.015625 31.287109 C 8.898625 32.107109 9.4671094 32.867375 10.287109 32.984375 C 11.106109 33.102375 11.867375 32.533891 11.984375 31.712891 C 12.096375 30.931891 12.537 30 14 30 C 15.103 30 16 30.897 16 32 C 16 33.103 15.103 34 14 34 C 11.592 34 9 35.721 9 39.5 C 9 40.329 9.672 41 10.5 41 L 17.5 41 C 18.329 41 19 40.329 19 39.5 C 19 38.671 18.329 38 17.5 38 L 12.308594 38 C 12.781594 37.093 13.664 37 14 37 C 16.757 37 19 34.757 19 32 C 19 29.243 16.757 27 14 27 z"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button id="sort_2" onclick="Card.sort('3')" data-state="">
|
<button id="sort_2" onclick="Territory_card.sort('3')" data-state="">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
d="M 31.478516 6 A 1.50015 1.50015 0 0 0 30.439453 6.4394531 L 23.439453 13.439453 A 1.50015 1.50015 0 1 0 25.560547 15.560547 L 30 11.121094 L 30 41.5 A 1.50015 1.50015 0 1 0 33 41.5 L 33 11.121094 L 37.439453 15.560547 A 1.50015 1.50015 0 1 0 39.560547 13.439453 L 32.560547 6.4394531 A 1.50015 1.50015 0 0 0 31.478516 6 z M 13.375 8.0058594 C 13.257547 8.01575 13.139641 8.0379219 13.025391 8.0761719 L 10.025391 9.0761719 C 9.2393906 9.3381719 8.8141719 10.188609 9.0761719 10.974609 C 9.3381719 11.760609 10.190609 12.188828 10.974609 11.923828 L 12 11.580078 L 12 20.5 C 12 21.329 12.671 22 13.5 22 C 14.329 22 15 21.329 15 20.5 L 15 9.5 C 15 9.018 14.767953 8.5652031 14.376953 8.2832031 C 14.082953 8.0717031 13.727359 7.9761875 13.375 8.0058594 z M 13 27 C 10.344 27 8.387625 28.682109 8.015625 31.287109 C 7.898625 32.107109 8.4671094 32.867375 9.2871094 32.984375 C 10.106109 33.102375 10.867375 32.533891 10.984375 31.712891 C 11.096375 30.931891 11.537 30 13 30 C 14.103 30 15 30.897 15 32 C 15 33.103 14.103 34 13 34 C 10.592 34 8 35.721 8 39.5 C 8 40.329 8.672 41 9.5 41 L 16.5 41 C 17.329 41 18 40.329 18 39.5 C 18 38.671 17.329 38 16.5 38 L 11.308594 38 C 11.781594 37.093 12.664 37 13 37 C 15.757 37 18 34.757 18 32 C 18 29.243 15.757 27 13 27 z"
|
d="M 31.478516 6 A 1.50015 1.50015 0 0 0 30.439453 6.4394531 L 23.439453 13.439453 A 1.50015 1.50015 0 1 0 25.560547 15.560547 L 30 11.121094 L 30 41.5 A 1.50015 1.50015 0 1 0 33 41.5 L 33 11.121094 L 37.439453 15.560547 A 1.50015 1.50015 0 1 0 39.560547 13.439453 L 32.560547 6.4394531 A 1.50015 1.50015 0 0 0 31.478516 6 z M 13.375 8.0058594 C 13.257547 8.01575 13.139641 8.0379219 13.025391 8.0761719 L 10.025391 9.0761719 C 9.2393906 9.3381719 8.8141719 10.188609 9.0761719 10.974609 C 9.3381719 11.760609 10.190609 12.188828 10.974609 11.923828 L 12 11.580078 L 12 20.5 C 12 21.329 12.671 22 13.5 22 C 14.329 22 15 21.329 15 20.5 L 15 9.5 C 15 9.018 14.767953 8.5652031 14.376953 8.2832031 C 14.082953 8.0717031 13.727359 7.9761875 13.375 8.0058594 z M 13 27 C 10.344 27 8.387625 28.682109 8.015625 31.287109 C 7.898625 32.107109 8.4671094 32.867375 9.2871094 32.984375 C 10.106109 33.102375 10.867375 32.533891 10.984375 31.712891 C 11.096375 30.931891 11.537 30 13 30 C 14.103 30 15 30.897 15 32 C 15 33.103 14.103 34 13 34 C 10.592 34 8 35.721 8 39.5 C 8 40.329 8.672 41 9.5 41 L 16.5 41 C 17.329 41 18 40.329 18 39.5 C 18 38.671 17.329 38 16.5 38 L 11.308594 38 C 11.781594 37.093 12.664 37 13 37 C 15.757 37 18 34.757 18 32 C 18 29.243 15.757 27 13 27 z"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button id="sort_3" onclick="Card.sort('4')" data-state="">
|
<button id="sort_3" onclick="Territory_card.sort('4')" data-state="">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
transform="rotate(180 32.5 24.5106)"
|
transform="rotate(180 32.5 24.5106)"
|
||||||
@@ -226,7 +226,7 @@
|
|||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button id="sort_4" onclick="Card.sort('1')" data-state="">
|
<button id="sort_4" onclick="Territory_card.sort('1')" data-state="">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
id="svg_1"
|
id="svg_1"
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
let map_card;
|
let map_card;
|
||||||
|
|
||||||
const Card = {
|
const Territory_card = {
|
||||||
// Глобальні змінні стану
|
// Глобальні змінні стану
|
||||||
id: null,
|
id: null,
|
||||||
socket: null,
|
socket: null,
|
||||||
reconnectTimeout: null,
|
reconnectTimeout: null,
|
||||||
reconnectAttempts: 0,
|
reconnectAttempts: 0,
|
||||||
username: null,
|
|
||||||
listEntrances: [],
|
listEntrances: [],
|
||||||
listApartment: [],
|
listApartment: [],
|
||||||
listBuilding: [],
|
listBuilding: [],
|
||||||
@@ -25,13 +24,14 @@ const Card = {
|
|||||||
// Ініціалізація сторінки
|
// Ініціалізація сторінки
|
||||||
async init(type, Id) {
|
async init(type, Id) {
|
||||||
// Завантажуємо HTML
|
// Завантажуємо HTML
|
||||||
const html = await fetch('/lib/pages/card/index.html').then(r => r.text());
|
const html = await fetch('/lib/pages/territory/card/index.html').then(r => r.text());
|
||||||
app.innerHTML = html;
|
app.innerHTML = html;
|
||||||
Card.id = Id;
|
Territory_card.id = Id;
|
||||||
|
|
||||||
// Закриваємо старий WebSocket
|
// Закриваємо старий WebSocket
|
||||||
if (this.socket) this.socket.close(1000, "Перезапуск з'єднання");
|
if (this.socket) this.socket.close(1000, "Перезапуск з'єднання");
|
||||||
this.cloud.start(makeid(6));
|
// this.cloud.start(makeid(6));
|
||||||
|
this.cloud.start()
|
||||||
|
|
||||||
// Якщо це сторінка будинку, отримуємо під’їзди та стартуємо WebSocket
|
// Якщо це сторінка будинку, отримуємо під’їзди та стартуємо WebSocket
|
||||||
if (type === "house") {
|
if (type === "house") {
|
||||||
@@ -59,60 +59,60 @@ const Card = {
|
|||||||
|
|
||||||
// Робота з WebSocket
|
// Робота з WebSocket
|
||||||
cloud: {
|
cloud: {
|
||||||
start(name) {
|
start() {
|
||||||
if (!name) return;
|
|
||||||
Card.username = name;
|
|
||||||
|
|
||||||
const uuid = localStorage.getItem("uuid");
|
const uuid = localStorage.getItem("uuid");
|
||||||
const ws = new WebSocket(`${CONFIG.wss}?uuid=${uuid}`);
|
const ws = new WebSocket(CONFIG.wss, uuid);
|
||||||
Card.socket = ws;
|
Territory_card.socket = ws;
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
console.log("[WebSocket] З'єднання встановлено");
|
console.log("[WebSocket] З'єднання встановлено");
|
||||||
Card.cloud.setStatus('ok');
|
Territory_card.cloud.setStatus('ok');
|
||||||
ws.send(JSON.stringify({
|
ws.send(JSON.stringify({
|
||||||
event: 'connection',
|
event: 'connection',
|
||||||
id: getTimeInSeconds(),
|
id: getTimeInSeconds(),
|
||||||
date: getTimeInSeconds(),
|
date: getTimeInSeconds(),
|
||||||
uuid,
|
uuid,
|
||||||
username: name,
|
user: {
|
||||||
|
name: USER.name,
|
||||||
|
id: USER.id
|
||||||
|
},
|
||||||
data: {}
|
data: {}
|
||||||
}));
|
}));
|
||||||
Card.reconnectAttempts = 0;
|
Territory_card.reconnectAttempts = 0;
|
||||||
clearTimeout(Card.reconnectTimeout);
|
clearTimeout(Territory_card.reconnectTimeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onmessage = (e) => {
|
ws.onmessage = (e) => {
|
||||||
const data = JSON.parse(e.data);
|
const data = JSON.parse(e.data);
|
||||||
if (data.event === 'connection' && data.username !== Card.username) {
|
if (data.event === 'connection' && data.user.id !== USER.id) {
|
||||||
console.log(`Новий користувач: ${data.username}`);
|
console.log(`Новий користувач: ${data.user}`);
|
||||||
}
|
}
|
||||||
if (data.event === 'message') {
|
if (data.event === 'message') {
|
||||||
Card.cloud.update(data);
|
Territory_card.cloud.update(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
console.warn("[WebSocket] З'єднання розірвано");
|
console.warn("[WebSocket] З'єднання розірвано");
|
||||||
Card.cloud.setStatus('err');
|
Territory_card.cloud.setStatus('err');
|
||||||
Card.reconnectAttempts++;
|
Territory_card.reconnectAttempts++;
|
||||||
if (Card.reconnectAttempts <= 5) {
|
if (Territory_card.reconnectAttempts <= 5) {
|
||||||
Card.reconnectTimeout = setTimeout(() => {
|
Territory_card.reconnectTimeout = setTimeout(() => {
|
||||||
Card.getEntrances({ update: true });
|
Territory_card.getEntrances({ update: true });
|
||||||
Card.cloud.start(Card.username);
|
Territory_card.cloud.start();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
} else {
|
} else {
|
||||||
if (confirm("З'єднання розірвано! Перепідключитись?")) {
|
if (confirm("З'єднання розірвано! Перепідключитись?")) {
|
||||||
Card.reconnectAttempts = 0;
|
Territory_card.reconnectAttempts = 0;
|
||||||
Card.getEntrances({ update: true });
|
Territory_card.getEntrances({ update: true });
|
||||||
Card.cloud.start(Card.username);
|
Territory_card.cloud.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onerror = (err) => {
|
ws.onerror = (err) => {
|
||||||
console.error("[WebSocket] Помилка", err);
|
console.error("[WebSocket] Помилка", err);
|
||||||
Card.cloud.setStatus('err');
|
Territory_card.cloud.setStatus('err');
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ const Card = {
|
|||||||
update(msg) {
|
update(msg) {
|
||||||
if (msg.type !== "apartment" && msg.type !== "building") return;
|
if (msg.type !== "apartment" && msg.type !== "building") return;
|
||||||
|
|
||||||
const [bg, color] = Card.color_status[msg.data.status];
|
const [bg, color] = Territory_card.color_status[msg.data.status];
|
||||||
|
|
||||||
const id = msg.data.id;
|
const id = msg.data.id;
|
||||||
const el = document.getElementById(`status_${id}`);
|
const el = document.getElementById(`status_${id}`);
|
||||||
@@ -135,7 +135,7 @@ const Card = {
|
|||||||
|
|
||||||
if (msg.type === "building") {
|
if (msg.type === "building") {
|
||||||
redDot.style = `background:${bg};border:2px solid ${color}`;
|
redDot.style = `background:${bg};border:2px solid ${color}`;
|
||||||
const apt = Card.listBuilding.find(e => e.id === id);
|
const apt = Territory_card.listBuilding.find(e => e.id === id);
|
||||||
|
|
||||||
if (!apt) return;
|
if (!apt) return;
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ const Card = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
messApartment({ number, id, update, time }) {
|
messApartment({ number, id, update, time }) {
|
||||||
const apt = Card.listApartment[number]?.find(e => e.id === id);
|
const apt = Territory_card.listApartment[number]?.find(e => e.id === id);
|
||||||
if (!apt) return;
|
if (!apt) return;
|
||||||
|
|
||||||
const statusEl = document.getElementById(`status_${id}`);
|
const statusEl = document.getElementById(`status_${id}`);
|
||||||
@@ -184,14 +184,17 @@ const Card = {
|
|||||||
apt.description = descEl.value;
|
apt.description = descEl.value;
|
||||||
apt.updated_at = date();
|
apt.updated_at = date();
|
||||||
|
|
||||||
const [bg, color] = Card.color_status[apt.status];
|
const [bg, color] = Territory_card.color_status[apt.status];
|
||||||
statusEl.style = `background:${bg};color:${color};border:1px solid ${color}`;
|
statusEl.style = `background:${bg};color:${color};border:1px solid ${color}`;
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
event: 'message',
|
event: 'message',
|
||||||
id: getTimeInSeconds(),
|
id: getTimeInSeconds(),
|
||||||
date: getTimeInSeconds(),
|
date: getTimeInSeconds(),
|
||||||
username: Card.username,
|
user: {
|
||||||
|
name: USER.name,
|
||||||
|
id: USER.id
|
||||||
|
},
|
||||||
type: "apartment",
|
type: "apartment",
|
||||||
data: {
|
data: {
|
||||||
...apt,
|
...apt,
|
||||||
@@ -199,18 +202,18 @@ const Card = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Card.socket?.readyState === WebSocket.OPEN) {
|
if (Territory_card.socket?.readyState === WebSocket.OPEN) {
|
||||||
Card.socket.send(JSON.stringify(message));
|
Territory_card.socket.send(JSON.stringify(message));
|
||||||
} else {
|
} else {
|
||||||
if (confirm("З'єднання розірвано! Перепідключитись?")) {
|
if (confirm("З'єднання розірвано! Перепідключитись?")) {
|
||||||
Card.getEntrances({ update: true });
|
Territory_card.getEntrances({ update: true });
|
||||||
Card.cloud.start(Card.username);
|
Territory_card.cloud.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
messBuildings({ id, update, time }) {
|
messBuildings({ id, update, time }) {
|
||||||
const apt = Card.listBuilding.find(e => e.id === id);
|
const apt = Territory_card.listBuilding.find(e => e.id === id);
|
||||||
if (!apt) return;
|
if (!apt) return;
|
||||||
|
|
||||||
const statusEl = document.getElementById(`status_${id}`);
|
const statusEl = document.getElementById(`status_${id}`);
|
||||||
@@ -232,7 +235,7 @@ const Card = {
|
|||||||
apt.description = descEl.value;
|
apt.description = descEl.value;
|
||||||
apt.updated_at = date();
|
apt.updated_at = date();
|
||||||
|
|
||||||
const [bg, color] = Card.color_status[apt.status];
|
const [bg, color] = Territory_card.color_status[apt.status];
|
||||||
statusEl.style = `background:${bg};color:${color};border:1px solid ${color}`;
|
statusEl.style = `background:${bg};color:${color};border:1px solid ${color}`;
|
||||||
|
|
||||||
|
|
||||||
@@ -240,7 +243,10 @@ const Card = {
|
|||||||
event: 'message',
|
event: 'message',
|
||||||
id: getTimeInSeconds(),
|
id: getTimeInSeconds(),
|
||||||
date: getTimeInSeconds(),
|
date: getTimeInSeconds(),
|
||||||
username: Card.username,
|
user: {
|
||||||
|
name: USER.name,
|
||||||
|
id: USER.id
|
||||||
|
},
|
||||||
type: "building",
|
type: "building",
|
||||||
data: {
|
data: {
|
||||||
...apt,
|
...apt,
|
||||||
@@ -248,19 +254,19 @@ const Card = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Card.socket?.readyState === WebSocket.OPEN) {
|
if (Territory_card.socket?.readyState === WebSocket.OPEN) {
|
||||||
Card.socket.send(JSON.stringify(message));
|
Territory_card.socket.send(JSON.stringify(message));
|
||||||
} else {
|
} else {
|
||||||
if (confirm("З'єднання розірвано! Перепідключитись?")) {
|
if (confirm("З'єднання розірвано! Перепідключитись?")) {
|
||||||
Card.getEntrances({ update: true });
|
Territory_card.getEntrances({ update: true });
|
||||||
Card.cloud.start(Card.username);
|
Territory_card.cloud.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Отримання під’їздів
|
// Отримання під’їздів
|
||||||
async getEntrances({ house_id = Card.id, update = false }) {
|
async getEntrances({ house_id = Territory_card.id, update = false }) {
|
||||||
const uuid = localStorage.getItem("uuid");
|
const uuid = localStorage.getItem("uuid");
|
||||||
const res = await fetch(`${CONFIG.api}/house/${house_id}/entrances`, {
|
const res = await fetch(`${CONFIG.api}/house/${house_id}/entrances`, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -351,7 +357,7 @@ const Card = {
|
|||||||
statusEl.value = apt.status;
|
statusEl.value = apt.status;
|
||||||
statusEl.style = style;
|
statusEl.style = style;
|
||||||
}
|
}
|
||||||
if (dateEl) dateEl.setAttribute('onclick', `Card.dateEditor.open({id: ${apt.id}, number: ${number}, updated_at: ${apt.updated_at}})`);
|
if (dateEl) dateEl.setAttribute('onclick', `Territory_card.dateEditor.open({id: ${apt.id}, number: ${number}, updated_at: ${apt.updated_at}})`);
|
||||||
if (dateTextEl) dateTextEl.innerText = formattedDateTime(apt.updated_at);
|
if (dateTextEl) dateTextEl.innerText = formattedDateTime(apt.updated_at);
|
||||||
if (descEl) descEl.innerText = apt.description ?? "";
|
if (descEl) descEl.innerText = apt.description ?? "";
|
||||||
}
|
}
|
||||||
@@ -383,15 +389,15 @@ const Card = {
|
|||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span>кв.${apt.title}</span>
|
<span>кв.${apt.title}</span>
|
||||||
<select id="status_${apt.id}" onchange="Card.cloud.messApartment({number:${number},id:${apt.id},update:true})" style="${style}">
|
<select id="status_${apt.id}" onchange="Territory_card.cloud.messApartment({number:${number},id:${apt.id},update:true})" style="${style}">
|
||||||
${statusOptions(apt.status)}
|
${statusOptions(apt.status)}
|
||||||
</select>
|
</select>
|
||||||
<button id="date_${apt.id}" onclick="Card.dateEditor.open({id:${apt.id},number:${number},updated_at:${apt.updated_at}})">
|
<button id="date_${apt.id}" onclick="Territory_card.dateEditor.open({id:${apt.id},number:${number},updated_at:${apt.updated_at}})">
|
||||||
<p id="date_text_${apt.id}">${formattedDateTime(apt.updated_at)}</p>
|
<p id="date_text_${apt.id}">${formattedDateTime(apt.updated_at)}</p>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path></svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<textarea id="description_${apt.id}" onchange="Card.cloud.messApartment({number:${number},id:${apt.id}})" placeholder="Коротка нотатка.">${apt.description || ""}</textarea>
|
<textarea id="description_${apt.id}" onchange="Territory_card.cloud.messApartment({number:${number},id:${apt.id}})" placeholder="Коротка нотатка.">${apt.description || ""}</textarea>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
fragment.appendChild(div);
|
fragment.appendChild(div);
|
||||||
@@ -418,7 +424,7 @@ const Card = {
|
|||||||
return await response.json();
|
return await response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
async map({ homestead_id = Card.id }) {
|
async map({ homestead_id = Territory_card.id }) {
|
||||||
let data = await this.loadAPI({ url: `${CONFIG.api}homestead/${homestead_id}` });
|
let data = await this.loadAPI({ url: `${CONFIG.api}homestead/${homestead_id}` });
|
||||||
|
|
||||||
console.log(data);
|
console.log(data);
|
||||||
@@ -428,9 +434,9 @@ const Card = {
|
|||||||
let lng = data.geo?.lng ?? data.points?.[0]?.[0]?.[0]?.lng ?? 25.6145625;
|
let lng = data.geo?.lng ?? data.points?.[0]?.[0]?.[0]?.lng ?? 25.6145625;
|
||||||
let zoom = 15;
|
let zoom = 15;
|
||||||
|
|
||||||
if (map_card && map_card.remove) {
|
if (map_card && map_Territory_card.remove) {
|
||||||
map_card.stopLocate();
|
map_Territory_card.stopLocate();
|
||||||
map_card.remove();
|
map_Territory_card.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapElement = document.getElementById('map_card');
|
const mapElement = document.getElementById('map_card');
|
||||||
@@ -465,13 +471,13 @@ const Card = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// слежение в реальном времени
|
// слежение в реальном времени
|
||||||
map_card.locate({ setView: false, watch: true, enableHighAccuracy: true });
|
map_Territory_card.locate({ setView: false, watch: true, enableHighAccuracy: true });
|
||||||
map_card.on('locationfound', (e) => {
|
map_Territory_card.on('locationfound', (e) => {
|
||||||
if (!map_card._userMarker) {
|
if (!map_Territory_card._userMarker) {
|
||||||
map_card._userMarker = L.marker(e.latlng).addTo(map_card)
|
map_Territory_card._userMarker = L.marker(e.latlng).addTo(map_card)
|
||||||
.bindPopup("Ви тут!");
|
.bindPopup("Ви тут!");
|
||||||
} else {
|
} else {
|
||||||
map_card._userMarker.setLatLng(e.latlng);
|
map_Territory_card._userMarker.setLatLng(e.latlng);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -483,7 +489,7 @@ const Card = {
|
|||||||
|
|
||||||
let layerControl = L.control.layers(baseMaps, [], { position: 'bottomright' }).addTo(map_card);
|
let layerControl = L.control.layers(baseMaps, [], { position: 'bottomright' }).addTo(map_card);
|
||||||
|
|
||||||
map_card.pm.setLang("ua");
|
map_Territory_card.pm.setLang("ua");
|
||||||
|
|
||||||
const polygonOptions = {
|
const polygonOptions = {
|
||||||
color: "#f2bd53",
|
color: "#f2bd53",
|
||||||
@@ -495,23 +501,23 @@ const Card = {
|
|||||||
|
|
||||||
L.polygon(data.points, polygonOptions).addTo(map_card);
|
L.polygon(data.points, polygonOptions).addTo(map_card);
|
||||||
|
|
||||||
map_card.setZoom(data.zoom);
|
map_Territory_card.setZoom(data.zoom);
|
||||||
|
|
||||||
// map_card.getZoom()
|
// map_Territory_card.getZoom()
|
||||||
|
|
||||||
// console.log(data.zoom);
|
// console.log(data.zoom);
|
||||||
|
|
||||||
|
|
||||||
Card.listBuilding = await this.loadAPI({ url: `${CONFIG.api}building/${homestead_id}` });
|
Territory_card.listBuilding = await this.loadAPI({ url: `${CONFIG.api}building/${homestead_id}` });
|
||||||
|
|
||||||
const statusOptions = (selected) => {
|
const statusOptions = (selected) => {
|
||||||
const labels = ["", "Відмова (Не цікавить)", "Не заходити (Груба відмова)", "Нема домофона", "Повторна відвідина", "Немає вдома", "Свідки Єгови"];
|
const labels = ["", "Відмова (Не цікавить)", "Не заходити (Груба відмова)", "Нема домофона", "Повторна відвідина", "Немає вдома", "Свідки Єгови"];
|
||||||
return labels.map((txt, i) => `<option value="${i}" ${i === selected ? "selected" : ""}>${txt}</option>`).join("");
|
return labels.map((txt, i) => `<option value="${i}" ${i === selected ? "selected" : ""}>${txt}</option>`).join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let i = 0; i < Card.listBuilding.length; i++) {
|
for (let i = 0; i < Territory_card.listBuilding.length; i++) {
|
||||||
const element = Card.listBuilding[i];
|
const element = Territory_card.listBuilding[i];
|
||||||
const [bg, color] = Card.color_status[element.status];
|
const [bg, color] = Territory_card.color_status[element.status];
|
||||||
|
|
||||||
const redDot = L.divIcon({
|
const redDot = L.divIcon({
|
||||||
className: "leaflet_drop",
|
className: "leaflet_drop",
|
||||||
@@ -527,8 +533,8 @@ const Card = {
|
|||||||
|
|
||||||
// при открытии popup генерим div заново
|
// при открытии popup генерим div заново
|
||||||
marker.on("popupopen", () => {
|
marker.on("popupopen", () => {
|
||||||
const el = Card.listBuilding.find(e => e.id === element.id);
|
const el = Territory_card.listBuilding.find(e => e.id === element.id);
|
||||||
const [bg, color] = Card.color_status[el.status];
|
const [bg, color] = Territory_card.color_status[el.status];
|
||||||
const style = `background:${bg};color:${color};border:1px solid ${color}`;
|
const style = `background:${bg};color:${color};border:1px solid ${color}`;
|
||||||
|
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
@@ -541,18 +547,18 @@ const Card = {
|
|||||||
|
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<select id="status_${element.id}" onchange="Card.cloud.messBuildings({id:${element.id},update:true})" style="${style}">
|
<select id="status_${element.id}" onchange="Territory_card.cloud.messBuildings({id:${element.id},update:true})" style="${style}">
|
||||||
${statusOptions(element.status)}
|
${statusOptions(element.status)}
|
||||||
</select>
|
</select>
|
||||||
<input type="datetime-local" id="date_${element.id}" placeholder="Дата" onchange="Card.cloud.messBuildings({id:${element.id},update:true, time: this.value })" value="${date.toISOString().slice(0, 16)}">
|
<input type="datetime-local" id="date_${element.id}" placeholder="Дата" onchange="Territory_card.cloud.messBuildings({id:${element.id},update:true, time: this.value })" value="${date.toISOString().slice(0, 16)}">
|
||||||
</div>
|
</div>
|
||||||
<textarea id="description_${element.id}" onchange="Card.cloud.messBuildings({id:${element.id}})" placeholder="Коротка нотатка.">${element.description || ""}</textarea>
|
<textarea id="description_${element.id}" onchange="Territory_card.cloud.messBuildings({id:${element.id}})" placeholder="Коротка нотатка.">${element.description || ""}</textarea>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
marker.setPopupContent(div);
|
marker.setPopupContent(div);
|
||||||
});
|
});
|
||||||
|
|
||||||
Card.getHomestead.markers[element.id] = marker; // сохраним ссылку на маркер
|
Territory_card.getHomestead.markers[element.id] = marker; // сохраним ссылку на маркер
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -580,8 +586,8 @@ const Card = {
|
|||||||
input.value = date.toISOString().slice(0, 16)
|
input.value = date.toISOString().slice(0, 16)
|
||||||
|
|
||||||
// Призначаємо обробники
|
// Призначаємо обробники
|
||||||
input.setAttribute("onchange", `Card.dateEditor.edit({ id: ${id}, number: ${number} })`)
|
input.setAttribute("onchange", `Territory_card.dateEditor.edit({ id: ${id}, number: ${number} })`)
|
||||||
button.setAttribute("onclick", `Card.dateEditor.edit({ id: ${id}, number: ${number}, type: 'now'})`)
|
button.setAttribute("onclick", `Territory_card.dateEditor.edit({ id: ${id}, number: ${number}, type: 'now'})`)
|
||||||
|
|
||||||
|
|
||||||
// Показуємо блок
|
// Показуємо блок
|
||||||
@@ -603,13 +609,13 @@ const Card = {
|
|||||||
let input = document.getElementById('card-new-date-input').value;
|
let input = document.getElementById('card-new-date-input').value;
|
||||||
|
|
||||||
if (type == "now") {
|
if (type == "now") {
|
||||||
Card.cloud.messApartment({ number: number, id: id, update: true });
|
Territory_card.cloud.messApartment({ number: number, id: id, update: true });
|
||||||
} else {
|
} else {
|
||||||
if (input) {
|
if (input) {
|
||||||
const ts = new Date(input).getTime();
|
const ts = new Date(input).getTime();
|
||||||
Card.cloud.messApartment({ number, id, update: true, time: ts });
|
Territory_card.cloud.messApartment({ number, id, update: true, time: ts });
|
||||||
} else {
|
} else {
|
||||||
Card.cloud.messApartment({ number: number, id: id });
|
Territory_card.cloud.messApartment({ number: number, id: id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.close();
|
this.close();
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="123, 345, 678"
|
placeholder="123, 345, 678"
|
||||||
onchange="Constructor.osm.autoPoligon(this.value)"
|
onchange="Territory_constructor.osm.autoPoligon(this.value)"
|
||||||
/>
|
/>
|
||||||
<a
|
<a
|
||||||
href="https://www.openstreetmap.org/#map=19/49.561725/25.604458"
|
href="https://www.openstreetmap.org/#map=19/49.561725/25.604458"
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span>або</span>
|
<span>або</span>
|
||||||
<button onclick="Constructor.osm.newPoligon()">Обрати на карті</button>
|
<button onclick="Territory_constructor.osm.newPoligon()">Обрати на карті</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="block-map">
|
<div class="block-map">
|
||||||
@@ -3,10 +3,10 @@ let numApartments = 1;
|
|||||||
let mode = '';
|
let mode = '';
|
||||||
|
|
||||||
|
|
||||||
const Constructor = {
|
const Territory_constructor = {
|
||||||
info: {},
|
info: {},
|
||||||
async init() {
|
async init() {
|
||||||
let html = await fetch('/lib/pages/constructor/index.html').then((response) => response.text());
|
let html = await fetch('/lib/pages/territory/constructor/index.html').then((response) => response.text());
|
||||||
app.innerHTML = html;
|
app.innerHTML = html;
|
||||||
|
|
||||||
map = "";
|
map = "";
|
||||||
@@ -36,25 +36,25 @@ const Constructor = {
|
|||||||
title: "Назва",
|
title: "Назва",
|
||||||
number: "Номер",
|
number: "Номер",
|
||||||
settlement: "Місто",
|
settlement: "Місто",
|
||||||
init: () => Constructor.points.init(),
|
init: () => Territory_constructor.points.init(),
|
||||||
next: () => Constructor.points.next(),
|
next: () => Territory_constructor.points.next(),
|
||||||
save: () => Constructor.points.save()
|
save: () => Territory_constructor.points.save()
|
||||||
},
|
},
|
||||||
homestead: {
|
homestead: {
|
||||||
title: "Назва району / села",
|
title: "Назва району / села",
|
||||||
number: "Номер району",
|
number: "Номер району",
|
||||||
settlement: "Місто",
|
settlement: "Місто",
|
||||||
init: () => Constructor.homestead.init(),
|
init: () => Territory_constructor.homestead.init(),
|
||||||
next: () => Constructor.homestead.next(),
|
next: () => Territory_constructor.homestead.next(),
|
||||||
save: () => Constructor.homestead.save()
|
save: () => Territory_constructor.homestead.save()
|
||||||
},
|
},
|
||||||
house: {
|
house: {
|
||||||
title: "Назва вулиці",
|
title: "Назва вулиці",
|
||||||
number: "Номер будинку",
|
number: "Номер будинку",
|
||||||
settlement: "Місто",
|
settlement: "Місто",
|
||||||
init: () => Constructor.house.init(),
|
init: () => Territory_constructor.house.init(),
|
||||||
next: () => Constructor.house.next(),
|
next: () => Territory_constructor.house.next(),
|
||||||
save: () => Constructor.house.save()
|
save: () => Territory_constructor.house.save()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ const Constructor = {
|
|||||||
document.getElementById('part-1-button').style.display = "none";
|
document.getElementById('part-1-button').style.display = "none";
|
||||||
|
|
||||||
['title', 'number', 'settlement'].forEach(key => {
|
['title', 'number', 'settlement'].forEach(key => {
|
||||||
Constructor.info[key] = document.getElementById(`info-${key}`).value;
|
Territory_constructor.info[key] = document.getElementById(`info-${key}`).value;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (currentInit) currentInit();
|
if (currentInit) currentInit();
|
||||||
@@ -173,7 +173,7 @@ const Constructor = {
|
|||||||
part_2_title.innerHTML = `<span>Крок 2.</span> Створення ділянки`;
|
part_2_title.innerHTML = `<span>Крок 2.</span> Створення ділянки`;
|
||||||
part_2.style.display = "";
|
part_2.style.display = "";
|
||||||
|
|
||||||
Constructor.osm.init();
|
Territory_constructor.osm.init();
|
||||||
},
|
},
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
@@ -191,7 +191,7 @@ const Constructor = {
|
|||||||
<p>*Натисніть кнопку нижче, а потім клацайте на карті, щоб додати будинки. Після цього натисніть "Зберегти".</p>
|
<p>*Натисніть кнопку нижче, а потім клацайте на карті, щоб додати будинки. Після цього натисніть "Зберегти".</p>
|
||||||
<p>*Щоб видалити будинок, клацніть на ньому та у спливаючому вікні оберіть "Видалити".</p>
|
<p>*Щоб видалити будинок, клацніть на ньому та у спливаючому вікні оберіть "Видалити".</p>
|
||||||
<br />
|
<br />
|
||||||
<button onclick="Constructor.homestead.building.newHouse(this)">
|
<button onclick="Territory_constructor.homestead.building.newHouse(this)">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path></svg>
|
||||||
<span>Додати будинок</span>
|
<span>Додати будинок</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -205,11 +205,11 @@ const Constructor = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
Constructor.info.buildings = Constructor.homestead.building.list;
|
Territory_constructor.info.buildings = Territory_constructor.homestead.building.list;
|
||||||
|
|
||||||
console.log(Constructor.info);
|
console.log(Territory_constructor.info);
|
||||||
|
|
||||||
Constructor.save();
|
Territory_constructor.save();
|
||||||
},
|
},
|
||||||
|
|
||||||
building: {
|
building: {
|
||||||
@@ -252,7 +252,7 @@ const Constructor = {
|
|||||||
marker.bindPopup(`
|
marker.bindPopup(`
|
||||||
Будинок: ${this.list.length}<br>
|
Будинок: ${this.list.length}<br>
|
||||||
Координати: ${geo.lat.toFixed(5)}, ${geo.lng.toFixed(5)}<br>
|
Координати: ${geo.lat.toFixed(5)}, ${geo.lng.toFixed(5)}<br>
|
||||||
<button class="map_dell" onclick="Constructor.homestead.building.delleteBuilding({id: ${this.list.length}})" type="button">Видалити</button>
|
<button class="map_dell" onclick="Territory_constructor.homestead.building.delleteBuilding({id: ${this.list.length}})" type="button">Видалити</button>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
setLeafletCursor('crosshair');
|
setLeafletCursor('crosshair');
|
||||||
@@ -295,7 +295,7 @@ const Constructor = {
|
|||||||
part_2_title.innerHTML = `<span>Крок 2.</span> Конструктор будинків`;
|
part_2_title.innerHTML = `<span>Крок 2.</span> Конструктор будинків`;
|
||||||
part_2.style.display = "";
|
part_2.style.display = "";
|
||||||
|
|
||||||
Constructor.osm.init();
|
Territory_constructor.osm.init();
|
||||||
},
|
},
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
@@ -308,7 +308,7 @@ const Constructor = {
|
|||||||
title.innerHTML = `<span>Крок 3.</span> Конструктор квартир`;
|
title.innerHTML = `<span>Крок 3.</span> Конструктор квартир`;
|
||||||
|
|
||||||
part_3.appendChild(title);
|
part_3.appendChild(title);
|
||||||
part_3.innerHTML += `<input onchange="Constructor.house.apartments.editQuantity(this.value)" type="number" value="1" id="next-apartment-title" title="Авто-номер наступної квартири">`
|
part_3.innerHTML += `<input onchange="Territory_constructor.house.apartments.editQuantity(this.value)" type="number" value="1" id="next-apartment-title" title="Авто-номер наступної квартири">`
|
||||||
part_3.appendChild(button);
|
part_3.appendChild(button);
|
||||||
part_3.style.display = "";
|
part_3.style.display = "";
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ const Constructor = {
|
|||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
console.log('house next save');
|
console.log('house next save');
|
||||||
Constructor.info.entrances = this.apartments.list.map((entrance, entranceIndex) => {
|
Territory_constructor.info.entrances = this.apartments.list.map((entrance, entranceIndex) => {
|
||||||
let apartments = [];
|
let apartments = [];
|
||||||
let apartmentCounter = 0;
|
let apartmentCounter = 0;
|
||||||
|
|
||||||
@@ -339,7 +339,7 @@ const Constructor = {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
Constructor.save();
|
Territory_constructor.save();
|
||||||
},
|
},
|
||||||
|
|
||||||
apartments: {
|
apartments: {
|
||||||
@@ -377,8 +377,8 @@ const Constructor = {
|
|||||||
div.className = "apartment";
|
div.className = "apartment";
|
||||||
div.id = `apartment-${entrance}-${floor}-${apartment}`;
|
div.id = `apartment-${entrance}-${floor}-${apartment}`;
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<input onchange="Constructor.house.apartments.editApartment(${entrance}, ${floor}, ${apartment}, this.value)" type="text" value="${value}">
|
<input onchange="Territory_constructor.house.apartments.editApartment(${entrance}, ${floor}, ${apartment}, this.value)" type="text" value="${value}">
|
||||||
<button onclick="Constructor.house.apartments.deleteApartment(${entrance}, ${floor}, ${apartment})" title="Видалити квартиру" type="button">
|
<button onclick="Territory_constructor.house.apartments.deleteApartment(${entrance}, ${floor}, ${apartment})" title="Видалити квартиру" type="button">
|
||||||
<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>
|
<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>
|
</button>
|
||||||
`;
|
`;
|
||||||
@@ -392,7 +392,7 @@ const Constructor = {
|
|||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div class="floor-info">
|
<div class="floor-info">
|
||||||
<h2>Поверх ${floor + 1}</h2>
|
<h2>Поверх ${floor + 1}</h2>
|
||||||
<button onclick="Constructor.house.apartments.addApartment(${entrance}, ${floor})" title="Додати квартиру" type="button">
|
<button onclick="Territory_constructor.house.apartments.addApartment(${entrance}, ${floor})" title="Додати квартиру" type="button">
|
||||||
<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>
|
<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>
|
</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -405,8 +405,8 @@ const Constructor = {
|
|||||||
div.id = `entrance-${entrance}`;
|
div.id = `entrance-${entrance}`;
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div class="entrance-info">
|
<div class="entrance-info">
|
||||||
<input onchange="Constructor.house.apartments.editEntrance(${entrance}, this.value)" type="text" value="Під'їзд ${entrance + 1}">
|
<input onchange="Territory_constructor.house.apartments.editEntrance(${entrance}, this.value)" type="text" value="Під'їзд ${entrance + 1}">
|
||||||
<button onclick="Constructor.house.apartments.addFloors(${entrance})" title="Додати поверх" type="button">
|
<button onclick="Territory_constructor.house.apartments.addFloors(${entrance})" title="Додати поверх" type="button">
|
||||||
<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>
|
<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>
|
</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -417,7 +417,7 @@ const Constructor = {
|
|||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.id = `house`;
|
div.id = `house`;
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<button class="entrance-button" onclick="Constructor.house.apartments.addEntrance()" title="Додати під'їзд" type="button">
|
<button class="entrance-button" onclick="Territory_constructor.house.apartments.addEntrance()" title="Додати під'їзд" type="button">
|
||||||
<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>
|
<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>`;
|
</button>`;
|
||||||
return div;
|
return div;
|
||||||
@@ -560,15 +560,15 @@ const Constructor = {
|
|||||||
let LatLngs = layer.getLatLngs();
|
let LatLngs = layer.getLatLngs();
|
||||||
LatLngs[0].push(LatLngs[0][0]);
|
LatLngs[0].push(LatLngs[0][0]);
|
||||||
|
|
||||||
Constructor.info.points.push(LatLngs);
|
Territory_constructor.info.points.push(LatLngs);
|
||||||
Constructor.info.points_number.push(this.center(layer.getLatLngs()));
|
Territory_constructor.info.points_number.push(this.center(layer.getLatLngs()));
|
||||||
let geo = this.center(layer.getLatLngs());
|
let geo = this.center(layer.getLatLngs());
|
||||||
|
|
||||||
const house = layer; // сохраняем именно слой
|
const house = layer; // сохраняем именно слой
|
||||||
|
|
||||||
if (Constructor.info.type === 'house') {
|
if (Territory_constructor.info.type === 'house') {
|
||||||
houseGroup.addLayer(house);
|
houseGroup.addLayer(house);
|
||||||
} else if (Constructor.info.type === 'homestead') {
|
} else if (Territory_constructor.info.type === 'homestead') {
|
||||||
homesteadGroup.addLayer(house);
|
homesteadGroup.addLayer(house);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,7 +579,7 @@ const Constructor = {
|
|||||||
|
|
||||||
// при открытии popup вешаем обработчик удаления
|
// при открытии popup вешаем обработчик удаления
|
||||||
house.on('popupopen', (e) => {
|
house.on('popupopen', (e) => {
|
||||||
if (Constructor.homestead.building.editing) {
|
if (Territory_constructor.homestead.building.editing) {
|
||||||
house.closePopup();
|
house.closePopup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -587,12 +587,12 @@ const Constructor = {
|
|||||||
const btn = e.popup.getElement().querySelector('.map_dell');
|
const btn = e.popup.getElement().querySelector('.map_dell');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
Constructor.osm.delete(house);
|
Territory_constructor.osm.delete(house);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Constructor.osm.autoZoom(Constructor.info.points);
|
Territory_constructor.osm.autoZoom(Territory_constructor.info.points);
|
||||||
});
|
});
|
||||||
|
|
||||||
map.pm.setLang("ua");
|
map.pm.setLang("ua");
|
||||||
@@ -605,7 +605,7 @@ const Constructor = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
newPoligon() {
|
newPoligon() {
|
||||||
if (Constructor.info.type === 'house') {
|
if (Territory_constructor.info.type === 'house') {
|
||||||
map.pm.enableDraw('Polygon', {
|
map.pm.enableDraw('Polygon', {
|
||||||
snappable: true,
|
snappable: true,
|
||||||
snapDistance: 20,
|
snapDistance: 20,
|
||||||
@@ -627,7 +627,7 @@ const Constructor = {
|
|||||||
fillOpacity: 0.8
|
fillOpacity: 0.8
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (Constructor.info.type === 'homestead') {
|
} else if (Territory_constructor.info.type === 'homestead') {
|
||||||
map.pm.enableDraw('Polygon', {
|
map.pm.enableDraw('Polygon', {
|
||||||
snappable: true,
|
snappable: true,
|
||||||
snapDistance: 20,
|
snapDistance: 20,
|
||||||
@@ -658,21 +658,21 @@ const Constructor = {
|
|||||||
if (!IDs) return;
|
if (!IDs) return;
|
||||||
|
|
||||||
const ids_list = IDs.replace(/\s+/g, "").split(',');
|
const ids_list = IDs.replace(/\s+/g, "").split(',');
|
||||||
Constructor.info.osm_id = ids_list;
|
Territory_constructor.info.osm_id = ids_list;
|
||||||
|
|
||||||
houseGroup.clearLayers();
|
houseGroup.clearLayers();
|
||||||
homesteadGroup.clearLayers();
|
homesteadGroup.clearLayers();
|
||||||
|
|
||||||
Constructor.info.points = [];
|
Territory_constructor.info.points = [];
|
||||||
Constructor.info.points_number = [];
|
Territory_constructor.info.points_number = [];
|
||||||
Constructor.info.geo = {}
|
Territory_constructor.info.geo = {}
|
||||||
|
|
||||||
|
|
||||||
// 1006306041, 1006306065
|
// 1006306041, 1006306065
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < ids_list.length; i++) {
|
for (let i = 0; i < ids_list.length; i++) {
|
||||||
const element = await Constructor.osm.getOSM(Constructor.info.osm_id[i]);
|
const element = await Territory_constructor.osm.getOSM(Territory_constructor.info.osm_id[i]);
|
||||||
|
|
||||||
// Преобразуем координаты в LatLng
|
// Преобразуем координаты в LatLng
|
||||||
const LatLngs = [[]];
|
const LatLngs = [[]];
|
||||||
@@ -687,20 +687,20 @@ const Constructor = {
|
|||||||
const center = this.center(LatLngs);
|
const center = this.center(LatLngs);
|
||||||
|
|
||||||
// Сохраняем в points / points_number
|
// Сохраняем в points / points_number
|
||||||
Constructor.info.points.push(LatLngs);
|
Territory_constructor.info.points.push(LatLngs);
|
||||||
Constructor.info.points_number.push(center);
|
Territory_constructor.info.points_number.push(center);
|
||||||
|
|
||||||
// Создаем L.polygon
|
// Создаем L.polygon
|
||||||
const polyOptions = Constructor.info.type === 'homestead'
|
const polyOptions = Territory_constructor.info.type === 'homestead'
|
||||||
? { color: "#f2bd53", fillColor: "#f2bd53", fillOpacity: 0.4, dashArray: '5,10' }
|
? { color: "#f2bd53", fillColor: "#f2bd53", fillOpacity: 0.4, dashArray: '5,10' }
|
||||||
: { color: "#585858", fillColor: "#f2bd53", fillOpacity: 0.8 };
|
: { color: "#585858", fillColor: "#f2bd53", fillOpacity: 0.8 };
|
||||||
|
|
||||||
const house = L.polygon(LatLngs, polyOptions);
|
const house = L.polygon(LatLngs, polyOptions);
|
||||||
|
|
||||||
// Добавляем в нужную группу
|
// Добавляем в нужную группу
|
||||||
if (Constructor.info.type === 'house') {
|
if (Territory_constructor.info.type === 'house') {
|
||||||
houseGroup.addLayer(house);
|
houseGroup.addLayer(house);
|
||||||
} else if (Constructor.info.type === 'homestead') {
|
} else if (Territory_constructor.info.type === 'homestead') {
|
||||||
homesteadGroup.addLayer(house);
|
homesteadGroup.addLayer(house);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +711,7 @@ const Constructor = {
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
house.on('popupopen', (e) => {
|
house.on('popupopen', (e) => {
|
||||||
if (Constructor.homestead.building.editing) {
|
if (Territory_constructor.homestead.building.editing) {
|
||||||
house.closePopup();
|
house.closePopup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -719,13 +719,13 @@ const Constructor = {
|
|||||||
const btn = e.popup.getElement().querySelector('.map_dell');
|
const btn = e.popup.getElement().querySelector('.map_dell');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
Constructor.osm.delete(house);
|
Territory_constructor.osm.delete(house);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor.osm.autoZoom(Constructor.info.points);
|
Territory_constructor.osm.autoZoom(Territory_constructor.info.points);
|
||||||
},
|
},
|
||||||
|
|
||||||
center(geo) {
|
center(geo) {
|
||||||
@@ -792,8 +792,8 @@ const Constructor = {
|
|||||||
if (map.getZoom() > 18) map.setZoom(18);
|
if (map.getZoom() > 18) map.setZoom(18);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
Constructor.info.zoom = map.getZoom();
|
Territory_constructor.info.zoom = map.getZoom();
|
||||||
Constructor.info.geo = map.getCenter();
|
Territory_constructor.info.geo = map.getCenter();
|
||||||
}, 200)
|
}, 200)
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -862,10 +862,10 @@ const Constructor = {
|
|||||||
async save() {
|
async save() {
|
||||||
const part_3_button = document.getElementById('part-3-button');
|
const part_3_button = document.getElementById('part-3-button');
|
||||||
|
|
||||||
console.log(Constructor.info);
|
console.log(Territory_constructor.info);
|
||||||
|
|
||||||
setLeafletCursor('pointer');
|
setLeafletCursor('pointer');
|
||||||
Constructor.homestead.building.editing = false;
|
Territory_constructor.homestead.building.editing = false;
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
const uuid = localStorage.getItem('uuid');
|
||||||
const URL = `${CONFIG.api}constructor`;
|
const URL = `${CONFIG.api}constructor`;
|
||||||
@@ -875,7 +875,7 @@ const Constructor = {
|
|||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Authorization": uuid
|
"Authorization": uuid
|
||||||
},
|
},
|
||||||
body: JSON.stringify(Constructor.info)
|
body: JSON.stringify(Territory_constructor.info)
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.status == 200) {
|
if (response.status == 200) {
|
||||||
@@ -895,7 +895,7 @@ const Constructor = {
|
|||||||
|
|
||||||
Territory.house.list = [];
|
Territory.house.list = [];
|
||||||
Territory.homestead.list = [];
|
Territory.homestead.list = [];
|
||||||
Router.navigate(`/territory/manager/${Constructor.info.type}/${data.id}`);
|
Router.navigate(`/territory/manager/${Territory_constructor.info.type}/${data.id}`);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
part_3_button.innerText = "Зберегти";
|
part_3_button.innerText = "Зберегти";
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
id="info-osm"
|
id="info-osm"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="123, 345, 678"
|
placeholder="123, 345, 678"
|
||||||
onchange="Editor.osm.autoPoligon(this.value)"
|
onchange="Territory_editor.osm.autoPoligon(this.value)"
|
||||||
/>
|
/>
|
||||||
<a
|
<a
|
||||||
href="https://www.openstreetmap.org/#map=19/49.561725/25.604458"
|
href="https://www.openstreetmap.org/#map=19/49.561725/25.604458"
|
||||||
@@ -66,14 +66,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span>або</span>
|
<span>або</span>
|
||||||
<button onclick="Editor.osm.newPoligon()">Обрати на карті</button>
|
<button onclick="Territory_editor.osm.newPoligon()">Обрати на карті</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="block-map">
|
<div class="block-map">
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button" id="part-2-button" onclick="Editor.save()">Зберегти</button>
|
<button type="button" id="part-2-button" onclick="Territory_editor.save()">Зберегти</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="part-3" class="part_block" style="display: none">
|
<div id="part-3" class="part_block" style="display: none">
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
const Editor = {
|
const Territory_editor = {
|
||||||
info: {},
|
info: {},
|
||||||
|
|
||||||
// Ініціалізація редактора за типом об'єкта та його ID
|
// Ініціалізація редактора за типом об'єкта та його ID
|
||||||
async init(type, id) {
|
async init(type, id) {
|
||||||
let html = await fetch('/lib/pages/editor/index.html').then((response) => response.text());
|
let html = await fetch('/lib/pages/territory/editor/index.html').then((response) => response.text());
|
||||||
app.innerHTML = html;
|
app.innerHTML = html;
|
||||||
|
|
||||||
// Очищення груп та карти
|
// Очищення груп та карти
|
||||||
@@ -34,7 +34,7 @@ const Editor = {
|
|||||||
|
|
||||||
// Встановлення HTML-контенту для редактора залежно від типу об'єкта
|
// Встановлення HTML-контенту для редактора залежно від типу об'єкта
|
||||||
async setHTML(type, id) {
|
async setHTML(type, id) {
|
||||||
let list = await Editor.loadAPI(`${CONFIG.api}${type}/${id}`);
|
let list = await Territory_editor.loadAPI(`${CONFIG.api}${type}/${id}`);
|
||||||
|
|
||||||
console.log(list);
|
console.log(list);
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ const Editor = {
|
|||||||
<p>*Натисніть кнопку нижче, а потім клацайте на карті, щоб додати будинки. Після цього натисніть "Зберегти".</p>
|
<p>*Натисніть кнопку нижче, а потім клацайте на карті, щоб додати будинки. Після цього натисніть "Зберегти".</p>
|
||||||
<p>*Щоб видалити будинок, клацніть на ньому та у спливаючому вікні оберіть "Видалити".</p>
|
<p>*Щоб видалити будинок, клацніть на ньому та у спливаючому вікні оберіть "Видалити".</p>
|
||||||
<br />
|
<br />
|
||||||
<button onclick="Editor.homestead.building.newHouse(this)">
|
<button onclick="Territory_editor.homestead.building.newHouse(this)">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"></path></svg>
|
||||||
<span>Додати будинок</span>
|
<span>Додати будинок</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -111,7 +111,7 @@ const Editor = {
|
|||||||
this.editing = false;
|
this.editing = false;
|
||||||
setLeafletCursor('pointer');
|
setLeafletCursor('pointer');
|
||||||
|
|
||||||
this.list = await Editor.loadAPI(`${CONFIG.api}building/${Editor.info.id}`);
|
this.list = await Territory_editor.loadAPI(`${CONFIG.api}building/${Territory_editor.info.id}`);
|
||||||
|
|
||||||
// Обробник кліку на карту
|
// Обробник кліку на карту
|
||||||
homesteadGroup.on('click', e => {
|
homesteadGroup.on('click', e => {
|
||||||
@@ -142,7 +142,7 @@ const Editor = {
|
|||||||
.bindPopup(`
|
.bindPopup(`
|
||||||
Точка: ${element.id}<br>
|
Точка: ${element.id}<br>
|
||||||
Координати: ${element.geo.lat.toFixed(5)}, ${element.geo.lng.toFixed(5)}<br>
|
Координати: ${element.geo.lat.toFixed(5)}, ${element.geo.lng.toFixed(5)}<br>
|
||||||
<button class="map_dell" onclick="Editor.homestead.building.delleteBuilding({id: ${element.id}})" type="button">Видалити</button>
|
<button class="map_dell" onclick="Territory_editor.homestead.building.delleteBuilding({id: ${element.id}})" type="button">Видалити</button>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -154,7 +154,7 @@ const Editor = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
const uuid = localStorage.getItem('uuid');
|
||||||
const URL = `${CONFIG.api}building/${Editor.info.id}`;
|
const URL = `${CONFIG.api}building/${Territory_editor.info.id}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(URL, {
|
const response = await fetch(URL, {
|
||||||
@@ -180,7 +180,7 @@ const Editor = {
|
|||||||
marker.bindPopup(`
|
marker.bindPopup(`
|
||||||
Точка: ${data.id}<br>
|
Точка: ${data.id}<br>
|
||||||
Координати: ${geo.lat.toFixed(5)}, ${geo.lng.toFixed(5)}<br>
|
Координати: ${geo.lat.toFixed(5)}, ${geo.lng.toFixed(5)}<br>
|
||||||
<button class="map_dell" onclick="Editor.homestead.building.delleteBuilding({id: ${data.id}})" type="button">Видалити</button>
|
<button class="map_dell" onclick="Territory_editor.homestead.building.delleteBuilding({id: ${data.id}})" type="button">Видалити</button>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
setLeafletCursor('crosshair');
|
setLeafletCursor('crosshair');
|
||||||
@@ -244,17 +244,17 @@ const Editor = {
|
|||||||
title.innerHTML = `<span>Крок 3.</span> Конструктор квартир`;
|
title.innerHTML = `<span>Крок 3.</span> Конструктор квартир`;
|
||||||
|
|
||||||
part_3.appendChild(title);
|
part_3.appendChild(title);
|
||||||
part_3.innerHTML += `<input onchange="Editor.house.apartments.editNum(this)" type="number" value="1" id="next-apartment-title" title="Авто-номер наступної квартири"><div id="house"></div>`;
|
part_3.innerHTML += `<input onchange="Territory_editor.house.apartments.editNum(this)" type="number" value="1" id="next-apartment-title" title="Авто-номер наступної квартири"><div id="house"></div>`;
|
||||||
part_3.style.display = "";
|
part_3.style.display = "";
|
||||||
|
|
||||||
this.entrances.setHTML(Editor.info.id);
|
this.entrances.setHTML(Territory_editor.info.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
entrances: {
|
entrances: {
|
||||||
list: [],
|
list: [],
|
||||||
|
|
||||||
async setHTML(id) {
|
async setHTML(id) {
|
||||||
this.list = await Editor.loadAPI(`${CONFIG.api}house/${id}/entrances`);
|
this.list = await Territory_editor.loadAPI(`${CONFIG.api}house/${id}/entrances`);
|
||||||
|
|
||||||
const houseDiv = document.getElementById('house');
|
const houseDiv = document.getElementById('house');
|
||||||
if (!houseDiv) return;
|
if (!houseDiv) return;
|
||||||
@@ -266,7 +266,7 @@ const Editor = {
|
|||||||
newBtn.type = "button";
|
newBtn.type = "button";
|
||||||
newBtn.title = "Додати під'їзд";
|
newBtn.title = "Додати під'їзд";
|
||||||
newBtn.innerHTML = `<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>`;
|
newBtn.innerHTML = `<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>`;
|
||||||
newBtn.onclick = () => Editor.house.entrances.addEntrance();
|
newBtn.onclick = () => Territory_editor.house.entrances.addEntrance();
|
||||||
|
|
||||||
houseDiv.appendChild(newBtn);
|
houseDiv.appendChild(newBtn);
|
||||||
|
|
||||||
@@ -279,13 +279,13 @@ const Editor = {
|
|||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.value = element.title;
|
input.value = element.title;
|
||||||
input.type = "text"
|
input.type = "text"
|
||||||
input.onchange = () => Editor.house.entrances.editEntrance(element.id, input.value);
|
input.onchange = () => Territory_editor.house.entrances.editEntrance(element.id, input.value);
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
const delBtn = document.createElement('button');
|
||||||
delBtn.type = "button";
|
delBtn.type = "button";
|
||||||
delBtn.title = "Видалити під'їзд";
|
delBtn.title = "Видалити під'їзд";
|
||||||
delBtn.innerHTML = `<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>`;
|
delBtn.innerHTML = `<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>`;
|
||||||
delBtn.onclick = () => Editor.house.entrances.deleteEntrance(element.id);
|
delBtn.onclick = () => Territory_editor.house.entrances.deleteEntrance(element.id);
|
||||||
|
|
||||||
const headerDiv = document.createElement('div');
|
const headerDiv = document.createElement('div');
|
||||||
headerDiv.className = "entrance-header";
|
headerDiv.className = "entrance-header";
|
||||||
@@ -296,7 +296,7 @@ const Editor = {
|
|||||||
addBtn.type = "button";
|
addBtn.type = "button";
|
||||||
addBtn.title = "Додати поверх";
|
addBtn.title = "Додати поверх";
|
||||||
addBtn.innerHTML = `<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>`;
|
addBtn.innerHTML = `<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>`;
|
||||||
addBtn.onclick = () => Editor.house.apartments.addFloors(element.id);
|
addBtn.onclick = () => Territory_editor.house.apartments.addFloors(element.id);
|
||||||
|
|
||||||
|
|
||||||
const infoDiv = document.createElement('div');
|
const infoDiv = document.createElement('div');
|
||||||
@@ -307,7 +307,7 @@ const Editor = {
|
|||||||
houseDiv.insertBefore(entranceDiv, houseDiv.querySelector(".entrance-button"));
|
houseDiv.insertBefore(entranceDiv, houseDiv.querySelector(".entrance-button"));
|
||||||
|
|
||||||
// Завантажуємо квартири для ентрансів
|
// Завантажуємо квартири для ентрансів
|
||||||
Editor.house.apartments.setHTML(element.id);
|
Territory_editor.house.apartments.setHTML(element.id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ const Editor = {
|
|||||||
this.list[pos].title = value;
|
this.list[pos].title = value;
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
const uuid = localStorage.getItem('uuid');
|
||||||
const URL = `${CONFIG.api}house/${Editor.info.id}/entrances`;
|
const URL = `${CONFIG.api}house/${Territory_editor.info.id}/entrances`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(URL, {
|
const response = await fetch(URL, {
|
||||||
@@ -346,7 +346,7 @@ const Editor = {
|
|||||||
console.log('addEntrance');
|
console.log('addEntrance');
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
const uuid = localStorage.getItem('uuid');
|
||||||
const URL = `${CONFIG.api}house/${Editor.info.id}/entrances`;
|
const URL = `${CONFIG.api}house/${Territory_editor.info.id}/entrances`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(URL, {
|
const response = await fetch(URL, {
|
||||||
@@ -356,7 +356,7 @@ const Editor = {
|
|||||||
"Authorization": uuid
|
"Authorization": uuid
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
house_id: Editor.info.id,
|
house_id: Territory_editor.info.id,
|
||||||
entrance_number: this.list.length,
|
entrance_number: this.list.length,
|
||||||
title: `Під'їзд ${this.list.length + 1}`,
|
title: `Під'їзд ${this.list.length + 1}`,
|
||||||
description: null
|
description: null
|
||||||
@@ -368,14 +368,14 @@ const Editor = {
|
|||||||
|
|
||||||
let element = {
|
let element = {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
house_id: Editor.info.id,
|
house_id: Territory_editor.info.id,
|
||||||
entrance_number: this.list.length,
|
entrance_number: this.list.length,
|
||||||
title: `Під'їзд ${this.list.length + 1}`,
|
title: `Під'їзд ${this.list.length + 1}`,
|
||||||
description: null
|
description: null
|
||||||
}
|
}
|
||||||
|
|
||||||
this.list.push(element);
|
this.list.push(element);
|
||||||
Editor.house.apartments.list[element.id] = []
|
Territory_editor.house.apartments.list[element.id] = []
|
||||||
console.log(this.list);
|
console.log(this.list);
|
||||||
|
|
||||||
|
|
||||||
@@ -387,13 +387,13 @@ const Editor = {
|
|||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.value = element.title;
|
input.value = element.title;
|
||||||
input.type = "text"
|
input.type = "text"
|
||||||
input.onchange = () => Editor.house.entrances.editEntrance(element.id, input.value);
|
input.onchange = () => Territory_editor.house.entrances.editEntrance(element.id, input.value);
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
const delBtn = document.createElement('button');
|
||||||
delBtn.type = "button";
|
delBtn.type = "button";
|
||||||
delBtn.title = "Видалити під'їзд";
|
delBtn.title = "Видалити під'їзд";
|
||||||
delBtn.innerHTML = `<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>`;
|
delBtn.innerHTML = `<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>`;
|
||||||
delBtn.onclick = () => Editor.house.entrances.deleteEntrance(element.id);
|
delBtn.onclick = () => Territory_editor.house.entrances.deleteEntrance(element.id);
|
||||||
|
|
||||||
const headerDiv = document.createElement('div');
|
const headerDiv = document.createElement('div');
|
||||||
headerDiv.className = "entrance-header";
|
headerDiv.className = "entrance-header";
|
||||||
@@ -404,7 +404,7 @@ const Editor = {
|
|||||||
addBtn.type = "button";
|
addBtn.type = "button";
|
||||||
addBtn.title = "Додати поверх";
|
addBtn.title = "Додати поверх";
|
||||||
addBtn.innerHTML = `<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>`;
|
addBtn.innerHTML = `<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>`;
|
||||||
addBtn.onclick = () => Editor.house.apartments.addFloors(element.id);
|
addBtn.onclick = () => Territory_editor.house.apartments.addFloors(element.id);
|
||||||
|
|
||||||
|
|
||||||
const infoDiv = document.createElement('div');
|
const infoDiv = document.createElement('div');
|
||||||
@@ -423,10 +423,10 @@ const Editor = {
|
|||||||
async deleteEntrance(entrance) {
|
async deleteEntrance(entrance) {
|
||||||
console.log(entrance);
|
console.log(entrance);
|
||||||
|
|
||||||
if (Editor.house.apartments.list[entrance].length == 0) {
|
if (Territory_editor.house.apartments.list[entrance].length == 0) {
|
||||||
console.log("OK");
|
console.log("OK");
|
||||||
const uuid = localStorage.getItem('uuid');
|
const uuid = localStorage.getItem('uuid');
|
||||||
const URL = `${CONFIG.api}house/${Editor.info.id}/entrances`;
|
const URL = `${CONFIG.api}house/${Territory_editor.info.id}/entrances`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(URL, {
|
const response = await fetch(URL, {
|
||||||
@@ -445,7 +445,7 @@ const Editor = {
|
|||||||
|
|
||||||
const index = this.list.findIndex(item => item.id === entrance);
|
const index = this.list.findIndex(item => item.id === entrance);
|
||||||
if (index !== -1) this.list.splice(index, 1);
|
if (index !== -1) this.list.splice(index, 1);
|
||||||
delete Editor.house.apartments.list[entrance];
|
delete Territory_editor.house.apartments.list[entrance];
|
||||||
|
|
||||||
document.getElementById(`entrance-${entrance}`).remove();
|
document.getElementById(`entrance-${entrance}`).remove();
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ const Editor = {
|
|||||||
list: {},
|
list: {},
|
||||||
|
|
||||||
async setHTML(id) {
|
async setHTML(id) {
|
||||||
this.list[id] = await Editor.loadAPI(`${CONFIG.api}apartments/${id}`);
|
this.list[id] = await Territory_editor.loadAPI(`${CONFIG.api}apartments/${id}`);
|
||||||
const entranceDiv = document.getElementById(`entrance-${id}`);
|
const entranceDiv = document.getElementById(`entrance-${id}`);
|
||||||
if (!entranceDiv) return;
|
if (!entranceDiv) return;
|
||||||
|
|
||||||
@@ -485,7 +485,7 @@ const Editor = {
|
|||||||
addBtn.type = "button";
|
addBtn.type = "button";
|
||||||
addBtn.title = "Додати квартиру";
|
addBtn.title = "Додати квартиру";
|
||||||
addBtn.innerHTML = `<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>`;
|
addBtn.innerHTML = `<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>`;
|
||||||
addBtn.onclick = () => Editor.house.apartments.addApartment(id, num);
|
addBtn.onclick = () => Territory_editor.house.apartments.addApartment(id, num);
|
||||||
|
|
||||||
|
|
||||||
const infoDiv = document.createElement('div');
|
const infoDiv = document.createElement('div');
|
||||||
@@ -512,13 +512,13 @@ const Editor = {
|
|||||||
input.type = "text";
|
input.type = "text";
|
||||||
input.value = apartment.title;
|
input.value = apartment.title;
|
||||||
input.id = `apartment-input-${id}-${apartment.id}`;
|
input.id = `apartment-input-${id}-${apartment.id}`;
|
||||||
input.onchange = () => Editor.house.apartments.editApartment(id, apartment.id);
|
input.onchange = () => Territory_editor.house.apartments.editApartment(id, apartment.id);
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
const delBtn = document.createElement('button');
|
||||||
delBtn.type = "button";
|
delBtn.type = "button";
|
||||||
delBtn.title = "Видалити квартиру";
|
delBtn.title = "Видалити квартиру";
|
||||||
delBtn.innerHTML = `<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>`;
|
delBtn.innerHTML = `<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>`;
|
||||||
delBtn.onclick = () => Editor.house.apartments.deleteApartment(id, apartment.id);
|
delBtn.onclick = () => Territory_editor.house.apartments.deleteApartment(id, apartment.id);
|
||||||
|
|
||||||
apartmentDiv.append(input, delBtn);
|
apartmentDiv.append(input, delBtn);
|
||||||
floorDiv.prepend(apartmentDiv);
|
floorDiv.prepend(apartmentDiv);
|
||||||
@@ -573,7 +573,7 @@ const Editor = {
|
|||||||
addBtn.id = `buttonApartment-${entrance}-${newFloors}`;
|
addBtn.id = `buttonApartment-${entrance}-${newFloors}`;
|
||||||
addBtn.title = "Додати квартиру";
|
addBtn.title = "Додати квартиру";
|
||||||
addBtn.type = "button";
|
addBtn.type = "button";
|
||||||
addBtn.onclick = () => Editor.house.apartments.addApartment(entrance, newFloors);
|
addBtn.onclick = () => Territory_editor.house.apartments.addApartment(entrance, newFloors);
|
||||||
addBtn.innerHTML = `<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>`;
|
addBtn.innerHTML = `<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>`;
|
||||||
|
|
||||||
const infoDiv = document.createElement('div');
|
const infoDiv = document.createElement('div');
|
||||||
@@ -591,13 +591,13 @@ const Editor = {
|
|||||||
input.type = "text";
|
input.type = "text";
|
||||||
input.value = numApartments;
|
input.value = numApartments;
|
||||||
input.id = `apartment-input-${entrance}-${data.id}`;
|
input.id = `apartment-input-${entrance}-${data.id}`;
|
||||||
input.onchange = () => Editor.house.apartments.editApartment(entrance, data.id);
|
input.onchange = () => Territory_editor.house.apartments.editApartment(entrance, data.id);
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
const delBtn = document.createElement('button');
|
||||||
delBtn.type = "button";
|
delBtn.type = "button";
|
||||||
delBtn.title = "Видалити квартиру";
|
delBtn.title = "Видалити квартиру";
|
||||||
delBtn.innerHTML = `<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>`;
|
delBtn.innerHTML = `<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>`;
|
||||||
delBtn.onclick = () => Editor.house.apartments.deleteApartment(entrance, data.id);
|
delBtn.onclick = () => Territory_editor.house.apartments.deleteApartment(entrance, data.id);
|
||||||
apartmentBlock.append(input, delBtn);
|
apartmentBlock.append(input, delBtn);
|
||||||
|
|
||||||
|
|
||||||
@@ -667,13 +667,13 @@ const Editor = {
|
|||||||
input.type = "text";
|
input.type = "text";
|
||||||
input.value = numApartments;
|
input.value = numApartments;
|
||||||
input.id = `apartment-input-${entrance}-${data.id}`;
|
input.id = `apartment-input-${entrance}-${data.id}`;
|
||||||
input.onchange = () => Editor.house.apartments.editApartment(entrance, data.id);
|
input.onchange = () => Territory_editor.house.apartments.editApartment(entrance, data.id);
|
||||||
|
|
||||||
const delBtn = document.createElement('button');
|
const delBtn = document.createElement('button');
|
||||||
delBtn.type = "button";
|
delBtn.type = "button";
|
||||||
delBtn.title = "Видалити квартиру";
|
delBtn.title = "Видалити квартиру";
|
||||||
delBtn.innerHTML = `<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>`;
|
delBtn.innerHTML = `<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>`;
|
||||||
delBtn.onclick = () => Editor.house.apartments.deleteApartment(entrance, data.id);
|
delBtn.onclick = () => Territory_editor.house.apartments.deleteApartment(entrance, data.id);
|
||||||
|
|
||||||
apartmentDiv.append(input, delBtn);
|
apartmentDiv.append(input, delBtn);
|
||||||
floorDiv.insertBefore(apartmentDiv, floorDiv.querySelector(".floor-info"));
|
floorDiv.insertBefore(apartmentDiv, floorDiv.querySelector(".floor-info"));
|
||||||
@@ -770,8 +770,8 @@ const Editor = {
|
|||||||
|
|
||||||
osm: {
|
osm: {
|
||||||
init() {
|
init() {
|
||||||
const center = Editor.info.geo;
|
const center = Territory_editor.info.geo;
|
||||||
const zoom = Editor.info.zoom;
|
const zoom = Territory_editor.info.zoom;
|
||||||
|
|
||||||
const googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
|
const googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
|
||||||
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
|
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
|
||||||
@@ -829,15 +829,15 @@ const Editor = {
|
|||||||
let LatLngs = layer.getLatLngs();
|
let LatLngs = layer.getLatLngs();
|
||||||
LatLngs[0].push(LatLngs[0][0]);
|
LatLngs[0].push(LatLngs[0][0]);
|
||||||
|
|
||||||
Editor.info.points.push(LatLngs);
|
Territory_editor.info.points.push(LatLngs);
|
||||||
let geo = this.center(layer.getLatLngs());
|
let geo = this.center(layer.getLatLngs());
|
||||||
|
|
||||||
const house = layer; // сохраняем именно слой
|
const house = layer; // сохраняем именно слой
|
||||||
|
|
||||||
if (Editor.info.type === 'house') {
|
if (Territory_editor.info.type === 'house') {
|
||||||
houseGroup.addLayer(house);
|
houseGroup.addLayer(house);
|
||||||
Editor.info.points_number.push(this.center(layer.getLatLngs()));
|
Territory_editor.info.points_number.push(this.center(layer.getLatLngs()));
|
||||||
} else if (Editor.info.type === 'homestead') {
|
} else if (Territory_editor.info.type === 'homestead') {
|
||||||
homesteadGroup.addLayer(house);
|
homesteadGroup.addLayer(house);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -848,7 +848,7 @@ const Editor = {
|
|||||||
|
|
||||||
// при открытии popup вешаем обработчик удаления
|
// при открытии popup вешаем обработчик удаления
|
||||||
house.on('popupopen', (e) => {
|
house.on('popupopen', (e) => {
|
||||||
if (Editor.homestead.building.editing) {
|
if (Territory_editor.homestead.building.editing) {
|
||||||
house.closePopup();
|
house.closePopup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -856,12 +856,12 @@ const Editor = {
|
|||||||
const btn = e.popup.getElement().querySelector('.map_dell');
|
const btn = e.popup.getElement().querySelector('.map_dell');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
Editor.osm.delete(house);
|
Territory_editor.osm.delete(house);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Editor.osm.autoZoom(Editor.info.points);
|
Territory_editor.osm.autoZoom(Territory_editor.info.points);
|
||||||
});
|
});
|
||||||
|
|
||||||
map.pm.setLang("ua");
|
map.pm.setLang("ua");
|
||||||
@@ -872,31 +872,31 @@ const Editor = {
|
|||||||
buildingGroup.clearLayers();
|
buildingGroup.clearLayers();
|
||||||
pointsGroup.clearLayers();
|
pointsGroup.clearLayers();
|
||||||
|
|
||||||
for (let i = 0; i < Editor.info.points.length; i++) {
|
for (let i = 0; i < Territory_editor.info.points.length; i++) {
|
||||||
const LatLngs = Editor.info.points[i];
|
const LatLngs = Territory_editor.info.points[i];
|
||||||
|
|
||||||
// Создаем L.polygon
|
// Создаем L.polygon
|
||||||
const polyOptions = Editor.info.type === 'homestead'
|
const polyOptions = Territory_editor.info.type === 'homestead'
|
||||||
? { color: "#f2bd53", fillColor: "#f2bd53", fillOpacity: 0.4, dashArray: '5,10' }
|
? { color: "#f2bd53", fillColor: "#f2bd53", fillOpacity: 0.4, dashArray: '5,10' }
|
||||||
: { color: "#585858", fillColor: "#f2bd53", fillOpacity: 0.8 };
|
: { color: "#585858", fillColor: "#f2bd53", fillOpacity: 0.8 };
|
||||||
|
|
||||||
const house = L.polygon(LatLngs, polyOptions);
|
const house = L.polygon(LatLngs, polyOptions);
|
||||||
|
|
||||||
// Добавляем в нужную группу
|
// Добавляем в нужную группу
|
||||||
if (Editor.info.type === 'house') {
|
if (Territory_editor.info.type === 'house') {
|
||||||
houseGroup.addLayer(house);
|
houseGroup.addLayer(house);
|
||||||
} else if (Editor.info.type === 'homestead') {
|
} else if (Territory_editor.info.type === 'homestead') {
|
||||||
homesteadGroup.addLayer(house);
|
homesteadGroup.addLayer(house);
|
||||||
}
|
}
|
||||||
|
|
||||||
house.bindPopup(`
|
house.bindPopup(`
|
||||||
Координати: ${Editor.info.geo.lat.toFixed(5)}, ${Editor.info.geo.lng.toFixed(5)}<br>
|
Координати: ${Territory_editor.info.geo.lat.toFixed(5)}, ${Territory_editor.info.geo.lng.toFixed(5)}<br>
|
||||||
<button class="map_dell" type="button">Видалити</button>
|
<button class="map_dell" type="button">Видалити</button>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// при открытии popup вешаем обработчик удаления
|
// при открытии popup вешаем обработчик удаления
|
||||||
house.on('popupopen', (e) => {
|
house.on('popupopen', (e) => {
|
||||||
if (Editor.homestead.building.editing) {
|
if (Territory_editor.homestead.building.editing) {
|
||||||
house.closePopup();
|
house.closePopup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -904,17 +904,17 @@ const Editor = {
|
|||||||
const btn = e.popup.getElement().querySelector('.map_dell');
|
const btn = e.popup.getElement().querySelector('.map_dell');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
Editor.osm.delete(house);
|
Territory_editor.osm.delete(house);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Editor.osm.autoZoom(Editor.info.points);
|
Territory_editor.osm.autoZoom(Territory_editor.info.points);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
newPoligon() {
|
newPoligon() {
|
||||||
if (Editor.info.type === 'house') {
|
if (Territory_editor.info.type === 'house') {
|
||||||
map.pm.enableDraw('Polygon', {
|
map.pm.enableDraw('Polygon', {
|
||||||
snappable: true,
|
snappable: true,
|
||||||
snapDistance: 20,
|
snapDistance: 20,
|
||||||
@@ -936,7 +936,7 @@ const Editor = {
|
|||||||
fillOpacity: 0.8
|
fillOpacity: 0.8
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (Editor.info.type === 'homestead') {
|
} else if (Territory_editor.info.type === 'homestead') {
|
||||||
map.pm.enableDraw('Polygon', {
|
map.pm.enableDraw('Polygon', {
|
||||||
snappable: true,
|
snappable: true,
|
||||||
snapDistance: 20,
|
snapDistance: 20,
|
||||||
@@ -967,21 +967,21 @@ const Editor = {
|
|||||||
if (!IDs) return;
|
if (!IDs) return;
|
||||||
|
|
||||||
const ids_list = IDs.replace(/\s+/g, "").split(',');
|
const ids_list = IDs.replace(/\s+/g, "").split(',');
|
||||||
Editor.info.osm_id = ids_list;
|
Territory_editor.info.osm_id = ids_list;
|
||||||
|
|
||||||
houseGroup.clearLayers();
|
houseGroup.clearLayers();
|
||||||
homesteadGroup.clearLayers();
|
homesteadGroup.clearLayers();
|
||||||
|
|
||||||
Editor.info.points = [];
|
Territory_editor.info.points = [];
|
||||||
Editor.info.points_number = [];
|
Territory_editor.info.points_number = [];
|
||||||
Editor.info.geo = {}
|
Territory_editor.info.geo = {}
|
||||||
|
|
||||||
|
|
||||||
// 1006306041, 1006306065
|
// 1006306041, 1006306065
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < ids_list.length; i++) {
|
for (let i = 0; i < ids_list.length; i++) {
|
||||||
const element = await Editor.osm.getOSM(Editor.info.osm_id[i]);
|
const element = await Territory_editor.osm.getOSM(Territory_editor.info.osm_id[i]);
|
||||||
|
|
||||||
// Преобразуем координаты в LatLng
|
// Преобразуем координаты в LatLng
|
||||||
const LatLngs = [[]];
|
const LatLngs = [[]];
|
||||||
@@ -996,20 +996,20 @@ const Editor = {
|
|||||||
const center = this.center(LatLngs);
|
const center = this.center(LatLngs);
|
||||||
|
|
||||||
// Сохраняем в points / points_number
|
// Сохраняем в points / points_number
|
||||||
Editor.info.points.push(LatLngs);
|
Territory_editor.info.points.push(LatLngs);
|
||||||
Editor.info.points_number.push(center);
|
Territory_editor.info.points_number.push(center);
|
||||||
|
|
||||||
// Создаем L.polygon
|
// Создаем L.polygon
|
||||||
const polyOptions = Editor.info.type === 'homestead'
|
const polyOptions = Territory_editor.info.type === 'homestead'
|
||||||
? { color: "#f2bd53", fillColor: "#f2bd53", fillOpacity: 0.4, dashArray: '5,10' }
|
? { color: "#f2bd53", fillColor: "#f2bd53", fillOpacity: 0.4, dashArray: '5,10' }
|
||||||
: { color: "#585858", fillColor: "#f2bd53", fillOpacity: 0.8 };
|
: { color: "#585858", fillColor: "#f2bd53", fillOpacity: 0.8 };
|
||||||
|
|
||||||
const house = L.polygon(LatLngs, polyOptions);
|
const house = L.polygon(LatLngs, polyOptions);
|
||||||
|
|
||||||
// Добавляем в нужную группу
|
// Добавляем в нужную группу
|
||||||
if (Editor.info.type === 'house') {
|
if (Territory_editor.info.type === 'house') {
|
||||||
houseGroup.addLayer(house);
|
houseGroup.addLayer(house);
|
||||||
} else if (Editor.info.type === 'homestead') {
|
} else if (Territory_editor.info.type === 'homestead') {
|
||||||
homesteadGroup.addLayer(house);
|
homesteadGroup.addLayer(house);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,7 +1020,7 @@ const Editor = {
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
house.on('popupopen', (e) => {
|
house.on('popupopen', (e) => {
|
||||||
if (Editor.homestead.building.editing) {
|
if (Territory_editor.homestead.building.editing) {
|
||||||
house.closePopup();
|
house.closePopup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1028,13 +1028,13 @@ const Editor = {
|
|||||||
const btn = e.popup.getElement().querySelector('.map_dell');
|
const btn = e.popup.getElement().querySelector('.map_dell');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
Editor.osm.delete(house);
|
Territory_editor.osm.delete(house);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Editor.osm.autoZoom(Editor.info.points);
|
Territory_editor.osm.autoZoom(Territory_editor.info.points);
|
||||||
},
|
},
|
||||||
|
|
||||||
center(geo) {
|
center(geo) {
|
||||||
@@ -1101,16 +1101,16 @@ const Editor = {
|
|||||||
if (map.getZoom() > 18) map.setZoom(18);
|
if (map.getZoom() > 18) map.setZoom(18);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
Editor.info.zoom = map.getZoom();
|
Territory_editor.info.zoom = map.getZoom();
|
||||||
Editor.info.geo = map.getCenter();
|
Territory_editor.info.geo = map.getCenter();
|
||||||
}, 200)
|
}, 200)
|
||||||
},
|
},
|
||||||
|
|
||||||
delete(house) {
|
delete(house) {
|
||||||
// убрать слой с карты
|
// убрать слой с карты
|
||||||
if (Editor.info.type === 'house') {
|
if (Territory_editor.info.type === 'house') {
|
||||||
houseGroup.removeLayer(house);
|
houseGroup.removeLayer(house);
|
||||||
} else if (Editor.info.type === 'homestead') {
|
} else if (Territory_editor.info.type === 'homestead') {
|
||||||
homesteadGroup.removeLayer(house);
|
homesteadGroup.removeLayer(house);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1120,7 +1120,7 @@ const Editor = {
|
|||||||
target_1[0].push(target_1[0][0])
|
target_1[0].push(target_1[0][0])
|
||||||
|
|
||||||
|
|
||||||
const index = Editor.info.points.findIndex(
|
const index = Territory_editor.info.points.findIndex(
|
||||||
poly => {
|
poly => {
|
||||||
if(JSON.stringify(poly[0]) === JSON.stringify(target_1[0])) return true
|
if(JSON.stringify(poly[0]) === JSON.stringify(target_1[0])) return true
|
||||||
else if(JSON.stringify(poly[0]) === JSON.stringify(target_2[0])) return true
|
else if(JSON.stringify(poly[0]) === JSON.stringify(target_2[0])) return true
|
||||||
@@ -1130,17 +1130,17 @@ const Editor = {
|
|||||||
|
|
||||||
|
|
||||||
console.log("index ", index);
|
console.log("index ", index);
|
||||||
console.log(Editor.info.points);
|
console.log(Territory_editor.info.points);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
// удалить из points и points_number по индексу
|
// удалить из points и points_number по индексу
|
||||||
Editor.info.points.splice(index, 1);
|
Territory_editor.info.points.splice(index, 1);
|
||||||
Editor.info.points_number.splice(index, 1);
|
Territory_editor.info.points_number.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Editor.osm.autoZoom(Editor.info.points);
|
Territory_editor.osm.autoZoom(Territory_editor.info.points);
|
||||||
},
|
},
|
||||||
|
|
||||||
async getOSM(wayId) {
|
async getOSM(wayId) {
|
||||||
@@ -1171,13 +1171,13 @@ const Editor = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
console.log(Editor.info);
|
console.log(Territory_editor.info);
|
||||||
|
|
||||||
setLeafletCursor('pointer');
|
setLeafletCursor('pointer');
|
||||||
Editor.homestead.building.editing = false;
|
Territory_editor.homestead.building.editing = false;
|
||||||
|
|
||||||
const uuid = localStorage.getItem('uuid');
|
const uuid = localStorage.getItem('uuid');
|
||||||
const URL = `${CONFIG.api}${Editor.info.type}/${Editor.info.id}`;
|
const URL = `${CONFIG.api}${Territory_editor.info.type}/${Territory_editor.info.id}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(URL, {
|
const response = await fetch(URL, {
|
||||||
@@ -1186,7 +1186,7 @@ const Editor = {
|
|||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Authorization": uuid
|
"Authorization": uuid
|
||||||
},
|
},
|
||||||
body: JSON.stringify(Editor.info)
|
body: JSON.stringify(Territory_editor.info)
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@@ -2,7 +2,7 @@ const Territory_History = {
|
|||||||
list: [],
|
list: [],
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
let html = await fetch('/lib/pages/territory_history/index.html').then((response) => response.text());
|
let html = await fetch('/lib/pages/territory/history/index.html').then((response) => response.text());
|
||||||
app.innerHTML = html;
|
app.innerHTML = html;
|
||||||
|
|
||||||
this.setHTML()
|
this.setHTML()
|
||||||
@@ -23,7 +23,7 @@ const Territory_History = {
|
|||||||
|
|
||||||
async setHTML() {
|
async setHTML() {
|
||||||
const block_list = document.getElementById('list');
|
const block_list = document.getElementById('list');
|
||||||
const url = `${CONFIG.api}history/apartments/list?limit=5000`;
|
const url = `${CONFIG.api}history/apartments/list?limit=300`;
|
||||||
let list = this.list.length > 0 ? this.list : await this.loadAPI(url);
|
let list = this.list.length > 0 ? this.list : await this.loadAPI(url);
|
||||||
|
|
||||||
list.sort((a, b) => b.id - a.id);
|
list.sort((a, b) => b.id - a.id);
|
||||||
@@ -37,8 +37,6 @@ const Territory_History = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderCard: ({ element }) => {
|
renderCard: ({ element }) => {
|
||||||
console.log(element);
|
|
||||||
|
|
||||||
const labels = ["", "Відмова (Не цікавить)", "Не заходити (Груба відмова)", "Нема домофона", "Повторна відвідина", "Немає вдома", "Свідки Єгови"];
|
const labels = ["", "Відмова (Не цікавить)", "Не заходити (Груба відмова)", "Нема домофона", "Повторна відвідина", "Немає вдома", "Свідки Єгови"];
|
||||||
const color_status = [
|
const color_status = [
|
||||||
["var(--ColorThemes2)", "var(--ColorThemes3)"],
|
["var(--ColorThemes2)", "var(--ColorThemes3)"],
|
||||||
@@ -58,7 +56,7 @@ const Territory_History = {
|
|||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="card" style="background:${bg};color:${color};border:1px solid ${color}">
|
<div class="card" style="background:${bg};color:${color};border:1px solid ${color}">
|
||||||
<div class="info">
|
<div class="info" title="${element.id}">
|
||||||
<a href="/territory/card/house/${element.house_id}" class="address">
|
<a href="/territory/card/house/${element.house_id}" class="address">
|
||||||
<p title="${element.address.entrance}">${element.address.house.title} ${element.address.house.number}</p>
|
<p title="${element.address.entrance}">${element.address.house.title} ${element.address.house.number}</p>
|
||||||
</a>
|
</a>
|
||||||
@@ -69,7 +67,7 @@ const Territory_History = {
|
|||||||
<p>${labels[element.status]}</p>
|
<p>${labels[element.status]}</p>
|
||||||
</div>
|
</div>
|
||||||
<a href="/sheeps/${element.sheep.id}" class="name">
|
<a href="/sheeps/${element.sheep.id}" class="name">
|
||||||
<p>${element.sheep.name}</p>
|
<p>${element.sheep.name ?? "--"}</p>
|
||||||
</a>
|
</a>
|
||||||
<div class="date">
|
<div class="date">
|
||||||
<p>${formattedDateTime(element.created_at)}</p>
|
<p>${formattedDateTime(element.created_at)}</p>
|
||||||
@@ -1,19 +1,21 @@
|
|||||||
.page-territory_history {
|
.page-territory_history {
|
||||||
width: calc(100% - 18px);
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin: 20px 9px 0 9px;
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-territory_history>#list {
|
.page-territory_history>#list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-territory_history>#list>.card {
|
.page-territory_history>#list>.card {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: calc(100% - 2px);
|
min-width: calc(100% - 2px);
|
||||||
|
width: 700px;
|
||||||
background: var(--ColorThemes1);
|
background: var(--ColorThemes1);
|
||||||
border: 1px solid var(--ColorThemes2);
|
border: 1px solid var(--ColorThemes2);
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
@@ -66,6 +68,8 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 0 10px 10px 10px;
|
margin: 0 10px 10px 10px;
|
||||||
background: var(--ColorThemes0);
|
background: var(--ColorThemes0);
|
||||||
|
color: var(--ColorThemes3);
|
||||||
|
font-size: var(--FontSize2);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class="page-territory">
|
<div class="page-territory">
|
||||||
<div class="buttons-list" id="buttons-list">
|
<div class="buttons-list" id="buttons-list">
|
||||||
<a
|
<a
|
||||||
href="/constructor"
|
href="/territory/constructor"
|
||||||
data-route
|
data-route
|
||||||
id="constructorButton"
|
id="constructorButton"
|
||||||
style="display: none"
|
style="display: none"
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<span>Конструктор</span>
|
<span>Конструктор</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button onclick="Territory.report()">
|
<button onclick="Territory_list.report()">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
d="M13.13,2H5.958c-1.1,0-2,0.9-2,2v16c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V8.828c0-0.53-0.211-1.039-0.586-1.414l-4.828-4.828 C14.169,2.211,13.66,2,13.13,2z M11.255,17.711l-1.297-1.297l-1.251,1.293c-0.39,0.39-1.024,0.39-1.414,0l0,0 c-0.39-0.39-0.39-1.024,0-1.414l1.958-1.989c0.39-0.396,1.027-0.398,1.42-0.006l1.287,1.287l2.335-2.293 c0.39-0.39,1.024-0.39,1.414,0l0,0c0.39,0.39,0.39,1.024,0,1.414l-3.042,3.008C12.274,18.102,11.644,18.1,11.255,17.711z M12.958,9 V3.5l5.5,5.5H12.958z"
|
d="M13.13,2H5.958c-1.1,0-2,0.9-2,2v16c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V8.828c0-0.53-0.211-1.039-0.586-1.414l-4.828-4.828 C14.169,2.211,13.66,2,13.13,2z M11.255,17.711l-1.297-1.297l-1.251,1.293c-0.39,0.39-1.024,0.39-1.414,0l0,0 c-0.39-0.39-0.39-1.024,0-1.414l1.958-1.989c0.39-0.396,1.027-0.398,1.42-0.006l1.287,1.287l2.335-2.293 c0.39-0.39,1.024-0.39,1.414,0l0,0c0.39,0.39,0.39,1.024,0,1.414l-3.042,3.008C12.274,18.102,11.644,18.1,11.255,17.711z M12.958,9 V3.5l5.5,5.5H12.958z"
|
||||||
@@ -40,21 +40,21 @@
|
|||||||
|
|
||||||
<div class="list-controls">
|
<div class="list-controls">
|
||||||
<div id="page-territory-sort">
|
<div id="page-territory-sort">
|
||||||
<button id="sort_1" onclick="Territory.sort('2')" data-state="active">
|
<button id="sort_1" onclick="Territory_list.sort('2')" data-state="active">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
d="M 32.476562 5.9785156 A 1.50015 1.50015 0 0 0 31 7.5 L 31 37.878906 L 26.560547 33.439453 A 1.50015 1.50015 0 1 0 24.439453 35.560547 L 31.439453 42.560547 A 1.50015 1.50015 0 0 0 33.560547 42.560547 L 40.560547 35.560547 A 1.50015 1.50015 0 1 0 38.439453 33.439453 L 34 37.878906 L 34 7.5 A 1.50015 1.50015 0 0 0 32.476562 5.9785156 z M 14.375 8.0058594 C 14.257547 8.01575 14.139641 8.0379219 14.025391 8.0761719 L 11.025391 9.0761719 C 10.239391 9.3381719 9.8141719 10.188609 10.076172 10.974609 C 10.338172 11.760609 11.190609 12.188828 11.974609 11.923828 L 13 11.580078 L 13 20.5 C 13 21.329 13.671 22 14.5 22 C 15.329 22 16 21.329 16 20.5 L 16 9.5 C 16 9.018 15.767953 8.5652031 15.376953 8.2832031 C 15.082953 8.0717031 14.727359 7.9761875 14.375 8.0058594 z M 14 27 C 11.344 27 9.387625 28.682109 9.015625 31.287109 C 8.898625 32.107109 9.4671094 32.867375 10.287109 32.984375 C 11.106109 33.102375 11.867375 32.533891 11.984375 31.712891 C 12.096375 30.931891 12.537 30 14 30 C 15.103 30 16 30.897 16 32 C 16 33.103 15.103 34 14 34 C 11.592 34 9 35.721 9 39.5 C 9 40.329 9.672 41 10.5 41 L 17.5 41 C 18.329 41 19 40.329 19 39.5 C 19 38.671 18.329 38 17.5 38 L 12.308594 38 C 12.781594 37.093 13.664 37 14 37 C 16.757 37 19 34.757 19 32 C 19 29.243 16.757 27 14 27 z"
|
d="M 32.476562 5.9785156 A 1.50015 1.50015 0 0 0 31 7.5 L 31 37.878906 L 26.560547 33.439453 A 1.50015 1.50015 0 1 0 24.439453 35.560547 L 31.439453 42.560547 A 1.50015 1.50015 0 0 0 33.560547 42.560547 L 40.560547 35.560547 A 1.50015 1.50015 0 1 0 38.439453 33.439453 L 34 37.878906 L 34 7.5 A 1.50015 1.50015 0 0 0 32.476562 5.9785156 z M 14.375 8.0058594 C 14.257547 8.01575 14.139641 8.0379219 14.025391 8.0761719 L 11.025391 9.0761719 C 10.239391 9.3381719 9.8141719 10.188609 10.076172 10.974609 C 10.338172 11.760609 11.190609 12.188828 11.974609 11.923828 L 13 11.580078 L 13 20.5 C 13 21.329 13.671 22 14.5 22 C 15.329 22 16 21.329 16 20.5 L 16 9.5 C 16 9.018 15.767953 8.5652031 15.376953 8.2832031 C 15.082953 8.0717031 14.727359 7.9761875 14.375 8.0058594 z M 14 27 C 11.344 27 9.387625 28.682109 9.015625 31.287109 C 8.898625 32.107109 9.4671094 32.867375 10.287109 32.984375 C 11.106109 33.102375 11.867375 32.533891 11.984375 31.712891 C 12.096375 30.931891 12.537 30 14 30 C 15.103 30 16 30.897 16 32 C 16 33.103 15.103 34 14 34 C 11.592 34 9 35.721 9 39.5 C 9 40.329 9.672 41 10.5 41 L 17.5 41 C 18.329 41 19 40.329 19 39.5 C 19 38.671 18.329 38 17.5 38 L 12.308594 38 C 12.781594 37.093 13.664 37 14 37 C 16.757 37 19 34.757 19 32 C 19 29.243 16.757 27 14 27 z"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button id="sort_2" onclick="Territory.sort('3')" data-state="">
|
<button id="sort_2" onclick="Territory_list.sort('3')" data-state="">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
d="M 31.478516 6 A 1.50015 1.50015 0 0 0 30.439453 6.4394531 L 23.439453 13.439453 A 1.50015 1.50015 0 1 0 25.560547 15.560547 L 30 11.121094 L 30 41.5 A 1.50015 1.50015 0 1 0 33 41.5 L 33 11.121094 L 37.439453 15.560547 A 1.50015 1.50015 0 1 0 39.560547 13.439453 L 32.560547 6.4394531 A 1.50015 1.50015 0 0 0 31.478516 6 z M 13.375 8.0058594 C 13.257547 8.01575 13.139641 8.0379219 13.025391 8.0761719 L 10.025391 9.0761719 C 9.2393906 9.3381719 8.8141719 10.188609 9.0761719 10.974609 C 9.3381719 11.760609 10.190609 12.188828 10.974609 11.923828 L 12 11.580078 L 12 20.5 C 12 21.329 12.671 22 13.5 22 C 14.329 22 15 21.329 15 20.5 L 15 9.5 C 15 9.018 14.767953 8.5652031 14.376953 8.2832031 C 14.082953 8.0717031 13.727359 7.9761875 13.375 8.0058594 z M 13 27 C 10.344 27 8.387625 28.682109 8.015625 31.287109 C 7.898625 32.107109 8.4671094 32.867375 9.2871094 32.984375 C 10.106109 33.102375 10.867375 32.533891 10.984375 31.712891 C 11.096375 30.931891 11.537 30 13 30 C 14.103 30 15 30.897 15 32 C 15 33.103 14.103 34 13 34 C 10.592 34 8 35.721 8 39.5 C 8 40.329 8.672 41 9.5 41 L 16.5 41 C 17.329 41 18 40.329 18 39.5 C 18 38.671 17.329 38 16.5 38 L 11.308594 38 C 11.781594 37.093 12.664 37 13 37 C 15.757 37 18 34.757 18 32 C 18 29.243 15.757 27 13 27 z"
|
d="M 31.478516 6 A 1.50015 1.50015 0 0 0 30.439453 6.4394531 L 23.439453 13.439453 A 1.50015 1.50015 0 1 0 25.560547 15.560547 L 30 11.121094 L 30 41.5 A 1.50015 1.50015 0 1 0 33 41.5 L 33 11.121094 L 37.439453 15.560547 A 1.50015 1.50015 0 1 0 39.560547 13.439453 L 32.560547 6.4394531 A 1.50015 1.50015 0 0 0 31.478516 6 z M 13.375 8.0058594 C 13.257547 8.01575 13.139641 8.0379219 13.025391 8.0761719 L 10.025391 9.0761719 C 9.2393906 9.3381719 8.8141719 10.188609 9.0761719 10.974609 C 9.3381719 11.760609 10.190609 12.188828 10.974609 11.923828 L 12 11.580078 L 12 20.5 C 12 21.329 12.671 22 13.5 22 C 14.329 22 15 21.329 15 20.5 L 15 9.5 C 15 9.018 14.767953 8.5652031 14.376953 8.2832031 C 14.082953 8.0717031 13.727359 7.9761875 13.375 8.0058594 z M 13 27 C 10.344 27 8.387625 28.682109 8.015625 31.287109 C 7.898625 32.107109 8.4671094 32.867375 9.2871094 32.984375 C 10.106109 33.102375 10.867375 32.533891 10.984375 31.712891 C 11.096375 30.931891 11.537 30 13 30 C 14.103 30 15 30.897 15 32 C 15 33.103 14.103 34 13 34 C 10.592 34 8 35.721 8 39.5 C 8 40.329 8.672 41 9.5 41 L 16.5 41 C 17.329 41 18 40.329 18 39.5 C 18 38.671 17.329 38 16.5 38 L 11.308594 38 C 11.781594 37.093 12.664 37 13 37 C 15.757 37 18 34.757 18 32 C 18 29.243 15.757 27 13 27 z"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button id="sort_3" onclick="Territory.sort('4')" data-state="">
|
<button id="sort_3" onclick="Territory_list.sort('4')" data-state="">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
transform="rotate(180 32.5 24.5106)"
|
transform="rotate(180 32.5 24.5106)"
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button id="sort_4" onclick="Territory.sort('1')" data-state="">
|
<button id="sort_4" onclick="Territory_list.sort('1')" data-state="">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
<path
|
<path
|
||||||
id="svg_1"
|
id="svg_1"
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
<select
|
<select
|
||||||
id="list-controls-filter-status"
|
id="list-controls-filter-status"
|
||||||
name="status"
|
name="status"
|
||||||
onchange="Territory.filter()"
|
onchange="Territory_list.filter()"
|
||||||
>
|
>
|
||||||
<option value="0" selected>Всі території</option>
|
<option value="0" selected>Всі території</option>
|
||||||
<option value="1">Зайняті території</option>
|
<option value="1">Зайняті території</option>
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
id="territory_entrances_true"
|
id="territory_entrances_true"
|
||||||
onclick="Territory.house.territoryType('true')"
|
onclick="Territory_list.house.territoryType('true')"
|
||||||
data-state=""
|
data-state=""
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
id="territory_entrances_false"
|
id="territory_entrances_false"
|
||||||
onclick="Territory.house.territoryType('false')"
|
onclick="Territory_list.house.territoryType('false')"
|
||||||
data-state=""
|
data-state=""
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
const Territory = {
|
const Territory_list = {
|
||||||
init: async () => {
|
init: async () => {
|
||||||
let html = await fetch('/lib/pages/territory/index.html').then((response) => response.text());
|
let html = await fetch('/lib/pages/territory/list/index.html').then((response) => response.text());
|
||||||
app.innerHTML = html;
|
app.innerHTML = html;
|
||||||
|
|
||||||
let selectStatus = document.getElementById('list-controls-filter-status');
|
let selectStatus = document.getElementById('list-controls-filter-status');
|
||||||
@@ -17,7 +17,7 @@ const Territory = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Застосовуємо режим сортування
|
// Застосовуємо режим сортування
|
||||||
Territory.sort(localStorage.getItem('territory_sort_mode'));
|
Territory_list.sort(localStorage.getItem('territory_sort_mode'));
|
||||||
|
|
||||||
|
|
||||||
if (localStorage.getItem('territory_entrances') == 'true') {
|
if (localStorage.getItem('territory_entrances') == 'true') {
|
||||||
@@ -37,8 +37,8 @@ const Territory = {
|
|||||||
});
|
});
|
||||||
localStorage.setItem('territory_sort_mode', idx);
|
localStorage.setItem('territory_sort_mode', idx);
|
||||||
|
|
||||||
Territory.house.setHTML();
|
Territory_list.house.setHTML();
|
||||||
Territory.homestead.setHTML();
|
Territory_list.homestead.setHTML();
|
||||||
},
|
},
|
||||||
|
|
||||||
house: {
|
house: {
|
||||||
@@ -52,8 +52,8 @@ const Territory = {
|
|||||||
"Authorization": uuid
|
"Authorization": uuid
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Territory.house.list = await response.json();
|
Territory_list.house.list = await response.json();
|
||||||
return Territory.house.list;
|
return Territory_list.house.list;
|
||||||
},
|
},
|
||||||
setHTML: async function () {
|
setHTML: async function () {
|
||||||
const block_house = document.getElementById('list-house');
|
const block_house = document.getElementById('list-house');
|
||||||
@@ -164,8 +164,8 @@ const Territory = {
|
|||||||
localStorage.setItem('territory_entrances', type);
|
localStorage.setItem('territory_entrances', type);
|
||||||
document.getElementById('territory_entrances_true').setAttribute('data-state', type === 'false' ? 'active' : '');
|
document.getElementById('territory_entrances_true').setAttribute('data-state', type === 'false' ? 'active' : '');
|
||||||
document.getElementById('territory_entrances_false').setAttribute('data-state', type === 'true' ? 'active' : '');
|
document.getElementById('territory_entrances_false').setAttribute('data-state', type === 'true' ? 'active' : '');
|
||||||
Territory.house.list = [];
|
Territory_list.house.list = [];
|
||||||
Territory.house.setHTML();
|
Territory_list.house.setHTML();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
homestead: {
|
homestead: {
|
||||||
@@ -247,8 +247,8 @@ const Territory = {
|
|||||||
localStorage.setItem("filterStatus", selectStatus);
|
localStorage.setItem("filterStatus", selectStatus);
|
||||||
|
|
||||||
|
|
||||||
Territory.house.setHTML();
|
Territory_list.house.setHTML();
|
||||||
Territory.homestead.setHTML();
|
Territory_list.homestead.setHTML();
|
||||||
},
|
},
|
||||||
report: async () => {
|
report: async () => {
|
||||||
const uuid = localStorage.getItem("uuid");
|
const uuid = localStorage.getItem("uuid");
|
||||||
@@ -2,7 +2,7 @@ let map_territory, type_territory;
|
|||||||
|
|
||||||
const Territory_Manager = {
|
const Territory_Manager = {
|
||||||
init: async (type, id) => {
|
init: async (type, id) => {
|
||||||
let html = await fetch('/lib/pages/territory_manager/index.html').then((response) => response.text());
|
let html = await fetch('/lib/pages/territory/manager/index.html').then((response) => response.text());
|
||||||
app.innerHTML = html;
|
app.innerHTML = html;
|
||||||
|
|
||||||
type_territory = type;
|
type_territory = type;
|
||||||
@@ -3,17 +3,21 @@ Router
|
|||||||
pageActive('');
|
pageActive('');
|
||||||
Auth.init();;
|
Auth.init();;
|
||||||
})
|
})
|
||||||
|
.add('territory/constructor', function () {
|
||||||
|
pageActive();
|
||||||
|
Territory_constructor.init();;
|
||||||
|
})
|
||||||
.add('territory/manager/(.*)/(.*)', function (type, id) {
|
.add('territory/manager/(.*)/(.*)', function (type, id) {
|
||||||
pageActive();
|
pageActive();
|
||||||
Territory_Manager.init(type, id);
|
Territory_Manager.init(type, id);
|
||||||
})
|
})
|
||||||
.add('territory/editor/(.*)/(.*)', function (type, id) {
|
.add('territory/editor/(.*)/(.*)', function (type, id) {
|
||||||
pageActive();
|
pageActive();
|
||||||
Editor.init(type, id);
|
Territory_editor.init(type, id);
|
||||||
})
|
})
|
||||||
.add('territory/card/(.*)/(.*)', function (type, id) {
|
.add('territory/card/(.*)/(.*)', function (type, id) {
|
||||||
pageActive();
|
pageActive();
|
||||||
Card.init(type, id);
|
Territory_card.init(type, id);
|
||||||
})
|
})
|
||||||
.add('territory/history', function () {
|
.add('territory/history', function () {
|
||||||
pageActive();
|
pageActive();
|
||||||
@@ -21,7 +25,7 @@ Router
|
|||||||
})
|
})
|
||||||
.add('territory', function () {
|
.add('territory', function () {
|
||||||
pageActive('territory');
|
pageActive('territory');
|
||||||
Territory.init();
|
Territory_list.init();
|
||||||
})
|
})
|
||||||
.add('sheeps/(.*)', function (name) {
|
.add('sheeps/(.*)', function (name) {
|
||||||
pageActive('sheeps');
|
pageActive('sheeps');
|
||||||
@@ -39,18 +43,18 @@ Router
|
|||||||
pageActive('schedule');
|
pageActive('schedule');
|
||||||
Schedule.init();;
|
Schedule.init();;
|
||||||
})
|
})
|
||||||
|
.add('stand/card/(.*)', function (id) {
|
||||||
|
pageActive();
|
||||||
|
Stand_card.init(id);;
|
||||||
|
})
|
||||||
.add('stand', function () {
|
.add('stand', function () {
|
||||||
pageActive('stand');
|
pageActive('stand');
|
||||||
Stand.init();;
|
Stand_list.init();;
|
||||||
})
|
})
|
||||||
.add('options', function () {
|
.add('options', function () {
|
||||||
pageActive('options');
|
pageActive('options');
|
||||||
Options.init();;
|
Options.init();;
|
||||||
})
|
})
|
||||||
.add('constructor', function () {
|
|
||||||
pageActive();
|
|
||||||
Constructor.init();;
|
|
||||||
})
|
|
||||||
.add(function () {
|
.add(function () {
|
||||||
page_404();;
|
page_404();;
|
||||||
pageActive();
|
pageActive();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const path = require("path");
|
|||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const PORT = process.env.WEB_PORT || 4002;
|
const PORT = 4002;
|
||||||
const DIR_CARDS = process.env.CARDS_PATH || path.join(__dirname, '../cards');
|
const DIR_CARDS = process.env.CARDS_PATH || path.join(__dirname, '../cards');
|
||||||
const DIR_MAP = process.env.MAP_PATH || path.join(__dirname, '../map');
|
const DIR_MAP = process.env.MAP_PATH || path.join(__dirname, '../map');
|
||||||
|
|
||||||
|
|||||||
21
ws/config/db.js
Normal file
21
ws/config/db.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const sqlite3 = require("sqlite3");
|
||||||
|
const path = require("path");
|
||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
const dbPath = process.env.DATABASE_PATH || path.join(__dirname, ".."); // если в .env относительный путь
|
||||||
|
const fileName = process.env.DATABASE_FILE || "database.sqlite";
|
||||||
|
|
||||||
|
const fullPath = path.isAbsolute(dbPath) ? path.join(dbPath, fileName) : path.join(dbPath, fileName);
|
||||||
|
|
||||||
|
const db = new sqlite3.Database(fullPath, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("❌ Failed to open sqlite database:", err);
|
||||||
|
} else {
|
||||||
|
console.log("✅ SQLite DB opened at", fullPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// optional: enable foreign keys
|
||||||
|
db.exec("PRAGMA foreign_keys = ON;");
|
||||||
|
|
||||||
|
module.exports = db;
|
||||||
50
ws/middleware/auth.js
Normal file
50
ws/middleware/auth.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
const db = require("../config/db");
|
||||||
|
|
||||||
|
async function auth(uuid) {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
db.get(`
|
||||||
|
SELECT
|
||||||
|
sheeps.*,
|
||||||
|
possibilities.can_add_sheeps,
|
||||||
|
possibilities.can_view_sheeps,
|
||||||
|
possibilities.can_add_territory,
|
||||||
|
possibilities.can_view_territory,
|
||||||
|
possibilities.can_manager_territory,
|
||||||
|
possibilities.can_add_stand,
|
||||||
|
possibilities.can_view_stand,
|
||||||
|
possibilities.can_manager_stand,
|
||||||
|
possibilities.can_add_schedule,
|
||||||
|
possibilities.can_view_schedule
|
||||||
|
FROM sheeps
|
||||||
|
LEFT JOIN possibilities ON possibilities.sheep_id = sheeps.id
|
||||||
|
WHERE sheeps.uuid_manager = ? OR sheeps.uuid = ?
|
||||||
|
`, [uuid, uuid], (err, row) => {
|
||||||
|
if (err) return rej(err);
|
||||||
|
if (!row) return res(false);
|
||||||
|
|
||||||
|
res({
|
||||||
|
id: row.id,
|
||||||
|
name: row.name,
|
||||||
|
uuid: row.uuid,
|
||||||
|
group_id: row.group_id,
|
||||||
|
icon: row.icon,
|
||||||
|
appointment: row.appointment,
|
||||||
|
sheepRole: row.mode_title,
|
||||||
|
possibilities: {
|
||||||
|
can_add_sheeps: !!row.can_add_sheeps,
|
||||||
|
can_view_sheeps: !!row.can_view_sheeps,
|
||||||
|
can_add_territory: !!row.can_add_territory,
|
||||||
|
can_view_territory: !!row.can_view_territory,
|
||||||
|
can_manager_territory: !!row.can_manager_territory,
|
||||||
|
can_add_stand: !!row.can_add_stand,
|
||||||
|
can_view_stand: !!row.can_view_stand,
|
||||||
|
can_manager_stand: !!row.can_manager_stand,
|
||||||
|
can_add_schedule: !!row.can_add_schedule,
|
||||||
|
can_view_schedule: !!row.can_view_schedule,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { auth };
|
||||||
11
ws/middleware/requirePermission.js
Normal file
11
ws/middleware/requirePermission.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
function requirePermission(permission, ws, next) {
|
||||||
|
if (!ws.user) {
|
||||||
|
return ws.send(JSON.stringify({ error: "Unauthorized" }));
|
||||||
|
}
|
||||||
|
if (!ws.user.possibilities[permission]) {
|
||||||
|
return ws.send(JSON.stringify({ error: `Forbidden: missing ${permission}` }));
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { requirePermission };
|
||||||
6
ws/routes/connection.js
Normal file
6
ws/routes/connection.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const { broadcast } = require("../utils/broadcaster");
|
||||||
|
|
||||||
|
module.exports = (wss, ws, message) => {
|
||||||
|
console.log(`🔗 Connection event from ${ws.user.name}`);
|
||||||
|
broadcast(wss, { event: "user_connected", user: {name: ws.user.name, id: ws.user.id } });
|
||||||
|
};
|
||||||
18
ws/routes/index.js
Normal file
18
ws/routes/index.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const connectionRoute = require("./connection");
|
||||||
|
const messageRoute = require("./message");
|
||||||
|
|
||||||
|
const routes = {
|
||||||
|
connection: connectionRoute,
|
||||||
|
message: messageRoute,
|
||||||
|
};
|
||||||
|
|
||||||
|
function routeMessage(wss, ws, message) {
|
||||||
|
const handler = routes[message.event];
|
||||||
|
if (handler) {
|
||||||
|
handler(wss, ws, message);
|
||||||
|
} else {
|
||||||
|
ws.send(JSON.stringify({ error: `Unknown event: ${message.event}` }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { routeMessage };
|
||||||
25
ws/routes/message.js
Normal file
25
ws/routes/message.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
const { updateApartment } = require("../services/apartments.service");
|
||||||
|
const { updateBuilding } = require("../services/buildings.service");
|
||||||
|
const { updateStand } = require("../services/stand.service");
|
||||||
|
const { broadcast } = require("../utils/broadcaster");
|
||||||
|
|
||||||
|
module.exports = async (wss, ws, message) => {
|
||||||
|
try {
|
||||||
|
switch (message.type) {
|
||||||
|
case "apartment":
|
||||||
|
await updateApartment(ws.user, message.data);
|
||||||
|
break;
|
||||||
|
case "building":
|
||||||
|
await updateBuilding(ws.user, message.data);
|
||||||
|
break;
|
||||||
|
case "stand":
|
||||||
|
await updateStand(ws.user, message.data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ws.send(JSON.stringify({ error: `Unknown message type: ${message.type}` }));
|
||||||
|
}
|
||||||
|
broadcast(wss, message);
|
||||||
|
} catch (err) {
|
||||||
|
ws.send(JSON.stringify({ error: err.message }));
|
||||||
|
}
|
||||||
|
};
|
||||||
31
ws/services/apartments.service.js
Normal file
31
ws/services/apartments.service.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
const db = require("../config/db");
|
||||||
|
|
||||||
|
function updateApartment(user, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!user.possibilities.can_manager_territory) {
|
||||||
|
return reject(new Error("Forbidden: no rights to manage territory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const sql = `
|
||||||
|
UPDATE apartments
|
||||||
|
SET status = ?, description = ?, sheep_id = ?, updated_at = ?
|
||||||
|
WHERE id = ?`;
|
||||||
|
|
||||||
|
db.run(sql, [Number(data.status), data.description, data.sheep_id, data.updated_at, data.id], function (err) {
|
||||||
|
if (err) return reject(err);
|
||||||
|
if (this.changes === 0) return reject(new Error("Apartment not found"));
|
||||||
|
|
||||||
|
const insertSql = `
|
||||||
|
INSERT INTO apartments_history
|
||||||
|
(apartments_id, status, description, sheep_id, created_at)
|
||||||
|
VALUES (?, ?, ?, ?, ?)`;
|
||||||
|
|
||||||
|
db.run(insertSql, [Number(data.id), Number(data.status), data.description, data.sheep_id, Date.now()], function (err) {
|
||||||
|
if (err) return reject(err);
|
||||||
|
resolve({ update: "ok", id: data.id, historyId: this.lastID });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { updateApartment };
|
||||||
31
ws/services/buildings.service.js
Normal file
31
ws/services/buildings.service.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
const db = require("../config/db");
|
||||||
|
|
||||||
|
function updateBuilding(user, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!user.possibilities.can_manager_territory) {
|
||||||
|
return reject(new Error("Forbidden: no rights to manage territory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const sql = `
|
||||||
|
UPDATE buildings
|
||||||
|
SET status = ?, description = ?, sheep_id = ?, updated_at = ?
|
||||||
|
WHERE id = ?`;
|
||||||
|
|
||||||
|
db.run(sql, [Number(data.status), data.description, data.sheep_id, data.updated_at, data.id], function (err) {
|
||||||
|
if (err) return reject(err);
|
||||||
|
if (this.changes === 0) return reject(new Error("Building not found"));
|
||||||
|
|
||||||
|
const insertSql = `
|
||||||
|
INSERT INTO buildings_history
|
||||||
|
(buildings_id, status, description, sheep_id, created_at)
|
||||||
|
VALUES (?, ?, ?, ?, ?)`;
|
||||||
|
|
||||||
|
db.run(insertSql, [Number(data.id), Number(data.status), data.description, data.sheep_id, Date.now()], function (err) {
|
||||||
|
if (err) return reject(err);
|
||||||
|
resolve({ update: "ok", id: data.id, historyId: this.lastID });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { updateBuilding };
|
||||||
31
ws/services/stand.service.js
Normal file
31
ws/services/stand.service.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
const db = require("../config/db");
|
||||||
|
|
||||||
|
function updateStand(user, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!user.possibilities.can_manager_territory) {
|
||||||
|
return reject(new Error("Forbidden: no rights to manage territory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const sql = `
|
||||||
|
UPDATE buildings
|
||||||
|
SET status = ?, description = ?, sheep_id = ?, updated_at = ?
|
||||||
|
WHERE id = ?`;
|
||||||
|
|
||||||
|
db.run(sql, [Number(data.status), data.description, data.sheep_id, data.updated_at, data.id], function (err) {
|
||||||
|
if (err) return reject(err);
|
||||||
|
if (this.changes === 0) return reject(new Error("Building not found"));
|
||||||
|
|
||||||
|
const insertSql = `
|
||||||
|
INSERT INTO buildings_history
|
||||||
|
(buildings_id, status, description, sheep_id, created_at)
|
||||||
|
VALUES (?, ?, ?, ?, ?)`;
|
||||||
|
|
||||||
|
db.run(insertSql, [Number(data.id), Number(data.status), data.description, data.sheep_id, Date.now()], function (err) {
|
||||||
|
if (err) return reject(err);
|
||||||
|
resolve({ update: "ok", id: data.id, historyId: this.lastID });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { updateStand };
|
||||||
8
ws/utils/broadcaster.js
Normal file
8
ws/utils/broadcaster.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
function broadcast(wss, message) {
|
||||||
|
wss.clients.forEach(client => {
|
||||||
|
if (client.readyState === 1) {
|
||||||
|
client.send(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
module.exports = { broadcast };
|
||||||
14
ws/utils/ping.js
Normal file
14
ws/utils/ping.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
function setupPing(ws) {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (ws.readyState === 1) {
|
||||||
|
ws.ping("ping");
|
||||||
|
} else {
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
|
ws.on("pong", (data) => {
|
||||||
|
console.log("📡 PONG from client:", data.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
module.exports = { setupPing };
|
||||||
240
ws/ws.js
240
ws/ws.js
@@ -1,226 +1,50 @@
|
|||||||
const WebSocket = require("ws");
|
const WebSocket = require("ws");
|
||||||
const { URL } = require('url');
|
const { URL } = require('url');
|
||||||
const sqlite3 = require('sqlite3');
|
const { routeMessage } = require("./routes");
|
||||||
const path = require('path');
|
const { auth } = require("./middleware/auth");
|
||||||
|
const { setupPing } = require("./utils/ping");
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
const dbPath = process.env.DATABASE_PATH || '../';
|
const api_version = '1.1.0';
|
||||||
const db = new sqlite3.Database(path.join(dbPath, 'database.sqlite'));
|
|
||||||
|
|
||||||
const port = process.env.WS_PORT || 4001;
|
const wss = new WebSocket.Server({ port: 4004 });
|
||||||
const api_version = '1.0.0';
|
console.log("WebSocket сервер запущен на порту 4004");
|
||||||
|
|
||||||
const wss = new WebSocket.Server({
|
|
||||||
port: port
|
|
||||||
}, () => console.log(`Server started on port ${port}`));
|
|
||||||
|
|
||||||
|
|
||||||
wss.on('connection', async (ws, request) => {
|
wss.on("connection", async (ws, request) => {
|
||||||
const url = new URL(request.url, `http://${request.headers.host}`)
|
const url = new URL(request.url, `http://${request.headers.host}`);
|
||||||
const params = Object.fromEntries(url.searchParams.entries());
|
const params = Object.fromEntries(url.searchParams.entries());
|
||||||
const uuid = params.uuid;
|
const uuid = params.uuid ?? ws.protocol;
|
||||||
|
|
||||||
if (!uuid) return
|
if (!uuid) return ws.close();
|
||||||
|
|
||||||
let check = await checkUUID(uuid);
|
const user = await auth(uuid);
|
||||||
|
if (!user) return ws.close();
|
||||||
|
|
||||||
console.log(check);
|
try {
|
||||||
|
const user = await auth(uuid);
|
||||||
|
if (!user) return ws.close();
|
||||||
|
|
||||||
|
ws.user = user;
|
||||||
|
ws.send(JSON.stringify({ connection: "success", api_version, user: {name: ws.user.name, id: ws.user.id } }));
|
||||||
|
|
||||||
if (!check && check.possibilities.can_view_territory) return
|
// Periodic ping to maintain a connection
|
||||||
|
setupPing(ws);
|
||||||
|
|
||||||
// Periodic ping to maintain a connection
|
ws.on("message", (raw) => {
|
||||||
const pingInterval = setInterval(() => {
|
try {
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
const message = JSON.parse(raw);
|
||||||
ws.ping('ping');
|
routeMessage(wss, ws, message);
|
||||||
}
|
} catch (e) {
|
||||||
}, 30000);
|
console.error("❌ Invalid message:", raw);
|
||||||
|
ws.send(JSON.stringify({ error: "Invalid message format" }));
|
||||||
|
|
||||||
ws.send(JSON.stringify({ "connection": "success", "api_version": api_version }));
|
|
||||||
|
|
||||||
ws.on('message', (message) => {
|
|
||||||
message = JSON.parse(message);
|
|
||||||
|
|
||||||
console.log(message.username, check.name);
|
|
||||||
|
|
||||||
switch (message.event) {
|
|
||||||
case "connection":
|
|
||||||
broadcastMessage(message);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "message":
|
|
||||||
updateDatabase(message);
|
|
||||||
broadcastMessage(message);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('pong', (data) => {
|
|
||||||
console.log('PONG received from the client:', data.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('close', () => {
|
|
||||||
console.log('Client close');
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('error', (err) => {
|
|
||||||
console.error('ERROR WebSocket:', err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function broadcastMessage(message) {
|
|
||||||
wss.clients.forEach(client => {
|
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
|
||||||
client.send(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateDatabase(message) {
|
|
||||||
|
|
||||||
console.log(message.type);
|
|
||||||
|
|
||||||
|
|
||||||
if (message.type === "apartment") {
|
|
||||||
|
|
||||||
let sql = 'UPDATE apartments SET status = ?, description = ?, sheep_id = ?, updated_at = ? WHERE id = ?';
|
|
||||||
|
|
||||||
db.run(sql, [
|
|
||||||
Number(message.data.status),
|
|
||||||
message.data.description,
|
|
||||||
message.data.sheep_id,
|
|
||||||
message.data.updated_at,
|
|
||||||
message.data.id
|
|
||||||
], function (err) {
|
|
||||||
if (err) {
|
|
||||||
console.error(err.message);
|
|
||||||
} else if (this.changes === 0) {
|
|
||||||
console.error('Product not found');
|
|
||||||
} else {
|
|
||||||
console.log({ "update": "ok", "id": message.data.id });
|
|
||||||
|
|
||||||
let sql = `INSERT INTO apartments_history (apartments_id, status, description, sheep_id, created_at) VALUES (?, ?, ?, ?, ?)`;
|
|
||||||
|
|
||||||
db.run(sql, [
|
|
||||||
Number(message.data.id),
|
|
||||||
Number(message.data.status),
|
|
||||||
message.data.description,
|
|
||||||
message.data.sheep_id,
|
|
||||||
Math.floor(Date.now())
|
|
||||||
], function (err) {
|
|
||||||
if (err) {
|
|
||||||
console.error(err.message);
|
|
||||||
} else if (this.changes === 0) {
|
|
||||||
console.error('Apartments not found');
|
|
||||||
} else {
|
|
||||||
console.log({ "insert": "ok", "id": this.lastID });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if(message.type === "building") {
|
|
||||||
let sql = 'UPDATE buildings SET status = ?, description = ?, sheep_id = ?, updated_at = ? WHERE id = ?';
|
|
||||||
|
|
||||||
db.run(sql, [
|
ws.on("close", () => console.log("🔌 Client disconnected"));
|
||||||
Number(message.data.status),
|
ws.on("error", (err) => console.error("❌ WS error:", err));
|
||||||
message.data.description,
|
} catch (err) {
|
||||||
message.data.sheep_id,
|
console.error("❌ Auth error:", err);
|
||||||
message.data.updated_at,
|
ws.close();
|
||||||
message.data.id
|
|
||||||
], function (err) {
|
|
||||||
if (err) {
|
|
||||||
console.error(err.message);
|
|
||||||
} else if (this.changes === 0) {
|
|
||||||
console.error('Product not found');
|
|
||||||
} else {
|
|
||||||
console.log({ "update": "ok", "id": message.data.id });
|
|
||||||
|
|
||||||
let sql = `INSERT INTO buildings_history (buildings_id, status, description, sheep_id, created_at) VALUES (?, ?, ?, ?, ?)`;
|
|
||||||
|
|
||||||
db.run(sql, [
|
|
||||||
Number(message.data.id),
|
|
||||||
Number(message.data.status),
|
|
||||||
message.data.description,
|
|
||||||
message.data.sheep_id,
|
|
||||||
Math.floor(Date.now())
|
|
||||||
], function (err) {
|
|
||||||
if (err) {
|
|
||||||
console.error(err.message);
|
|
||||||
} else if (this.changes === 0) {
|
|
||||||
console.error('Apartments not found');
|
|
||||||
} else {
|
|
||||||
console.log({ "insert": "ok", "id": this.lastID });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
async function checkUUID(uuid) {
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
db.get(`
|
|
||||||
SELECT
|
|
||||||
sheeps.*,
|
|
||||||
possibilities.can_view_territory AS can_view_territory
|
|
||||||
FROM
|
|
||||||
sheeps
|
|
||||||
LEFT JOIN
|
|
||||||
possibilities ON possibilities.sheep_id = sheeps.id
|
|
||||||
WHERE
|
|
||||||
sheeps.uuid_manager = ?`,
|
|
||||||
[uuid],
|
|
||||||
(err, moderator) => {
|
|
||||||
if (moderator) {
|
|
||||||
let data = {
|
|
||||||
id: moderator.sheep_id,
|
|
||||||
group_id: moderator.group_id,
|
|
||||||
name: moderator.name,
|
|
||||||
icon: moderator.icon,
|
|
||||||
uuid: moderator.uuid,
|
|
||||||
appointment: moderator.appointment,
|
|
||||||
sheepRole: moderator.mode_title,
|
|
||||||
possibilities: {
|
|
||||||
can_view_territory: moderator.can_view_territory == 1 ? true : false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
db.get(`
|
|
||||||
SELECT
|
|
||||||
sheeps.*,
|
|
||||||
possibilities.can_view_territory AS can_view_territory
|
|
||||||
FROM
|
|
||||||
sheeps
|
|
||||||
LEFT JOIN
|
|
||||||
possibilities ON possibilities.sheep_id = sheeps.id
|
|
||||||
WHERE
|
|
||||||
sheeps.uuid = ?`,
|
|
||||||
[uuid],
|
|
||||||
(err, sheep) => {
|
|
||||||
if (sheep) {
|
|
||||||
let data = {
|
|
||||||
id: sheep.sheep_id,
|
|
||||||
group_id: sheep.group_id,
|
|
||||||
name: sheep.name,
|
|
||||||
icon: sheep.icon,
|
|
||||||
uuid: sheep.uuid,
|
|
||||||
appointment: sheep.appointment,
|
|
||||||
sheepRole: sheep.mode_title,
|
|
||||||
possibilities: {
|
|
||||||
can_view_territory: sheep.can_view_territory == 1 ? true : false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res(false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
13
ws_old/Dockerfile
Normal file
13
ws_old/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FROM node:20.18
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 4001
|
||||||
|
|
||||||
|
CMD npm start
|
||||||
1644
ws_old/package-lock.json
generated
Normal file
1644
ws_old/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
ws_old/package.json
Normal file
18
ws_old/package.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "WS Sheep Service",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"main": "ws.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node ws.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"sqlite3": "^5.1.7",
|
||||||
|
"url": "^0.11.4",
|
||||||
|
"ws": "^8.18.0",
|
||||||
|
"dotenv": "^17.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
260
ws_old/ws.js
Normal file
260
ws_old/ws.js
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
const WebSocket = require("ws");
|
||||||
|
const { URL } = require('url');
|
||||||
|
const sqlite3 = require('sqlite3');
|
||||||
|
const path = require('path');
|
||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
const dbPath = process.env.DATABASE_PATH || '../';
|
||||||
|
const db = new sqlite3.Database(path.join(dbPath, 'database.sqlite'));
|
||||||
|
|
||||||
|
const port = 4004;
|
||||||
|
const api_version = '1.0.0';
|
||||||
|
|
||||||
|
const wss = new WebSocket.Server({
|
||||||
|
port: port
|
||||||
|
}, () => console.log(`Server started on port ${port}`));
|
||||||
|
|
||||||
|
|
||||||
|
wss.on('connection', async (ws, request) => {
|
||||||
|
const url = new URL(request.url, `http://${request.headers.host}`)
|
||||||
|
const params = Object.fromEntries(url.searchParams.entries());
|
||||||
|
const uuid = params.uuid;
|
||||||
|
|
||||||
|
if (!uuid) return
|
||||||
|
|
||||||
|
let check = await checkUUID(uuid);
|
||||||
|
|
||||||
|
console.log(check);
|
||||||
|
|
||||||
|
|
||||||
|
if (!check && check.possibilities.can_view_territory) return
|
||||||
|
|
||||||
|
// Periodic ping to maintain a connection
|
||||||
|
const pingInterval = setInterval(() => {
|
||||||
|
if (ws.readyState === WebSocket.OPEN) {
|
||||||
|
ws.ping('ping');
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
|
|
||||||
|
ws.send(JSON.stringify({ "connection": "success", "api_version": api_version }));
|
||||||
|
|
||||||
|
ws.on('message', (message) => {
|
||||||
|
message = JSON.parse(message);
|
||||||
|
|
||||||
|
console.log(message.username, check.name);
|
||||||
|
|
||||||
|
switch (message.event) {
|
||||||
|
case "connection":
|
||||||
|
broadcastMessage(message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "message":
|
||||||
|
updateDatabase(message);
|
||||||
|
broadcastMessage(message);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('pong', (data) => {
|
||||||
|
console.log('PONG received from the client:', data.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('close', () => {
|
||||||
|
console.log('Client close');
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('error', (err) => {
|
||||||
|
console.error('ERROR WebSocket:', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function broadcastMessage(message) {
|
||||||
|
wss.clients.forEach(client => {
|
||||||
|
if (client.readyState === WebSocket.OPEN) {
|
||||||
|
client.send(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDatabase(message) {
|
||||||
|
|
||||||
|
console.log(message.type);
|
||||||
|
|
||||||
|
|
||||||
|
if (message.type === "apartment") {
|
||||||
|
|
||||||
|
let sql = 'UPDATE apartments SET status = ?, description = ?, sheep_id = ?, updated_at = ? WHERE id = ?';
|
||||||
|
|
||||||
|
db.run(sql, [
|
||||||
|
Number(message.data.status),
|
||||||
|
message.data.description,
|
||||||
|
message.data.sheep_id,
|
||||||
|
message.data.updated_at,
|
||||||
|
message.data.id
|
||||||
|
], function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
} else if (this.changes === 0) {
|
||||||
|
console.error('Product not found');
|
||||||
|
} else {
|
||||||
|
console.log({ "update": "ok", "id": message.data.id });
|
||||||
|
|
||||||
|
let sql = `INSERT INTO apartments_history (apartments_id, status, description, sheep_id, created_at) VALUES (?, ?, ?, ?, ?)`;
|
||||||
|
|
||||||
|
db.run(sql, [
|
||||||
|
Number(message.data.id),
|
||||||
|
Number(message.data.status),
|
||||||
|
message.data.description,
|
||||||
|
message.data.sheep_id,
|
||||||
|
Math.floor(Date.now())
|
||||||
|
], function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
} else if (this.changes === 0) {
|
||||||
|
console.error('Apartments not found');
|
||||||
|
} else {
|
||||||
|
console.log({ "insert": "ok", "id": this.lastID });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if(message.type === "building") {
|
||||||
|
let sql = 'UPDATE buildings SET status = ?, description = ?, sheep_id = ?, updated_at = ? WHERE id = ?';
|
||||||
|
|
||||||
|
db.run(sql, [
|
||||||
|
Number(message.data.status),
|
||||||
|
message.data.description,
|
||||||
|
message.data.sheep_id,
|
||||||
|
message.data.updated_at,
|
||||||
|
message.data.id
|
||||||
|
], function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
} else if (this.changes === 0) {
|
||||||
|
console.error('Product not found');
|
||||||
|
} else {
|
||||||
|
console.log({ "update": "ok", "id": message.data.id });
|
||||||
|
|
||||||
|
let sql = `INSERT INTO buildings_history (buildings_id, status, description, sheep_id, created_at) VALUES (?, ?, ?, ?, ?)`;
|
||||||
|
|
||||||
|
db.run(sql, [
|
||||||
|
Number(message.data.id),
|
||||||
|
Number(message.data.status),
|
||||||
|
message.data.description,
|
||||||
|
message.data.sheep_id,
|
||||||
|
Math.floor(Date.now())
|
||||||
|
], function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
} else if (this.changes === 0) {
|
||||||
|
console.error('Apartments not found');
|
||||||
|
} else {
|
||||||
|
console.log({ "insert": "ok", "id": this.lastID });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if(message.type === "stand") {
|
||||||
|
let sql = 'UPDATE stand SET status = ?, sheep_id = ?, updated_at = ? WHERE id = ?';
|
||||||
|
|
||||||
|
db.run(sql, [
|
||||||
|
Number(message.data.status),
|
||||||
|
message.data.sheep_id,
|
||||||
|
message.data.updated_at,
|
||||||
|
message.data.id
|
||||||
|
], function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
} else if (this.changes === 0) {
|
||||||
|
console.error('Product not found');
|
||||||
|
} else {
|
||||||
|
console.log({ "update": "ok", "id": message.data.id });
|
||||||
|
|
||||||
|
let sql = `INSERT INTO stand_history (stand_id, status, sheep_id, created_at) VALUES (?, ?, ?, ?, ?)`;
|
||||||
|
|
||||||
|
db.run(sql, [
|
||||||
|
Number(message.data.id),
|
||||||
|
Number(message.data.status),
|
||||||
|
message.data.sheep_id,
|
||||||
|
Math.floor(Date.now())
|
||||||
|
], function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
} else if (this.changes === 0) {
|
||||||
|
console.error('Stand not found');
|
||||||
|
} else {
|
||||||
|
console.log({ "insert": "ok", "id": this.lastID });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkUUID(uuid) {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
db.get(`
|
||||||
|
SELECT
|
||||||
|
sheeps.*,
|
||||||
|
possibilities.can_view_territory AS can_view_territory
|
||||||
|
FROM
|
||||||
|
sheeps
|
||||||
|
LEFT JOIN
|
||||||
|
possibilities ON possibilities.sheep_id = sheeps.id
|
||||||
|
WHERE
|
||||||
|
sheeps.uuid_manager = ?`,
|
||||||
|
[uuid],
|
||||||
|
(err, moderator) => {
|
||||||
|
if (moderator) {
|
||||||
|
let data = {
|
||||||
|
id: moderator.sheep_id,
|
||||||
|
group_id: moderator.group_id,
|
||||||
|
name: moderator.name,
|
||||||
|
icon: moderator.icon,
|
||||||
|
uuid: moderator.uuid,
|
||||||
|
appointment: moderator.appointment,
|
||||||
|
sheepRole: moderator.mode_title,
|
||||||
|
possibilities: {
|
||||||
|
can_view_territory: moderator.can_view_territory == 1 ? true : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
db.get(`
|
||||||
|
SELECT
|
||||||
|
sheeps.*,
|
||||||
|
possibilities.can_view_territory AS can_view_territory
|
||||||
|
FROM
|
||||||
|
sheeps
|
||||||
|
LEFT JOIN
|
||||||
|
possibilities ON possibilities.sheep_id = sheeps.id
|
||||||
|
WHERE
|
||||||
|
sheeps.uuid = ?`,
|
||||||
|
[uuid],
|
||||||
|
(err, sheep) => {
|
||||||
|
if (sheep) {
|
||||||
|
let data = {
|
||||||
|
id: sheep.sheep_id,
|
||||||
|
group_id: sheep.group_id,
|
||||||
|
name: sheep.name,
|
||||||
|
icon: sheep.icon,
|
||||||
|
uuid: sheep.uuid,
|
||||||
|
appointment: sheep.appointment,
|
||||||
|
sheepRole: sheep.mode_title,
|
||||||
|
possibilities: {
|
||||||
|
can_view_territory: sheep.can_view_territory == 1 ? true : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user