Files
Sheep-Service/web/lib/pages/card/script_old.js
2025-09-09 00:10:53 +03:00

452 lines
22 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
}
}
}