"use strict"; import { COMMANDS } from './costants.js' let FEATURES = {} let LOGS = {} class Admin { constructor () { return (async () => { const element = document.createElement('div'); element.classList.add('admin'); const header = document.createElement('h2'); header.innerHTML = "Настройки TemaBot" element.append(header); const divider0 = new Divider("Фичи:") element.append(divider0.element) FEATURES = await Admin.getFeatures() console.log("!!! FEATURES", FEATURES) const features = new Features(FEATURES) element.append(features.element) const applyButton = new Button(COMMANDS[2].name, COMMANDS[2].uid, handleApplyButton) element.append(applyButton.element) const divider1 = new Divider("Контент:") element.append(divider1.element) const downloadButton = new Button("Скачать контент", "download", handleDownloadButton) element.append(downloadButton.element) const upload = new Upload("Загрузить контент", "upload", handleSubmit) element.append(upload.element) const divider2 = new Divider("Логи:") element.append(divider2.element) LOGS = await Admin.getLogs() console.log("!!! LOGS", LOGS) const showLogsButton = new Button("Посмотреть логи", "showLogs", handleShowLogsButton) element.append(showLogsButton.element) const clearLogsButton = new Button("Очистить логи", "clearLogs", handleClearLogsButton) element.append(clearLogsButton.element) const modal = new Modal(JSON.stringify(LOGS, null, '\\n'), handleModalClose) element.append(modal.element) const divider3 = new Divider("Рассылка:") element.append(divider3.element) const mailing = await Admin.getMailing() console.log("!!! MAILING", mailing) const mailingSwitch = new Switch(mailing.status, "Рассылка", "mailingSwitch", handleMailingSwitch) element.append(mailingSwitch.element) const divider4 = new Divider("Подписки:") element.append(divider4.element) const subscription = await Admin.getSubscriptionMailing() console.log("!!! MAILING", subscription) const subscriptionSwitch = new Switch(subscription.status, "Подписки", "subscriptionSwitch", handleSubscriptionSwitch) const subscriptionTimeInput = new TimeInput(subscription.time ,"Время рассылки", "subscriptionTimeInput", handleSubscriptionTime) const group = new Group('row', subscriptionTimeInput.element, subscriptionSwitch.element) element.append(group.element) this.element = element return this })(); } static async getFeatures() { const response = await fetch('/settings/', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify({}) }) if (response.ok) { return await response.json(); } else { alert("Не получили настройки :( Ошибка HTTP: " + response.status); return {} } } static async getMailing() { const response = await fetch('/settings/mailing', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify({}) }) if (response.ok) { return await response.json(); } else { alert("Не смогли получить рассылки :( Ошибка HTTP: " + response.status); return {} } } static async getSubscriptionMailing() { const response = await fetch('/settings/mailing/subscription', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify({}) }) if (response.ok) { return await response.json(); } else { alert("Не смогли получить рассылки :( Ошибка HTTP: " + response.status); return {} } } static async getLogs() { const response = await fetch('/settings/logs', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify({}) }) if (response.ok) { return await response.json(); } else { alert("Не смогли получить логи :( Ошибка HTTP: " + response.status); return {} } } static async clearLogs() { const response = await fetch('/settings/logs/clear', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify({}) }) if (response.ok) { return await response.json(); } else { alert("Не смогли очистить логи :( Ошибка HTTP: " + response.status); return {} } } setStatusName(name) { this.status.setName(name) } } class Features { constructor (features) { const element = document.createElement('div'); Object.entries(features).forEach(([key, value]) => { const { name, available, readonly } = value const checkbox = new Checkbox(name, key, available, readonly); element.append(checkbox.element); }) this.element = element; } } class Divider { constructor (title) { const element = document.createElement('div') element.classList.add('divider'); const hr = document.createElement('hr') hr.classList.add('divider_hr'); element.append(hr); if (title) { const h3 = document.createElement('h3'); h3.classList.add('divider_h3'); h3.innerHTML = title element.append(h3); } this.element = element; } } class Modal { constructor (text, onClose) { const element = document.createElement('div'); element.classList.add('modal'); const content = document.createElement('div'); content.classList.add('modal-content'); element.append(content); const close = document.createElement('button'); close.classList.add('modal-close'); close.append("X"); close.addEventListener( 'click', () => { onClose(); } ) content.append(close); const new_text = text.replaceAll("\\n", "") const p = document.createElement('pre'); p.classList.add('modal-text'); p.append(new_text); content.append(p); window.onclick = function(event) { if (event.target == element) { element.style.display = "none"; } } this.element = element; } } class Button { constructor (name, uid, onClick) { const element = document.createElement('button'); element.append(name); element.classList.add('button'); element.setAttribute('data-name', name) element.setAttribute('data-uid', uid) element.addEventListener( 'click', () => { onClick(this.element); } ) this.element = element; } } class Group { constructor (direction, ...elements) { const div = document.createElement('div'); div.classList.add('group'); if (direction === 'column') { div.classList.add('direction_column'); } else if (direction === 'row') { div.classList.add('direction_row'); } for (const element of elements) { div.append(element) } this.element = div; } } class Switch { constructor (status, name, uid, onClick) { const element = document.createElement('label'); element.classList.add('switch'); const input = document.createElement('input'); if (status === 'checked') { input.setAttribute('checked', "true"); } input.setAttribute('type', "checkbox"); input.setAttribute('data-name', name) input.setAttribute('data-uid', uid) input.addEventListener( 'click', () => { onClick(input); } ) const span = document.createElement('span'); span.classList.add('slider'); span.classList.add('round'); element.append(input); element.append(span); this.element = element; } } class TimeInput { constructor (time, name, uid, onBlur ) { const element = document.createElement('input'); element.setAttribute('id', uid); element.setAttribute('type', "time"); element.setAttribute('min', "00.00"); element.setAttribute('max', "23.59"); element.setAttribute('value', time) element.classList.add('timeInput'); element.setAttribute('data-name', name) element.setAttribute('data-uid', uid) element.addEventListener( 'blur', () => { onBlur(element); } ) this.element = element; } } class Upload { constructor (name, uid, onSubmit) { const form = document.createElement('form'); form.setAttribute('action', "/upload/"); form.setAttribute('method', "post"); form.setAttribute('enctype', "multipart/form-data"); form.addEventListener('submit', onSubmit); const label = document.createElement('label'); label.setAttribute('for', "file"); label.append("Файл: "); form.append(label); const input = document.createElement('input'); input.setAttribute('id', "file"); input.setAttribute('name', "file"); input.setAttribute('type', "file"); form.append(input); const button = document.createElement('button'); button.classList.add('button'); button.setAttribute('data-name', name); button.setAttribute('data-uid', uid); button.append(name); this.button = button form.append(button); this.element = form; } } class Checkbox { constructor (name, uid, available, readonly) { const element = document.createElement('div'); const label = document.createElement('label'); const checkbox = document.createElement('input'); checkbox.setAttribute('type', 'checkbox'); checkbox.setAttribute('data-name', name); checkbox.setAttribute('data-uid', uid); checkbox.setAttribute('data-available', available); if (available === 'true') { checkbox.setAttribute('checked',''); } if (readonly === 'true') { checkbox.setAttribute('disabled',''); } checkbox.addEventListener( 'change', () => { changeCheckbox(checkbox); } ) label.append(checkbox) label.append(name) element.append(label) this.element = element; } } const admin = await new Admin(); document .getElementById('root') .append(admin.element) function changeCheckbox(checkbox) { console.log(checkbox.dataset.name, checkbox.checked, checkbox.dataset.uid) const feature = FEATURES[checkbox.dataset.uid] feature.available = checkbox.checked ? "true" : "false" } function specialHandle (data, fetchComponent) { fetch(fetchComponent, { method: "POST", headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify(data) }) .then(response => response.json()) .then(result => { console.log("result", result) }) .catch((error) => console.log(error)); } function handleApplyButton (button) { console.log("click", button.dataset.name, button.dataset.uid); const data = { command: button.dataset.uid, features: FEATURES} const fetchComponent = `/tasks/` specialHandle(data, fetchComponent) } function handleMailingSwitch (input) { console.log("click", input.dataset.name, input.dataset.uid, input.checked) const data = { status: input.checked} const fetchComponent = `/settings/mailing/mailing_set` specialHandle(data, fetchComponent) } function handleSubscriptionSwitch (input) { console.log("click", input.dataset.name, input.dataset.uid, input.checked) const data = { status: input.checked} const fetchComponent = `/settings/mailing/subscription/set` specialHandle(data, fetchComponent) } function handleSubscriptionTime (input) { console.log("click", input.dataset.name, input.dataset.uid, input.checked) const data = { time: input.value } const fetchComponent = `/settings/mailing/subscription/set` specialHandle(data, fetchComponent) } function handleDownloadButton (button) { console.log("click", button.dataset.name, button.dataset.uid); window.location='./download'; } function handleShowLogsButton (button) { console.log("click", button.dataset.name, button.dataset.uid); const modal = document.getElementsByClassName("modal")[0]; modal.style.display = "block"; } function handleClearLogsButton (button) { console.log("click", button.dataset.name, button.dataset.uid); Admin.clearLogs() } function handleModalClose () { console.log("click", "handleModalClose"); const modal = document.getElementsByClassName("modal")[0]; modal.style.display = "none"; } /** @param {Event} event */ function handleSubmit(event) { /** @type {HTMLFormElement} */ const form = event.currentTarget; const url = new URL(form.action); const formData = new FormData(form); const searchParams = new URLSearchParams(formData); /** @type {Parameters[1]} */ const fetchOptions = { method: form.method, }; if (form.method.toLowerCase() === 'post') { if (form.enctype === 'multipart/form-data') { fetchOptions.body = formData; } else { fetchOptions.body = searchParams; } } else { url.search = searchParams; } fetch(url, fetchOptions) .then(response => response.json()) .then(result => { alert(result.ok) console.log("result", result) }) .catch((error) => console.log(error)); event.preventDefault(); } function ready(callback) { if (document.readyState !== 'loading') { callback(); return; } document.addEventListener('DOMContentLoaded', callback); } ready(function() { console.log('document ready') })