first commit

This commit is contained in:
Ivan 2023-07-04 01:31:18 +03:00
commit c38cb8c2a5
Signed by untrusted user who does not match committer: ppechenkoo
GPG Key ID: 0C191B86D9582583
55 changed files with 18273 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
/node_modules
static/scripts/.DS_Store
static/styles/.DS_Store
static/templates/.DS_Store
static/img/.DS_Store
static/.DS_Store
.DS_Store

14
Dockerfile Normal file
View File

@ -0,0 +1,14 @@
FROM node:18
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
EXPOSE 8081
CMD [ "node", "server.js" ]

1
README.md Normal file
View File

@ -0,0 +1 @@
# Argus site

4
captain-definition Normal file
View File

@ -0,0 +1,4 @@
{
"schemaVersion": 2,
"dockerfilePath": "./Dockerfile"
}

1552
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

16
package.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "argus",
"version": "1.0.0",
"description": "Cameras",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"path": "^0.12.7"
}
}

61
server.js Normal file
View File

@ -0,0 +1,61 @@
const express = require("express");
const app = express();
const path = require("path");
app.use(express.static(path.join(__dirname, "static")));
app.get("/", index);
app.get("/login", login);
app.get("/register", register);
app.get("/live", live);
app.get("/reports", reports);
app.get("/reports/346", reports346);
app.get("/devices", devices);
app.get("/devices/drivers", drivers);
app.get("/devices/newdevice", newdevice);
app.get("/devices/newdriver", newdriver);
function index(req, res) {
res.sendFile(path.join(__dirname, "static/templates/index.html"));
}
function login(req, res) {
res.sendFile(path.join(__dirname, "static/templates/login.html"));
}
function register(req, res) {
res.sendFile(path.join(__dirname, "static/templates/register.html"));
}
function live(req, res) {
res.sendFile(path.join(__dirname, "static/templates/live.html"));
}
function reports(req, res) {
res.sendFile(path.join(__dirname, "static/templates/reports/index.html"));
}
function reports346(req, res) {
res.sendFile(path.join(__dirname, "static/templates/reports/346.html"));
}
function devices(req, res) {
res.sendFile(path.join(__dirname, "static/templates/devices/index.html"));
}
function drivers(req, res) {
res.sendFile(path.join(__dirname, "static/templates/devices/drivers.html"));
}
function newdevice(req, res) {
res.sendFile(path.join(__dirname, "static/templates/devices/newdevice.html"));
}
function newdriver(req, res) {
res.sendFile(path.join(__dirname, "static/templates/devices/newdriver.html"));
}
// function unauthorized(req, res) {
// const td = {};
// res.sendFile(path.join(__dirname, "static/templates/unauthorized.html"));
// }
const port = 8081;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
// app.use((req, res, next) => {
// res.sendFile(path.join(__dirname, "static/templates/404.html"));
// });

Binary file not shown.

11
static/img/bubble.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="21.5234" height="21.5723">
<g>
<rect height="21.5723" opacity="0" width="21.5234" x="0" y="0"/>
<path d="M5.80078 21.5723C6.18164 21.5723 6.46484 21.377 6.92383 20.9473L10.4492 17.7246L17.0508 17.7246C19.9609 17.7246 21.5234 16.123 21.5234 13.2617L21.5234 5.78125C21.5234 2.91992 19.9609 1.30859 17.0508 1.30859L4.47266 1.30859C1.5625 1.30859 0 2.91016 0 5.78125L0 13.2617C0 16.1328 1.5625 17.7246 4.47266 17.7246L4.93164 17.7246L4.93164 20.5664C4.93164 21.1719 5.24414 21.5723 5.80078 21.5723ZM10.7715 11.3281C10.2637 11.3281 9.98047 11.0449 9.9707 10.5273L9.84375 5.21484C9.83398 4.69727 10.2148 4.31641 10.7617 4.31641C11.2988 4.31641 11.6992 4.70703 11.6895 5.22461L11.543 10.5273C11.5332 11.0547 11.25 11.3281 10.7715 11.3281ZM10.7715 14.5996C10.1855 14.5996 9.67773 14.1406 9.67773 13.5547C9.67773 12.9785 10.1758 12.5098 10.7715 12.5098C11.3574 12.5098 11.8555 12.9688 11.8555 13.5547C11.8555 14.1504 11.3477 14.5996 10.7715 14.5996Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

11
static/img/cars.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="31.1914" height="18.1543">
<g>
<rect height="18.1543" opacity="0" width="31.1914" x="0" y="0"/>
<path d="M9.23828 15.4004L9.23828 14.1211C6.46484 14.0723 3.62305 13.9355 2.40234 13.7988C1.57227 13.7109 1.2793 13.2715 1.2793 12.5293L1.2793 11.2012C1.2793 9.86328 1.49414 9.23828 2.25586 8.24219L3.25195 6.93359C3.51562 5.51758 4.15039 3.54492 4.57031 2.64648C4.88281 1.97266 5.49805 1.55273 6.38672 1.44531C7.01172 1.36719 8.99414 1.2793 11.5527 1.2793C12.9688 1.2793 14.1895 1.30859 15.1367 1.34766L15.6641 0.0585938C14.6582 0.0195312 13.1934 0 11.5527 0C9.0332 0 6.89453 0.0585938 6.24023 0.136719C4.94141 0.292969 3.92578 0.966797 3.4082 2.07031C3.06641 2.79297 2.42188 4.63867 2.06055 6.39648L1.24023 7.46094C0.332031 8.63281 0 9.55078 0 11.2012L0 12.7246C0 14.1113 0.722656 14.8926 2.06055 15.0488C3.50586 15.2344 6.44531 15.3516 9.23828 15.4004ZM10.9961 6.40625L12.0117 2.35352C11.8652 2.35352 11.709 2.35352 11.5527 2.35352C8.93555 2.35352 7.33398 2.42188 6.62109 2.51953C6.11328 2.58789 5.83008 2.7832 5.57617 3.22266C5.26367 3.75977 4.81445 5.10742 4.58008 6.14258C4.50195 6.48438 4.64844 6.62109 5.01953 6.60156C6.48438 6.49414 8.21289 6.41602 10.9961 6.40625ZM1.79688 18.1152L2.93945 18.1152C3.67188 18.1152 4.23828 17.5488 4.23828 16.8262L4.23828 14.5312L0.498047 13.9746L0.498047 16.8262C0.498047 17.5488 1.06445 18.1152 1.79688 18.1152ZM4.51172 12.793C5.40039 12.793 6.08398 12.1094 6.08398 11.2207C6.08398 10.3223 5.40039 9.64844 4.51172 9.64844C3.62305 9.64844 2.93945 10.3223 2.93945 11.2207C2.93945 12.1094 3.62305 12.793 4.51172 12.793ZM19.6387 15.4297C22.9199 15.4297 27.2754 15.2637 29.1309 15.0488C30.4492 14.9023 31.1914 14.1699 31.1914 12.9199L31.1914 11.2012C31.1914 9.55078 30.8594 8.63281 29.9512 7.46094L29.1309 6.39648C28.7695 4.63867 28.125 2.79297 27.7832 2.07031C27.2656 0.966797 26.25 0.3125 24.9512 0.136719C24.2969 0.0488281 22.1582 0 19.6387 0C17.1094 0 14.9707 0.0585938 14.3164 0.136719C13.0176 0.292969 12.002 0.966797 11.4844 2.07031C11.1523 2.79297 10.498 4.63867 10.1465 6.39648L9.31641 7.46094C8.4082 8.63281 8.07617 9.55078 8.07617 11.2012L8.07617 12.9199C8.07617 14.1699 8.81836 14.9023 10.1465 15.0488C11.9922 15.2637 16.3477 15.4297 19.6387 15.4297ZM19.6387 14.1504C16.3184 14.1504 12.0508 13.9941 10.4883 13.7988C9.6582 13.7012 9.35547 13.2715 9.35547 12.5293L9.35547 11.2012C9.35547 9.86328 9.58008 9.23828 10.332 8.24219L11.3379 6.93359C11.5918 5.51758 12.2363 3.54492 12.6465 2.64648C12.9688 1.97266 13.584 1.55273 14.4727 1.44531C15.0977 1.36719 17.0703 1.2793 19.6387 1.2793C22.1973 1.2793 24.2188 1.36719 24.7852 1.44531C25.7031 1.5625 26.3086 1.98242 26.6211 2.64648C27.0508 3.54492 27.6758 5.51758 27.9395 6.93359L28.9355 8.24219C29.6973 9.23828 29.9121 9.86328 29.9121 11.2012L29.9121 12.5293C29.9121 13.2715 29.6191 13.7012 28.7793 13.7988C27.2168 13.9941 22.959 14.1504 19.6387 14.1504ZM12.666 6.14258C12.5879 6.48438 12.7344 6.62109 13.0957 6.60156C14.6582 6.49414 16.5137 6.40625 19.6387 6.40625C22.7539 6.40625 24.6094 6.49414 26.1719 6.60156C26.543 6.62109 26.6797 6.48438 26.6016 6.14258C26.3672 5.10742 25.9277 3.75977 25.6152 3.22266C25.3613 2.7832 25.0781 2.58789 24.5703 2.51953C23.8574 2.42188 22.2559 2.35352 19.6387 2.35352C17.0117 2.35352 15.4102 2.42188 14.707 2.51953C14.1992 2.58789 13.9062 2.7832 13.6523 3.22266C13.3496 3.75977 12.9004 5.10742 12.666 6.14258ZM9.87305 18.1152L11.0254 18.1152C11.7578 18.1152 12.3145 17.5488 12.3145 16.8262L12.3145 14.502L8.58398 13.9648L8.58398 16.8262C8.58398 17.5488 9.14062 18.1152 9.87305 18.1152ZM28.252 18.1152L29.3945 18.1152C30.127 18.1152 30.6934 17.5488 30.6934 16.8262L30.6934 13.9648L26.9531 14.502L26.9531 16.8262C26.9531 17.5488 27.5195 18.1152 28.252 18.1152ZM12.5977 12.793C13.4863 12.793 14.1602 12.1094 14.1602 11.2207C14.1602 10.3223 13.4863 9.64844 12.5977 9.64844C11.6992 9.64844 11.0254 10.3223 11.0254 11.2207C11.0254 12.1094 11.6992 12.793 12.5977 12.793ZM17.0508 12.4023L22.2168 12.4023C22.8906 12.4023 23.3496 11.9434 23.3496 11.2695C23.3496 10.6055 22.8906 10.1465 22.2168 10.1465L17.0508 10.1465C16.3867 10.1465 15.918 10.6055 15.918 11.2695C15.918 11.9434 16.3867 12.4023 17.0508 12.4023ZM26.6797 12.793C27.5684 12.793 28.252 12.1094 28.252 11.2207C28.252 10.3223 27.5684 9.64844 26.6797 9.64844C25.7812 9.64844 25.1074 10.3223 25.1074 11.2207C25.1074 12.1094 25.7812 12.793 26.6797 12.793Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

11
static/img/chart.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24.541" height="18.4082">
<g>
<rect height="18.4082" opacity="0" width="24.541" x="0" y="0"/>
<path d="M2.03125 18.2617L4.93164 18.2617C6.2793 18.2617 6.97266 17.6172 6.97266 16.3379L6.97266 7.62695C6.97266 6.34766 6.2793 5.69336 4.93164 5.69336L2.03125 5.69336C0.693359 5.69336 0 6.34766 0 7.62695L0 16.3379C0 17.6172 0.693359 18.2617 2.03125 18.2617ZM10.8105 18.2617L13.7207 18.2617C15.0684 18.2617 15.752 17.6172 15.752 16.3379L15.752 4.78516C15.752 3.50586 15.0684 2.85156 13.7207 2.85156L10.8105 2.85156C9.47266 2.85156 8.7793 3.50586 8.7793 4.78516L8.7793 16.3379C8.7793 17.6172 9.47266 18.2617 10.8105 18.2617ZM19.5898 18.2617L22.5 18.2617C23.8477 18.2617 24.541 17.6172 24.541 16.3379L24.541 1.93359C24.541 0.654297 23.8477 0 22.5 0L19.5898 0C18.2617 0 17.5684 0.654297 17.5684 1.93359L17.5684 16.3379C17.5684 17.6172 18.2617 18.2617 19.5898 18.2617Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" viewBox="0 0 18 18">
<rect width="18" height="18" fill="#8086F9" fill-opacity=".85" rx="5"/>
<rect width="16" height="16" x="1" y="1" stroke="#000" stroke-opacity=".1" stroke-width="2" rx="4"/>
<path fill="#fff" fill-opacity=".85" d="M7.93 13.633c.322 0 .595-.156.79-.46l4.464-7.02c.117-.196.234-.41.234-.626 0-.44-.39-.722-.791-.722-.254 0-.498.156-.684.44l-4.052 6.503-1.924-2.49c-.235-.313-.45-.39-.713-.39a.759.759 0 0 0-.762.77c0 .216.088.42.225.606l2.383 2.93c.244.322.507.459.83.459Z"/>
<path fill="#fff" fill-opacity=".85" d="M7.93 13.633c.322 0 .595-.156.79-.46l4.464-7.02c.117-.196.234-.41.234-.626 0-.44-.39-.722-.791-.722-.254 0-.498.156-.684.44l-4.052 6.503-1.924-2.49c-.235-.313-.45-.39-.713-.39a.759.759 0 0 0-.762.77c0 .216.088.42.225.606l2.383 2.93c.244.322.507.459.83.459Z"/>
</svg>

After

Width:  |  Height:  |  Size: 884 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
<rect width="22" height="22" fill="#8086F9" fill-opacity=".85" rx="5"/>
<rect width="20" height="20" x="1" y="1" stroke="#000" stroke-opacity=".1" stroke-width="2" rx="4"/>
<path fill="#fff" fill-opacity=".85" d="M9.692 16.662c.393 0 .728-.19.966-.56l5.455-8.582c.143-.24.287-.502.287-.764 0-.537-.478-.884-.967-.884-.31 0-.609.191-.836.537l-4.953 7.95-2.351-3.044c-.287-.382-.55-.477-.872-.477a.927.927 0 0 0-.93.943c0 .262.107.513.274.74l2.912 3.58c.298.394.62.561 1.015.561Z"/>
<path fill="#fff" fill-opacity=".85" d="M9.692 16.662c.393 0 .728-.19.966-.56l5.455-8.582c.143-.24.287-.502.287-.764 0-.537-.478-.884-.967-.884-.31 0-.609.191-.836.537l-4.953 7.95-2.351-3.044c-.287-.382-.55-.477-.872-.477a.927.927 0 0 0-.93.943c0 .262.107.513.274.74l2.912 3.58c.298.394.62.561 1.015.561Z"/>
</svg>

After

Width:  |  Height:  |  Size: 900 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
<rect width="22" height="22" fill="#fff" rx="5"/>
<rect width="20" height="20" x="1" y="1" stroke="#000" stroke-opacity=".1" stroke-width="2" rx="4"/>
</svg>

After

Width:  |  Height:  |  Size: 258 B

4
static/img/checkbox.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" viewBox="0 0 18 18">
<rect width="18" height="18" fill="#fff" rx="5"/>
<rect width="16" height="16" x="1" y="1" stroke="#000" stroke-opacity=".1" stroke-width="2" rx="4"/>
</svg>

After

Width:  |  Height:  |  Size: 258 B

10
static/img/clockwise.svg Normal file
View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="22" fill="none" viewBox="0 0 17 22">
<g clip-path="url(#a)">
<path fill="#000" fill-opacity=".75" d="M0 11.657a8.108 8.108 0 0 0 8.127 8.137 8.1 8.1 0 0 0 8.118-8.137c0-.44-.313-.763-.763-.763-.432 0-.717.322-.717.763a6.621 6.621 0 0 1-6.638 6.656 6.629 6.629 0 0 1-6.647-6.656A6.62 6.62 0 0 1 8.127 5.02c.699 0 1.352.055 1.894.184l-2.749 2.72a.76.76 0 0 0-.211.525c0 .423.312.735.726.735.23 0 .404-.073.533-.211l3.788-3.806a.717.717 0 0 0 .23-.552.787.787 0 0 0-.23-.551L8.32.22A.68.68 0 0 0 7.787 0c-.414 0-.726.331-.726.754 0 .193.073.377.202.524l2.445 2.418a8.457 8.457 0 0 0-1.58-.157A8.098 8.098 0 0 0 0 11.658Z"/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h16.245v22H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 805 B

11
static/img/cloud.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28.1445" height="18.623">
<g>
<rect height="18.623" opacity="0" width="28.1445" x="0" y="0"/>
<path d="M13.9551 17.4902L24.2773 17.4902C26.5625 17.4902 28.1445 15.918 28.1445 13.6523C28.1445 11.3867 26.5625 9.80469 24.2773 9.80469L11.1621 9.80469C11.9238 10.5762 12.4316 11.6113 12.5879 12.7832C13.6328 13.5254 14.2578 14.6387 14.2578 16.0254C14.2578 16.5527 14.1504 17.041 13.9551 17.4902ZM24.2773 8.4668C25.1953 8.4668 26.0352 8.67188 26.7676 9.04297L24.4238 3.4082C23.8184 1.93359 22.5391 1.14258 20.8594 1.14258L12.9688 1.14258C11.2891 1.14258 10.0098 1.93359 9.4043 3.4082L7.34375 8.33984C7.91992 8.28125 8.49609 8.34961 9.0332 8.50586C9.3457 8.4668 9.66797 8.4668 9.92188 8.4668ZM22.8711 13.6523C22.8711 12.9785 23.4473 12.4023 24.1406 12.4023C24.8047 12.4023 25.3906 12.9785 25.3906 13.6523C25.3906 14.3457 24.8047 14.9023 24.1406 14.9023C23.4473 14.9121 22.8711 14.3555 22.8711 13.6523ZM3.07617 18.623L10.166 18.623C11.7285 18.623 12.9297 17.4707 12.9297 16.0547C12.9297 14.9805 12.3047 14.0332 11.3086 13.623C11.3184 11.3184 9.66797 9.6582 7.55859 9.6582C6.17188 9.6582 5.17578 10.4102 4.55078 11.3086C3.28125 10.9277 1.89453 11.9141 1.875 13.3594C0.712891 13.5352 0 14.5703 0 15.8301C0 17.3438 1.31836 18.623 3.07617 18.623Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Pixelmator Pro 2.4.3 -->
<svg width="12" height="8" viewBox="0 0 12 8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Group">
<path id="Path" fill="#000000" stroke="none" opacity="0" d="M -0 0.151983 L 12 0.151983 L 12 8 L -0 8 Z"/>
<path id="path1" fill="#000000" stroke="none" d="M 6.003452 8 C 6.176163 8 6.348875 7.926277 6.466314 7.786301 L 11.813452 1.942658 C 11.930884 1.817382 12 1.655266 12 1.471041 C 12 1.087846 11.730542 0.793088 11.37131 0.793088 C 11.198627 0.793088 11.03974 0.866779 10.922307 0.984686 L 5.630391 6.754628 L 6.369602 6.754628 L 1.077721 0.984686 C 0.967186 0.866779 0.808291 0.793088 0.62867 0.793088 C 0.26943 0.793088 -0 1.087846 -0 1.471041 C -0 1.655266 0.069085 1.817382 0.186528 1.950024 L 5.533679 7.786301 C 5.664934 7.926277 5.82383 8 6.003452 8 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 925 B

11
static/img/down.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.9629" height="10.4004">
<g>
<rect height="10.4004" opacity="0" width="16.9629" x="0" y="0"/>
<path d="M8.48633 10.4004C8.73047 10.4004 8.97461 10.3027 9.14062 10.1172L16.6992 2.37305C16.8652 2.20703 16.9629 1.99219 16.9629 1.74805C16.9629 1.24023 16.582 0.849609 16.0742 0.849609C15.8301 0.849609 15.6055 0.947266 15.4395 1.10352L7.95898 8.75L9.00391 8.75L1.52344 1.10352C1.36719 0.947266 1.14258 0.849609 0.888672 0.849609C0.380859 0.849609 0 1.24023 0 1.74805C0 1.99219 0.0976562 2.20703 0.263672 2.38281L7.82227 10.1172C8.00781 10.3027 8.23242 10.4004 8.48633 10.4004Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 905 B

11
static/img/gear.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.4102" height="20.4199">
<g>
<rect height="20.4199" opacity="0" width="20.4102" x="0" y="0"/>
<path d="M9.30664 20.4102L11.1035 20.4102C11.6113 20.4102 11.9824 20.1074 12.0898 19.6094L12.5977 17.4609C12.9785 17.334 13.3496 17.1875 13.6719 17.0312L15.5566 18.1836C15.9766 18.4473 16.4551 18.4082 16.8066 18.0566L18.0664 16.8066C18.418 16.4551 18.4668 15.9473 18.1836 15.5273L17.0312 13.6621C17.1973 13.3203 17.3438 12.9688 17.4512 12.6172L19.6191 12.0996C20.1172 11.9922 20.4102 11.6211 20.4102 11.1133L20.4102 9.3457C20.4102 8.84766 20.1172 8.47656 19.6191 8.36914L17.4707 7.85156C17.3438 7.45117 17.1875 7.08984 17.0508 6.78711L18.2031 4.89258C18.4766 4.47266 18.4473 3.99414 18.0859 3.64258L16.8066 2.38281C16.4453 2.05078 16.0156 1.99219 15.5859 2.23633L13.6719 3.41797C13.3594 3.25195 12.998 3.10547 12.5977 2.97852L12.0898 0.800781C11.9824 0.302734 11.6113 0 11.1035 0L9.30664 0C8.79883 0 8.42773 0.302734 8.31055 0.800781L7.80273 2.95898C7.42188 3.08594 7.05078 3.23242 6.71875 3.4082L4.82422 2.23633C4.39453 1.99219 3.95508 2.04102 3.59375 2.38281L2.32422 3.64258C1.96289 3.99414 1.92383 4.47266 2.20703 4.89258L3.34961 6.78711C3.22266 7.08984 3.06641 7.45117 2.93945 7.85156L0.791016 8.36914C0.292969 8.47656 0 8.84766 0 9.3457L0 11.1133C0 11.6211 0.292969 11.9922 0.791016 12.0996L2.95898 12.6172C3.06641 12.9688 3.21289 13.3203 3.36914 13.6621L2.22656 15.5273C1.93359 15.9473 1.99219 16.4551 2.34375 16.8066L3.59375 18.0566C3.94531 18.4082 4.43359 18.4473 4.85352 18.1836L6.72852 17.0312C7.06055 17.1875 7.42188 17.334 7.80273 17.4609L8.31055 19.6094C8.42773 20.1074 8.79883 20.4102 9.30664 20.4102ZM10.2051 13.6523C8.31055 13.6523 6.75781 12.0898 6.75781 10.1953C6.75781 8.31055 8.31055 6.75781 10.2051 6.75781C12.0996 6.75781 13.6523 8.31055 13.6523 10.1953C13.6523 12.0898 12.0996 13.6523 10.2051 13.6523Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
static/img/griphon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

5
static/img/griphon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 325 KiB

3
static/img/li-line.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="33" height="2" fill="none" viewBox="0 0 33 2">
<rect width="33" height="2" fill="#8086F9" rx="1"/>
</svg>

After

Width:  |  Height:  |  Size: 155 B

3
static/img/li.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="23" fill="none" viewBox="0 0 35 23">
<path fill="#8086F9" d="M2 1V0H0v1h2Zm32 22a1 1 0 1 0 0-2v2ZM0 1c0 4.963-.004 8.88.531 11.893.545 3.07 1.674 5.362 4.04 6.94 2.285 1.523 5.598 2.286 10.264 2.694C19.527 22.938 25.759 23 34 23v-2c-8.259 0-14.402-.063-18.99-.465-4.616-.404-7.491-1.14-9.33-2.367-1.76-1.173-2.693-2.88-3.18-5.624C2.004 9.745 2 6.037 2 1H0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 428 B

11
static/img/options.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="19.6777" height="16.6504">
<g>
<rect height="16.6504" opacity="0" width="19.6777" x="0" y="0"/>
<path d="M13.3398 16.6504C14.6289 16.6504 15.6836 15.5957 15.6836 14.3066C15.6836 13.0176 14.6289 11.9629 13.3398 11.9629C12.0508 11.9629 10.9863 13.0176 10.9863 14.3066C10.9863 15.5957 12.0508 16.6504 13.3398 16.6504ZM13.3398 15.4492C12.6953 15.4492 12.1973 14.9414 12.1973 14.3066C12.1973 13.6523 12.6953 13.1641 13.3398 13.1641C13.9844 13.1641 14.4824 13.6523 14.4824 14.3066C14.4824 14.9414 13.9844 15.4492 13.3398 15.4492ZM11.7871 13.5156L0.78125 13.5156C0.341797 13.5156 0 13.8672 0 14.3066C0 14.7461 0.341797 15.0879 0.78125 15.0879L11.7871 15.0879ZM18.9258 13.5156L15.0391 13.5156L15.0391 15.0879L18.9258 15.0879C19.3262 15.0879 19.6777 14.7461 19.6777 14.3066C19.6777 13.8672 19.3262 13.5156 18.9258 13.5156ZM6.44531 10.6934C7.73438 10.6934 8.78906 9.62891 8.78906 8.33984C8.78906 7.05078 7.73438 5.99609 6.44531 5.99609C5.15625 5.99609 4.10156 7.05078 4.10156 8.33984C4.10156 9.62891 5.15625 10.6934 6.44531 10.6934ZM6.44531 9.48242C5.81055 9.48242 5.30273 8.97461 5.30273 8.33984C5.30273 7.69531 5.81055 7.19727 6.44531 7.19727C7.08984 7.19727 7.58789 7.69531 7.58789 8.33984C7.58789 8.97461 7.08984 9.48242 6.44531 9.48242ZM0.742188 7.54883C0.341797 7.54883 0 7.90039 0 8.33984C0 8.7793 0.341797 9.12109 0.742188 9.12109L4.76562 9.12109L4.76562 7.54883ZM18.8867 7.54883L7.99805 7.54883L7.99805 9.12109L18.8867 9.12109C19.3262 9.12109 19.6777 8.7793 19.6777 8.33984C19.6777 7.90039 19.3262 7.54883 18.8867 7.54883ZM13.3398 4.7168C14.6289 4.7168 15.6836 3.66211 15.6836 2.37305C15.6836 1.08398 14.6289 0.0195312 13.3398 0.0195312C12.0508 0.0195312 10.9863 1.08398 10.9863 2.37305C10.9863 3.66211 12.0508 4.7168 13.3398 4.7168ZM13.3398 3.51562C12.6953 3.51562 12.1973 3.00781 12.1973 2.36328C12.1973 1.71875 12.6953 1.2207 13.3398 1.2207C13.9844 1.2207 14.4824 1.71875 14.4824 2.36328C14.4824 3.00781 13.9844 3.51562 13.3398 3.51562ZM11.8359 1.5918L0.78125 1.5918C0.341797 1.5918 0 1.93359 0 2.37305C0 2.8125 0.341797 3.16406 0.78125 3.16406L11.8359 3.16406ZM18.9258 1.5918L14.9023 1.5918L14.9023 3.16406L18.9258 3.16406C19.3262 3.16406 19.6777 2.8125 19.6777 2.37305C19.6777 1.93359 19.3262 1.5918 18.9258 1.5918Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

11
static/img/person.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="19.9219" height="19.9316">
<g>
<rect height="19.9316" opacity="0" width="19.9219" x="0" y="0"/>
<path d="M9.96094 19.9219C15.4102 19.9219 19.9219 15.4004 19.9219 9.96094C19.9219 4.51172 15.4004 0 9.95117 0C4.51172 0 0 4.51172 0 9.96094C0 15.4004 4.52148 19.9219 9.96094 19.9219ZM9.96094 18.2617C5.35156 18.2617 1.66992 14.5703 1.66992 9.96094C1.66992 5.35156 5.3418 1.66016 9.95117 1.66016C14.5605 1.66016 18.2617 5.35156 18.2617 9.96094C18.2617 14.5703 14.5703 18.2617 9.96094 18.2617ZM16.6406 16.3965L16.6113 16.2891C16.1328 14.8535 13.5547 13.2812 9.96094 13.2812C6.37695 13.2812 3.79883 14.8535 3.31055 16.2793L3.28125 16.3965C5.03906 18.1348 8.05664 19.1504 9.96094 19.1504C11.875 19.1504 14.8633 18.1445 16.6406 16.3965ZM9.96094 11.6211C11.8457 11.6406 13.3105 10.0391 13.3105 7.93945C13.3105 5.9668 11.8359 4.33594 9.96094 4.33594C8.08594 4.33594 6.60156 5.9668 6.61133 7.93945C6.62109 10.0391 8.08594 11.6016 9.96094 11.6211Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

11
static/img/play.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="23.0273" height="17.9785">
<g>
<rect height="17.9785" opacity="0" width="23.0273" x="0" y="0"/>
<path d="M3.06641 17.9785L19.9609 17.9785C22.0117 17.9785 23.0273 16.9727 23.0273 14.9609L23.0273 3.02734C23.0273 1.01562 22.0117 0 19.9609 0L3.06641 0C1.02539 0 0 1.01562 0 3.02734L0 14.9609C0 16.9727 1.02539 17.9785 3.06641 17.9785ZM9.6582 12.9297C9.19922 13.2129 8.65234 12.9883 8.65234 12.5L8.65234 5.49805C8.65234 5.01953 9.23828 4.81445 9.6582 5.06836L15.4004 8.4668C15.8105 8.71094 15.8203 9.29688 15.4004 9.55078Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 848 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="31" height="31" fill="none" viewBox="0 0 31 31">
<rect width="31" height="31" fill="#fff" rx="15.5"/>
<rect width="30" height="30" x=".5" y=".5" stroke="#000" stroke-opacity=".1" rx="15"/>
<rect width="17" height="17" x="7" y="7" fill="#8086F9" rx="8.5"/>
</svg>

After

Width:  |  Height:  |  Size: 316 B

4
static/img/radio.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="31" height="31" fill="none" viewBox="0 0 31 31">
<rect width="31" height="31" fill="#fff" rx="15.5"/>
<rect width="30" height="30" x=".5" y=".5" stroke="#000" stroke-opacity=".1" rx="15"/>
</svg>

After

Width:  |  Height:  |  Size: 247 B

11
static/img/search.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="19.082" height="19.2676">
<g>
<rect height="19.2676" opacity="0" width="19.082" x="0" y="0"/>
<path d="M0 7.79297C0 12.0898 3.49609 15.5859 7.79297 15.5859C9.49219 15.5859 11.0449 15.0391 12.3242 14.1211L17.1289 18.9355C17.3535 19.1602 17.6465 19.2676 17.959 19.2676C18.623 19.2676 19.082 18.7695 19.082 18.1152C19.082 17.8027 18.9648 17.5195 18.7598 17.3145L13.9844 12.5098C14.9902 11.2012 15.5859 9.57031 15.5859 7.79297C15.5859 3.49609 12.0898 0 7.79297 0C3.49609 0 0 3.49609 0 7.79297ZM1.66992 7.79297C1.66992 4.41406 4.41406 1.66992 7.79297 1.66992C11.1719 1.66992 13.916 4.41406 13.916 7.79297C13.916 11.1719 11.1719 13.916 7.79297 13.916C4.41406 13.916 1.66992 11.1719 1.66992 7.79297Z" fill="#000000" fill-opacity="0.25"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

10
static/img/share.svg Normal file
View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="22" fill="none" viewBox="0 0 17 22">
<g clip-path="url(#a)">
<path fill="#000" fill-opacity=".75" d="M2.872 20.646h10.493c1.912 0 2.872-.951 2.872-2.836V8.681c0-1.884-.96-2.836-2.872-2.836h-2.553v1.473h2.525c.906 0 1.427.494 1.427 1.445v8.965c0 .951-.521 1.445-1.427 1.445H2.891c-.915 0-1.418-.494-1.418-1.445V8.763c0-.95.503-1.445 1.418-1.445h2.534V5.845H2.872C.961 5.845 0 6.797 0 8.681v9.13c0 1.884.96 2.835 2.872 2.835Zm5.242-7.162c.393 0 .732-.33.732-.714V3.375L8.79 2.003l.613.65 1.39 1.482c.128.146.311.22.494.22.375 0 .668-.275.668-.65 0-.192-.082-.339-.22-.476L8.645.247C8.462.064 8.306 0 8.114 0c-.183 0-.339.064-.53.247L4.49 3.229a.638.638 0 0 0-.21.476c0 .375.275.65.659.65a.687.687 0 0 0 .503-.22l1.381-1.482.622-.65-.055 1.372v9.395c0 .384.33.714.723.714Z"/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h16.237v22H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 957 B

BIN
static/img/traffic.mp4 Normal file

Binary file not shown.

11
static/img/trash.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18.9062" height="23.4863">
<g>
<rect height="23.4863" opacity="0" width="18.9062" x="0" y="0"/>
<path d="M5.16602 4.46289L6.71875 4.46289L6.71875 2.37305C6.71875 1.81641 7.10938 1.45508 7.69531 1.45508L11.1914 1.45508C11.7773 1.45508 12.168 1.81641 12.168 2.37305L12.168 4.46289L13.7207 4.46289L13.7207 2.27539C13.7207 0.859375 12.8027 0 11.2988 0L7.58789 0C6.08398 0 5.16602 0.859375 5.16602 2.27539ZM0.732422 5.24414L18.1836 5.24414C18.584 5.24414 18.9062 4.90234 18.9062 4.50195C18.9062 4.10156 18.584 3.76953 18.1836 3.76953L0.732422 3.76953C0.341797 3.76953 0 4.10156 0 4.50195C0 4.91211 0.341797 5.24414 0.732422 5.24414ZM4.98047 21.748L13.9355 21.748C15.332 21.748 16.2695 20.8398 16.3379 19.4434L17.0215 5.05859L15.4492 5.05859L14.7949 19.2773C14.7754 19.8633 14.3555 20.2734 13.7793 20.2734L5.11719 20.2734C4.56055 20.2734 4.14062 19.8535 4.11133 19.2773L3.41797 5.05859L1.88477 5.05859L2.57812 19.4531C2.64648 20.8496 3.56445 21.748 4.98047 21.748ZM6.5625 18.6035C6.93359 18.6035 7.17773 18.3691 7.16797 18.0273L6.86523 7.57812C6.85547 7.23633 6.61133 7.01172 6.25977 7.01172C5.88867 7.01172 5.64453 7.24609 5.6543 7.58789L5.94727 18.0273C5.95703 18.3789 6.20117 18.6035 6.5625 18.6035ZM9.45312 18.6035C9.82422 18.6035 10.0879 18.3691 10.0879 18.0273L10.0879 7.58789C10.0879 7.24609 9.82422 7.01172 9.45312 7.01172C9.08203 7.01172 8.82812 7.24609 8.82812 7.58789L8.82812 18.0273C8.82812 18.3691 9.08203 18.6035 9.45312 18.6035ZM12.3535 18.6035C12.7051 18.6035 12.9492 18.3789 12.959 18.0273L13.252 7.58789C13.2617 7.24609 13.0176 7.01172 12.6465 7.01172C12.2949 7.01172 12.0508 7.23633 12.041 7.58789L11.748 18.0273C11.7383 18.3691 11.9824 18.6035 12.3535 18.6035Z" fill="#ff453a"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

3
static/img/ul.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="37" height="22" fill="none" viewBox="0 0 37 22">
<path fill="#8086F9" d="M2 1V0H0v1h2Zm34 21a1 1 0 1 0 0-2v2ZM0 1c0 4.958-.004 8.824.565 11.753.585 3.007 1.803 5.18 4.314 6.615 2.405 1.375 5.893 2.004 10.823 2.318C20.663 22 27.264 22 36 22v-2c-8.764 0-15.288 0-20.171-.31-4.913-.312-7.988-.933-9.958-2.058-1.864-1.065-2.833-2.642-3.343-5.26C2.004 9.676 2 6.042 2 1H0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 427 B

11
static/img/up.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.9629" height="10.3418">
<g>
<rect height="10.3418" opacity="0" width="16.9629" x="0" y="0"/>
<path d="M0.263672 8.02734C0.0976562 8.18359 0 8.4082 0 8.66211C0 9.16992 0.380859 9.55078 0.888672 9.55078C1.14258 9.55078 1.37695 9.46289 1.52344 9.29688L9.00391 1.66016L7.95898 1.66016L15.4395 9.29688C15.5957 9.46289 15.8301 9.55078 16.0742 9.55078C16.582 9.55078 16.9629 9.16992 16.9629 8.66211C16.9629 8.4082 16.8652 8.18359 16.6992 8.02734L9.14062 0.292969C8.97461 0.107422 8.73047 0 8.48633 0C8.23242 0 7.99805 0.107422 7.82227 0.292969Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 871 B

3
static/img/upload.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="none" viewBox="0 0 30 30">
<path fill="#8086F9" fill-opacity=".85" d="M15 29.985c8.206 0 15-6.805 15-14.992C30 6.79 23.191 0 14.985 0 6.795 0 0 6.79 0 14.993c0 8.187 6.809 14.992 15 14.992Zm0-2.498A12.437 12.437 0 0 1 2.515 14.993c0-6.938 5.53-12.494 12.47-12.494A12.462 12.462 0 0 1 27.5 14.993 12.45 12.45 0 0 1 15 27.487Zm-4.162-5.35h8.324c1.603 0 2.44-.824 2.44-2.411v-7.247c0-1.587-.837-2.396-2.44-2.396h-2.177v1.485h2.162c.647 0 .97.323.97.985v7.129c0 .646-.323.984-.97.984h-8.294c-.647 0-.97-.323-.97-.984v-7.13c0-.66.323-.984.97-.984h2.176v-1.485h-2.19c-1.589 0-2.427.823-2.442 2.396v7.247c.015 1.572.853 2.41 2.441 2.41Zm4.147-5.777c.412 0 .736-.309.736-.706V8.217l-.03-.691.647.69.662.691c.118.133.294.206.515.206.397 0 .676-.264.676-.647a.602.602 0 0 0-.22-.485l-2.456-2.38c-.177-.177-.353-.25-.53-.25-.176 0-.353.088-.514.25L12 7.966a.654.654 0 0 0-.206.5c0 .382.28.646.662.646a.686.686 0 0 0 .515-.206l.661-.69.662-.691-.03.69v7.438a.71.71 0 0 0 .721.706Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

11
static/img/waves.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 175.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25.4395" height="17.5343">
<g>
<rect height="17.5343" opacity="0" width="25.4395" x="0" y="0"/>
<path d="M0 8.77202C0 12.0435 1.23047 15.0416 3.35938 17.2681C3.71094 17.6392 4.18945 17.6001 4.46289 17.2876C4.74609 16.9849 4.6875 16.5357 4.35547 16.1939C2.48047 14.2408 1.46484 11.6236 1.46484 8.77202C1.46484 5.92046 2.48047 3.30327 4.35547 1.35015C4.6875 0.998587 4.74609 0.559134 4.46289 0.246634C4.18945-0.0561001 3.71094-0.0951626 3.35938 0.275931C1.23047 2.50249 0 5.50054 0 8.77202ZM3.49609 8.77202C3.49609 11.0865 4.32617 13.2447 5.82031 14.856C6.16211 15.2369 6.66016 15.2466 6.95312 14.9048C7.23633 14.5826 7.1582 14.1626 6.82617 13.8013C5.61523 12.4439 4.95117 10.6861 4.95117 8.77202C4.95117 6.85796 5.61523 5.10015 6.82617 3.74273C7.1582 3.3814 7.23633 2.96148 6.95312 2.62945C6.66016 2.29742 6.16211 2.29742 5.82031 2.67827C4.32617 4.29937 3.49609 6.44781 3.49609 8.77202ZM6.98242 8.77202C6.98242 10.0806 7.43164 11.3111 8.21289 12.2779C8.53516 12.688 9.07227 12.688 9.36523 12.356C9.6582 12.024 9.53125 11.6334 9.24805 11.233C8.7207 10.5689 8.44727 9.70952 8.44727 8.77202C8.44727 7.83452 8.7207 6.97515 9.24805 6.30132C9.53125 5.9107 9.6582 5.52007 9.36523 5.18804C9.07227 4.85601 8.53516 4.85601 8.21289 5.2564C7.43164 6.2232 6.98242 7.45367 6.98242 8.77202ZM18.457 8.77202C18.457 7.45367 18.0078 6.2232 17.2266 5.2564C16.9043 4.85601 16.3672 4.85601 16.0742 5.18804C15.7812 5.52007 15.8984 5.9107 16.1914 6.30132C16.7188 6.97515 16.9922 7.83452 16.9922 8.77202C16.9922 9.70952 16.7188 10.5689 16.1914 11.233C15.8984 11.6334 15.7812 12.024 16.0742 12.356C16.3672 12.688 16.9043 12.688 17.2266 12.2779C18.0078 11.3111 18.457 10.0806 18.457 8.77202ZM21.9434 8.77202C21.9434 6.44781 21.1133 4.29937 19.6191 2.67827C19.2773 2.29742 18.7793 2.29742 18.4863 2.62945C18.1934 2.96148 18.2812 3.3814 18.6035 3.74273C19.8242 5.10015 20.4883 6.85796 20.4883 8.77202C20.4883 10.6861 19.8242 12.4439 18.6035 13.8013C18.2812 14.1626 18.1934 14.5826 18.4863 14.9048C18.7793 15.2466 19.2773 15.2369 19.6191 14.856C21.1133 13.2447 21.9434 11.0865 21.9434 8.77202ZM25.4395 8.77202C25.4395 5.50054 24.209 2.50249 22.0801 0.275931C21.7285-0.0951626 21.25-0.0561001 20.9766 0.246634C20.6934 0.559134 20.752 0.998587 21.084 1.35015C22.9492 3.30327 23.9746 5.92046 23.9746 8.77202C23.9746 11.6236 22.9492 14.2408 21.084 16.1939C20.752 16.5357 20.6934 16.9849 20.9766 17.2876C21.25 17.6001 21.7285 17.6392 22.0801 17.2681C24.209 15.0416 25.4395 12.0435 25.4395 8.77202ZM10.9375 8.79156C10.9375 9.73882 11.7676 10.5396 12.7344 10.5396C13.7012 10.5396 14.4922 9.73882 14.4922 8.77202C14.4922 7.79546 13.7109 6.99468 12.7344 6.99468C11.748 6.99468 10.9375 7.81499 10.9375 8.79156Z" fill="#000000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

132
static/scripts/graphs.js Normal file
View File

@ -0,0 +1,132 @@
Chart.defaults.color = "rgba(0, 0, 0, 0.4)";
Chart.defaults.font.size = 15;
Chart.defaults.font.weight = 400;
var warningsData = {
labels: [
"9.03",
"10.03",
"11.03",
"12.03",
"13.03",
"14.03",
"15.03",
"16.03",
"17.03",
"18.03",
"19.03",
],
datasets: [
{
label: "Актуальный период",
backgroundColor: "rgba(235, 146, 139, 1)",
borderWidth: 0,
borderRadius: 9,
hoverBackgroundColor: "rgba(235, 146, 139, 0.8)",
data: [1150, 1400, 2100, 900, 1200, 400, 950, 1400, 1250, 1150, 1650],
grouped: false,
},
{
label: "Предыдущий период",
backgroundColor: "rgba(235, 146, 139, 0.5)",
borderWidth: 0,
borderRadius: 9,
hoverBackgroundColor: "rgba(235, 146, 139, 0.3)",
data: [2700, 1850, 1100, 1550, 2300, 2200, 1650, 1200, 1500, 1850, 800],
},
],
};
var warningsOptions = {
plugins: {
legend: {
display: false,
},
},
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
grid: {
display: true,
color: "#D9D9D9",
},
},
x: {
grid: {
display: false,
},
},
},
};
new Chart("chart-warnings", {
type: "bar",
options: warningsOptions,
data: warningsData,
});
var positionsData = {
labels: [
"9.03",
"10.03",
"11.03",
"12.03",
"13.03",
"14.03",
"15.03",
"16.03",
"17.03",
"18.03",
"19.03",
],
datasets: [
{
label: "Позиционирование",
borderColor: "#8086F9",
fill: false,
data: [
480000, 390000, 407000, 400000, 435000, 460000, 385000, 410000, 380000,
410000, 410000,
],
pointStyle: false,
pointRadius: 25,
pointHoverRadius: 25,
tension: 0.4,
},
],
};
var positionsOptions = {
plugins: {
legend: {
display: false,
},
},
labelStep: "3",
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
stacked: true,
grid: {
display: true,
color: "#D9D9D9",
},
ticks: {
stepSize: 50000,
},
},
x: {
grid: {
display: false,
},
},
},
};
new Chart("chart-positions", {
type: "line",
data: positionsData,
options: positionsOptions,
});

10965
static/scripts/jquery.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,285 @@
const devices = [
{
id: "2",
group: "2-device-2",
driverID: "233",
name: "Иван",
surname: "Спахов",
numberTS: "008803559E",
phone: "+7 999 123 45 67",
mail: "spahov@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "6",
group: "2-device-1",
driverID: "782",
name: "Александр",
surname: "Богаченко",
numberTS: "0088036B78",
phone: "+7 989 443 23 46",
mail: "bogachenko@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "7",
group: "2-device-4",
driverID: "2943",
name: "Михаил",
surname: "Гукасян",
numberTS: "009800852A",
phone: "+7 909 133 55 67",
mail: "agucasyan@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "8",
group: "2-device-4",
driverID: "87",
name: "Марат",
surname: "Шмидт",
numberTS: "009800858D",
phone: "+7 915 555 45 89",
mail: "shmidt@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "9",
group: "1-device-1",
driverID: "823",
name: "Никита",
surname: "Ильяшенко",
numberTS: "00980084FD",
phone: "+7 909 123 45 67",
mail: "iluashenko@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "10",
group: "2-device-4",
driverID: "15",
name: "Валерий",
surname: "Сараев",
numberTS: "0088036B7F",
phone: "+7 909 123 45 67",
mail: "saraev@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "11",
group: "2-device-3",
driverID: "423",
name: "Александр",
surname: "Курочкин",
numberTS: "00880302CD",
phone: "+7 999 123 45 67",
mail: "curochkin@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "12",
group: "1-device-2",
driverID: "6456",
name: "Екатерина",
surname: "Миненко",
numberTS: "008802A035",
phone: "+7 999 123 45 67",
mail: "minenko@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "13",
group: "3-device-1",
driverID: "887",
name: "Виталий",
surname: "Гаспарян",
numberTS: "008802A96A",
phone: "+7 999 123 45 67",
mail: "gosparyan@mail.ru",
driverCard: "RUD0000000000111",
},
{
id: "15",
group: "1-device-1",
driverID: "742",
name: "Светлана",
surname: "Амусова",
numberTS: "00880302C7",
phone: "+7 999 123 45 67",
mail: "amusova@mail.ru",
driverCard: "RUD0000000000111",
},
];
// Получаем высоту таблицы и определяем, сколько строк помещается на странице
let currentPage = 1;
let tableHeight = document.getElementById("table-area").offsetHeight;
let rowHeight = 60;
let rowsPerPage = Math.floor(tableHeight / rowHeight) - 2;
let filteredDevices = [...devices];
const createTable = () => {
const table = document.getElementById("deviceTable");
const tbody = table.querySelector("tbody");
// Очищаем таблицу
tbody.innerHTML = "";
// Добавляем строки таблицы
const startIndex = (currentPage - 1) * rowsPerPage;
const endIndex = startIndex + rowsPerPage;
const devicesToDisplay = filteredDevices.slice(startIndex, endIndex);
devicesToDisplay.forEach((device) => {
const row = document.createElement("tr");
// Добавляем чекбокс перед каждым рядом
const checkboxCell = document.createElement("td");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.value = `device-${device.id}`;
checkbox.id = `device-${device.id}`;
const checkboxLabel = document.createElement("label");
checkboxLabel.setAttribute("for", `device-${device.id}`);
const checkboxDiv = document.createElement("div");
checkboxDiv.setAttribute("class", "checkmark");
checkboxLabel.appendChild(checkboxDiv);
checkboxCell.appendChild(checkbox);
checkboxCell.appendChild(checkboxLabel);
row.appendChild(checkboxCell);
// Добавляем ячейки с данными
const driverID = document.createElement("td");
driverID.textContent = device.driverID;
row.appendChild(driverID);
const name = document.createElement("td");
name.textContent = device.name;
row.appendChild(name);
const surname = document.createElement("td");
surname.textContent = device.surname;
row.appendChild(surname);
const numberTS = document.createElement("td");
numberTS.textContent = device.numberTS;
row.appendChild(numberTS);
const phone = document.createElement("td");
phone.textContent = device.phone;
row.appendChild(phone);
const mail = document.createElement("td");
mail.textContent = device.mail;
row.appendChild(mail);
const driverCard = document.createElement("td");
driverCard.textContent = device.driverCard;
row.appendChild(driverCard);
// Добавляем кнопку удаления после каждого ряда
const trashCell = document.createElement("td");
trashCell.setAttribute("class", "optionsCell");
const trashButton = document.createElement("button");
trashButton.setAttribute("class", "trash");
trashButton.value = `delete-device-${device.id}`;
trashButton.id = `delete-device-${device.id}`;
const optionsButton = document.createElement("button");
optionsButton.setAttribute("class", "options");
optionsButton.value = `options-device-${device.id}`;
optionsButton.id = `options-device-${device.id}`;
trashCell.appendChild(optionsButton);
trashCell.appendChild(trashButton);
row.appendChild(trashCell);
tbody.appendChild(row);
});
};
window.addEventListener("resize", function (event) {
tableHeight = document.getElementById("table-area").offsetHeight;
rowHeight = 60;
rowsPerPage = Math.floor(tableHeight / rowHeight) - 2;
createTable();
createPagination();
});
const createPagination = () => {
const count = document.getElementById("count");
count.textContent = `Всего результатов: ${filteredDevices.length}`;
const pagination = document.getElementById("pagination");
pagination.innerHTML = "";
const pageCount = Math.ceil(filteredDevices.length / rowsPerPage);
for (let i = 1; i <= pageCount; i++) {
const pageLink = document.createElement("a");
pageLink.href = "#";
if (i === currentPage) {
document.querySelector("#device-all").checked = false;
pageLink.classList.add("active");
}
pageLink.textContent = i;
pageLink.addEventListener("click", (event) => {
event.preventDefault();
currentPage = i - 1;
currentPage = i;
createTable();
createPagination();
});
pagination.appendChild(pageLink);
}
// var currentPageSpan = document.createElement("span");
// currentPageSpan.textContent = currentPage;
// pagination.appendChild(currentPageSpan);
// Добавляем кнопки "Next" и "Previous"
// const prevButton = document.createElement("button");
// prevButton.innerText = "Previous";
// prevButton.onclick = () => {
// if (currentPage === 1) return;
// currentPage--;
// createTable();
// };
// pagination.appendChild(prevButton);
// const nextButton = document.createElement("button");
// nextButton.innerText = "Next";
// nextButton.onclick = () => {
// if (currentPage === pageCount) return;
// currentPage++;
// createTable();
// };
// pagination.appendChild(nextButton);
};
const applyFilterAndSearch = () => {
const searchValue = searchInput.value.toLowerCase();
const groupFilters = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter:checked')
).map((checkbox) => checkbox.value);
filteredDevices = devices.filter((device) => {
const searchString =
`${device.group} ${device.driverID} ${device.name} ${device.number} ${device.surname} ${device.numberTS} ${device.phone} ${device.mail} ${device.driverCard}`.toLowerCase();
const matchGroup =
groupFilters.length === 0 || groupFilters.includes(device.group);
const matchSearch = !searchValue || searchString.includes(searchValue);
return matchGroup && matchSearch;
});
currentPage = 1;
createTable();
createPagination();
};
const searchInput = document.getElementById("table-search");
searchInput.addEventListener("input", applyFilterAndSearch);
const filterCheckboxes = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter')
);
filterCheckboxes.forEach((checkbox) => {
checkbox.addEventListener("change", applyFilterAndSearch);
});
createTable();
createPagination();

View File

@ -0,0 +1,313 @@
const devices = [
{
id: "1",
group: "0001",
name: "Разговор по телефону",
reportID: "354",
plate: "AO30877",
numberTS: "008803559E",
time: "12.03.23 17:33",
place: "59.852371, 30.344543",
},
{
id: "2",
group: "0001",
name: "Водитель зевает",
reportID: "353",
plate: "AO64377",
numberTS: "0088036B78",
time: "12.03.23 14:26",
place: "60.058236, 30.315283",
},
{
id: "3",
group: "0002",
name: "Усталость",
reportID: "352",
plate: "ГД44377",
numberTS: "009800852A",
time: "12.03.23 10:07",
place: "59.878256, 30.31962",
},
{
id: "4",
group: "0003",
name: "Водитель зевает",
reportID: "351",
plate: "УА86577",
numberTS: "009800858D",
time: "12.03.23 09:56",
place: "60.045981, 30.4134",
},
{
id: "5",
group: "0003",
name: "Разговор по телефону",
reportID: "350",
plate: В74665",
numberTS: "00980084FD",
time: "11.03.23 20:43",
place: "59.83257, 30.389893",
},
{
id: "6",
group: "0004",
name: "Разговор по телефону",
reportID: "349",
plate: У445101",
numberTS: "0088036B7F",
time: "11.03.23 19:17",
place: "59.959926, 30.42224",
},
{
id: "7",
group: "0005",
name: "Усталость",
reportID: "348",
plate: "КТ32376",
numberTS: "00880302CD",
time: "11.03.23 15:32",
place: "60.046346, 30.405688",
},
{
id: "8",
group: "0006",
name: "Курение за рулём",
reportID: "347",
plate: "ОА33277",
numberTS: "008802A035",
time: "11.03.23 15:06",
place: "59.956626, 30.234408",
},
{
id: "9",
group: "0007",
name: "Водитель отвлекся",
reportID: "346",
plate: "КЛ987102",
numberTS: "008802A96A",
time: "11.03.23 12:44",
place: "59.956626, 30.234408",
},
{
id: "10",
group: "0002",
name: "Водитель отвлекся",
reportID: "345",
plate: "АУ22377",
numberTS: "00880302C7",
time: "11.03.23 11:40",
place: "59.956626, 30.234408",
},
];
// Получаем высоту таблицы и определяем, сколько строк помещается на странице
let currentPage = 1;
let tableHeight = document.getElementById("table-area").offsetHeight;
let rowHeight = 60;
let rowsPerPage = Math.floor(tableHeight / rowHeight) - 3;
let filteredDevices = [...devices];
let timeRangeStart = null;
let timeRangeEnd = null;
const createTable = () => {
const table = document.getElementById("deviceTable");
const tbody = table.querySelector("tbody");
// Очищаем таблицу
tbody.innerHTML = "";
// Добавляем строки таблицы
const startIndex = (currentPage - 1) * rowsPerPage;
const endIndex = startIndex + rowsPerPage;
const devicesToDisplay = filteredDevices.slice(startIndex, endIndex);
devicesToDisplay.forEach((device) => {
const row = document.createElement("tr");
// Добавляем чекбокс перед каждым рядом
const checkboxCell = document.createElement("td");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.value = `device-${device.id}`;
checkbox.id = `device-${device.id}`;
const checkboxLabel = document.createElement("label");
checkboxLabel.setAttribute("for", `device-${device.id}`);
const checkboxDiv = document.createElement("div");
checkboxDiv.setAttribute("class", "checkmark");
checkboxLabel.appendChild(checkboxDiv);
checkboxCell.appendChild(checkbox);
checkboxCell.appendChild(checkboxLabel);
row.appendChild(checkboxCell);
// Добавляем ячейки с данными
const name = document.createElement("td");
name.textContent = device.name;
row.appendChild(name);
const reportID = document.createElement("td");
reportID.textContent = device.reportID;
row.appendChild(reportID);
const plate = document.createElement("td");
plate.textContent = device.plate;
row.appendChild(plate);
const numberTS = document.createElement("td");
numberTS.textContent = device.numberTS;
row.appendChild(numberTS);
const time = document.createElement("td");
time.textContent = device.time;
row.appendChild(time);
const place = document.createElement("td");
place.textContent = device.place;
row.appendChild(place);
// Добавляем кнопку удаления после каждого ряда
const shareCell = document.createElement("td");
const shareButton = document.createElement("button");
shareButton.setAttribute("class", "share");
shareButton.setAttribute("onclick", "location.href = '/reports/346';");
shareButton.value = `delete-device-${device.id}`;
shareButton.id = `delete-device-${device.id}`;
shareCell.appendChild(shareButton);
row.appendChild(shareCell);
tbody.appendChild(row);
});
};
window.addEventListener("resize", function (event) {
tableHeight = document.getElementById("table-area").offsetHeight;
rowHeight = 60;
rowsPerPage = Math.floor(tableHeight / rowHeight) - 3;
createTable();
createPagination();
});
const createPagination = () => {
const count = document.getElementById("count");
count.textContent = `Всего результатов: ${filteredDevices.length}`;
const pagination = document.getElementById("pagination");
pagination.innerHTML = "";
const pageCount = Math.ceil(filteredDevices.length / rowsPerPage);
for (let i = 1; i <= pageCount; i++) {
const pageLink = document.createElement("a");
pageLink.href = "#";
if (i === currentPage) {
document.querySelector("#device-all").checked = false;
pageLink.classList.add("active");
}
pageLink.textContent = i;
pageLink.addEventListener("click", (event) => {
event.preventDefault();
currentPage = i - 1;
currentPage = i;
createTable();
createPagination();
});
pagination.appendChild(pageLink);
}
// var currentPageSpan = document.createElement("span");
// currentPageSpan.textContent = currentPage;
// pagination.appendChild(currentPageSpan);
// Добавляем кнопки "Next" и "Previous"
// const prevButton = document.createElement("button");
// prevButton.innerText = "Previous";
// prevButton.onclick = () => {
// if (currentPage === 1) return;
// currentPage--;
// createTable();
// };
// pagination.appendChild(prevButton);
// const nextButton = document.createElement("button");
// nextButton.innerText = "Next";
// nextButton.onclick = () => {
// if (currentPage === pageCount) return;
// currentPage++;
// createTable();
// };
// pagination.appendChild(nextButton);
};
const applyFilterAndSearch = () => {
const searchValue = searchInput.value.toLowerCase();
const groupFilters = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter:checked')
).map((checkbox) => checkbox.value);
filteredDevices = devices.filter((device) => {
const searchString =
`${device.group} ${device.name} ${device.reportID} ${device.place} ${device.numberTS} ${device.time} ${device.place}`.toLowerCase();
const matchGroup =
groupFilters.length === 0 || groupFilters.includes(device.group);
const matchSearch = !searchValue || searchString.includes(searchValue);
// Фильтр по временному диапазону
let matchTimeRange = true;
if (timeRangeStart) {
const startTimestamp = new Date(timeRangeStart).getTime();
const deviceTimestamp = parseTableTime(device.time); // Преобразование времени из таблицы
matchTimeRange = startTimestamp <= deviceTimestamp;
}
if (timeRangeEnd) {
const endTimestamp = new Date(timeRangeEnd).getTime();
const deviceTimestamp = parseTableTime(device.time); // Преобразование времени из таблицы
matchTimeRange = matchTimeRange && deviceTimestamp <= endTimestamp;
}
return matchGroup && matchSearch && matchTimeRange;
});
currentPage = 1;
createTable();
createPagination();
};
// Функция для преобразования времени из таблицы в миллисекунды
function parseTableTime(tableTime) {
// Парсинг даты и времени из строки формата "12.03.23 17:33"
const parts = tableTime.split(" ");
const dateParts = parts[0].split(".");
const timeParts = parts[1].split(":");
const year = 2000 + parseInt(dateParts[2]);
const month = parseInt(dateParts[1]) - 1; // Месяцы в JavaScript начинаются с 0
const day = parseInt(dateParts[0]);
const hours = parseInt(timeParts[0]);
const minutes = parseInt(timeParts[1]);
return new Date(year, month, day, hours, minutes).getTime();
}
const searchInput = document.getElementById("table-search");
searchInput.addEventListener("input", applyFilterAndSearch);
const filterCheckboxes = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter')
);
filterCheckboxes.forEach((checkbox) => {
checkbox.addEventListener("change", applyFilterAndSearch);
});
// Обработчик изменения значения в поле начала временного диапазона
const timeRangeStartInput = document.getElementById("timeRangeStart");
timeRangeStartInput.addEventListener("change", () => {
timeRangeStart = timeRangeStartInput.value;
console.log(timeRangeStart);
applyFilterAndSearch();
});
// Обработчик изменения значения в поле конца временного диапазона
const timeRangeEndInput = document.getElementById("timeRangeEnd");
timeRangeEndInput.addEventListener("change", () => {
timeRangeEnd = timeRangeEndInput.value;
console.log(timeRangeEnd);
applyFilterAndSearch();
});
createTable();
createPagination();

View File

@ -0,0 +1,284 @@
const devices = [
{
id: "1",
group: "0001",
name: "Трамваи",
numberTS: "008803559E",
time: "12.03.23 17:33",
file: "X5H_V262_T191112.80_R0010_FS5.0",
status: 100,
},
{
id: "2",
group: "0001",
name: "Электробусы",
numberTS: "0088036B78",
time: "12.03.23 17:33",
file: "A5H_V262.B107_T220801.70_C3920",
status: 60,
},
{
id: "3",
group: "0002",
name: "Трамваи",
numberTS: "009800852A",
time: "12.03.23 17:33",
file: "A5H_V262.B107_T220801.70_C3920",
status: 90,
},
{
id: "4",
group: "0003",
name: "Троллейбусы",
numberTS: "009800858D",
time: "12.03.23 17:33",
file: "A5H_V262.B107_T220801.70_C3920",
status: 100,
},
{
id: "5",
group: "0003",
name: "Электробусы",
numberTS: "00980084FD",
time: "12.03.23 17:33",
file: "A5H_V262.B107_T220801.70_C3920",
status: 100,
},
{
id: "6",
group: "0004",
name: "Трамваи",
numberTS: "0088036B7F",
time: "12.03.23 17:33",
file: "X5H_V262_T191112.80_R0010_FS5.0",
status: 100,
},
{
id: "7",
group: "0005",
name: "Старые ТС",
numberTS: "00880302CD",
time: "12.03.23 17:33",
file: "X5H_V262_T191112.80_R0010_FS5.0",
status: 20,
},
{
id: "8",
group: "0006",
name: "Старые ТС",
numberTS: "008802A035",
time: "12.03.23 17:33",
file: "X5H_V262_T191112.80_R0010_FS5.0",
status: 100,
},
{
id: "9",
group: "0007",
name: "Трамваи",
numberTS: "008802A96A",
time: "12.03.23 17:33",
file: "X5H_V262_T191112.80_R0010_FS5.0",
status: 100,
},
{
id: "10",
group: "0002",
name: "Старые ТС",
numberTS: "00880302C7",
time: "12.03.23 17:33",
file: "A5H_V262.B107_T220801.70_C3920",
status: 35,
},
];
// Получаем высоту таблицы и определяем, сколько строк помещается на странице
let currentPage = 1;
let tableHeight = document.getElementById("table-area").offsetHeight;
let rowHeight = 60;
let rowsPerPage = Math.floor(tableHeight / rowHeight) - 3;
let filteredDevices = [...devices];
const createTable = () => {
const table = document.getElementById("deviceTable");
const tbody = table.querySelector("tbody");
// Очищаем таблицу
tbody.innerHTML = "";
// Добавляем строки таблицы
const startIndex = (currentPage - 1) * rowsPerPage;
const endIndex = startIndex + rowsPerPage;
const devicesToDisplay = filteredDevices.slice(startIndex, endIndex);
devicesToDisplay.forEach((device) => {
const row = document.createElement("tr");
// Добавляем чекбокс перед каждым рядом
const checkboxCell = document.createElement("td");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.value = `device-${device.id}`;
checkbox.id = `device-${device.id}`;
const checkboxLabel = document.createElement("label");
checkboxLabel.setAttribute("for", `device-${device.id}`);
const checkboxDiv = document.createElement("div");
checkboxDiv.setAttribute("class", "checkmark");
checkboxLabel.appendChild(checkboxDiv);
checkboxCell.appendChild(checkbox);
checkboxCell.appendChild(checkboxLabel);
row.appendChild(checkboxCell);
// Добавляем ячейки с данными
const name = document.createElement("td");
name.textContent = device.name;
row.appendChild(name);
const numberTS = document.createElement("td");
numberTS.textContent = device.numberTS;
row.appendChild(numberTS);
// const statusСell = document.createElement("td");
// const status = document.createElement("div");
// status.setAttribute("class", "status");
// if (device.status === 100) {
// trashButton.setAttribute("class", "clockwise");
// }
// row.appendChild(statusСell);
const status = document.createElement("div");
status.setAttribute("class", "status");
status.style.width = "80px";
status.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
const fill = document.createElement("div");
if (device.status === 100) {
fill.style.width = `${device.status}%`;
fill.style.height = "100%";
fill.style.backgroundColor = "#32D74B";
fill.style.borderRadius = "5px";
} else {
fill.style.width = `${device.status}%`;
fill.style.height = "100%";
fill.style.backgroundColor = "#FF453A";
fill.style.borderRadius = "5px 0px 0px 5px";
}
status.appendChild(fill);
const statusСell = document.createElement("td");
statusСell.title = `Статус: ${device.status}%`;
statusСell.appendChild(status);
row.appendChild(statusСell);
const time = document.createElement("td");
time.textContent = device.time;
row.appendChild(time);
const file = document.createElement("td");
file.textContent = device.file;
row.appendChild(file);
// Добавляем кнопку удаления после каждого ряда
const trashCell = document.createElement("td");
const trashButton = document.createElement("button");
trashButton.setAttribute("class", "clockwise");
trashButton.value = `delete-device-${device.id}`;
trashButton.id = `delete-device-${device.id}`;
trashCell.appendChild(trashButton);
row.appendChild(trashCell);
tbody.appendChild(row);
});
};
window.addEventListener("resize", function (event) {
tableHeight = document.getElementById("table-area").offsetHeight;
rowHeight = 60;
rowsPerPage = Math.floor(tableHeight / rowHeight) - 3;
createTable();
createPagination();
});
const createPagination = () => {
const count = document.getElementById("count");
count.textContent = `Всего результатов: ${filteredDevices.length}`;
const pagination = document.getElementById("pagination");
pagination.innerHTML = "";
const pageCount = Math.ceil(filteredDevices.length / rowsPerPage);
for (let i = 1; i <= pageCount; i++) {
const pageLink = document.createElement("a");
pageLink.href = "#";
if (i === currentPage) {
document.querySelector("#device-all").checked = false;
pageLink.classList.add("active");
}
pageLink.textContent = i;
pageLink.addEventListener("click", (event) => {
event.preventDefault();
currentPage = i - 1;
currentPage = i;
createTable();
createPagination();
});
pagination.appendChild(pageLink);
}
// var currentPageSpan = document.createElement("span");
// currentPageSpan.textContent = currentPage;
// pagination.appendChild(currentPageSpan);
// Добавляем кнопки "Next" и "Previous"
// const prevButton = document.createElement("button");
// prevButton.innerText = "Previous";
// prevButton.onclick = () => {
// if (currentPage === 1) return;
// currentPage--;
// createTable();
// };
// pagination.appendChild(prevButton);
// const nextButton = document.createElement("button");
// nextButton.innerText = "Next";
// nextButton.onclick = () => {
// if (currentPage === pageCount) return;
// currentPage++;
// createTable();
// };
// pagination.appendChild(nextButton);
};
const applyFilterAndSearch = () => {
const searchValue = searchInput.value.toLowerCase();
const groupFilters = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter:checked')
).map((checkbox) => checkbox.value);
filteredDevices = devices.filter((device) => {
const searchString =
`${device.group} ${device.driverID} ${device.name} ${device.number} ${device.surname} ${device.numberTS} ${device.phone} ${device.mail} ${device.driverCard}`.toLowerCase();
const matchGroup =
groupFilters.length === 0 || groupFilters.includes(device.group);
const matchSearch = !searchValue || searchString.includes(searchValue);
return matchGroup && matchSearch;
});
currentPage = 1;
createTable();
createPagination();
};
const searchInput = document.getElementById("table-search");
searchInput.addEventListener("input", applyFilterAndSearch);
const filterCheckboxes = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter')
);
filterCheckboxes.forEach((checkbox) => {
checkbox.addEventListener("change", applyFilterAndSearch);
});
createTable();
createPagination();

340
static/scripts/table.js Normal file
View File

@ -0,0 +1,340 @@
const devices = [
{
id: "1",
group: "2-device-1",
name: "Трамваи",
plate: "AB1234",
serial: "008803559E",
sim: "1234567890",
channels: 12,
ip: "192.168.0.1",
port: 17891,
},
{
id: "2",
group: "2-device-2",
name: "Электробусы",
plate: "BC2345",
serial: "008803559E",
sim: "2345678901",
channels: 12,
ip: "192.168.0.2",
port: 17891,
},
{
id: "3",
group: "2-device-1",
name: "Трамваи",
plate: "CD3456",
serial: "009800852A",
sim: "3456789012",
channels: 16,
ip: "192.168.0.3",
port: 17891,
},
{
id: "4",
group: "2-device-3",
name: "Троллейбусы",
plate: "DE4567",
serial: "009800858D",
sim: "4567890123",
channels: 12,
ip: "192.168.0.4",
port: 17891,
},
{
id: "5",
group: "2-device-2",
name: "Электробусы",
plate: "EF5678",
serial: "00980084FD",
sim: "5678901234",
channels: 16,
ip: "192.168.0.5",
port: 17891,
},
{
id: "6",
group: "2-device-1",
name: "Трамваи",
plate: "FG6789",
serial: "0088036B7F",
sim: "6789012345",
channels: 16,
ip: "192.168.0.6",
port: 17891,
},
{
id: "7",
group: "2-device-4",
name: "Старые ТС",
plate: "GH7890",
serial: "00880302CD",
sim: "7890123456",
channels: 12,
ip: "192.168.0.7",
port: 17891,
},
{
id: "8",
group: "2-device-4",
name: "Старые ТС",
plate: "HI8901",
serial: "008802A035",
sim: "8901234567",
channels: 12,
ip: "192.168.0.8",
port: 17891,
},
{
id: "9",
group: "1-device-1",
name: "Трамваи",
plate: "IJ9012",
serial: "008802A96A",
sim: "9012345678",
channels: 16,
ip: "192.168.0.9",
port: 17891,
},
{
id: "10",
group: "2-device-4",
name: "Старые ТС",
plate: "КТ32376",
serial: "00880302C7",
sim: "7012345678",
channels: 14,
ip: "192.168.0.10",
port: 17891,
},
{
id: "11",
group: "2-device-3",
name: "Троллейбусы",
plate: "ОА33277",
serial: "008802A035",
sim: "9034234348",
channels: 12,
ip: "192.168.0.11",
port: 17891,
},
{
id: "12",
group: "1-device-2",
name: "Маршрутки",
plate: "КЛ987102",
serial: "009800852A",
sim: "9023345678",
channels: 10,
ip: "192.168.0.12",
port: 17891,
},
{
id: "13",
group: "3-device-1",
name: "Троллейбусы",
plate: "КЛ987102",
serial: "0088036B78",
sim: "9023345678",
channels: 8,
ip: "192.168.0.13",
port: 17891,
},
{
id: "14",
group: "3-device-1",
name: "Маршрутки",
plate: "КЛ987102",
serial: "0088036B7F",
sim: "9023345678",
channels: 8,
ip: "192.168.0.14",
port: 17891,
},
{
id: "15",
group: "1-device-1",
name: "Трамваи",
plate: "КЛ987102",
serial: "008802A96A",
sim: "9023345678",
channels: 16,
ip: "192.168.0.15",
port: 17891,
},
];
// Получаем высоту таблицы и определяем, сколько строк помещается на странице
let currentPage = 1;
let tableHeight = document.getElementById("table-area").offsetHeight;
let rowHeight = 60;
let rowsPerPage = Math.floor(tableHeight / rowHeight) - 2;
let filteredDevices = [...devices];
const createTable = () => {
const table = document.getElementById("deviceTable");
const tbody = table.querySelector("tbody");
// Очищаем таблицу
tbody.innerHTML = "";
// Добавляем строки таблицы
const startIndex = (currentPage - 1) * rowsPerPage;
const endIndex = startIndex + rowsPerPage;
const devicesToDisplay = filteredDevices.slice(startIndex, endIndex);
devicesToDisplay.forEach((device) => {
const row = document.createElement("tr");
// Добавляем чекбокс перед каждым рядом
const checkboxCell = document.createElement("td");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.value = `device-${device.id}`;
checkbox.id = `device-${device.id}`;
const checkboxLabel = document.createElement("label");
checkboxLabel.setAttribute("for", `device-${device.id}`);
const checkboxDiv = document.createElement("div");
checkboxDiv.setAttribute("class", "checkmark");
checkboxLabel.appendChild(checkboxDiv);
checkboxCell.appendChild(checkbox);
checkboxCell.appendChild(checkboxLabel);
row.appendChild(checkboxCell);
// Добавляем ячейки с данными
const name = document.createElement("td");
name.textContent = device.name;
row.appendChild(name);
const plate = document.createElement("td");
plate.textContent = device.plate;
row.appendChild(plate);
const serial = document.createElement("td");
serial.textContent = device.serial;
row.appendChild(serial);
const sim = document.createElement("td");
sim.textContent = device.sim;
row.appendChild(sim);
const channels = document.createElement("td");
channels.textContent = device.channels;
row.appendChild(channels);
const ip = document.createElement("td");
ip.textContent = device.ip;
row.appendChild(ip);
const port = document.createElement("td");
port.textContent = device.port;
row.appendChild(port);
// Добавляем кнопку удаления после каждого ряда
const trashCell = document.createElement("td");
trashCell.setAttribute("class", "optionsCell");
const trashButton = document.createElement("button");
trashButton.setAttribute("class", "trash");
trashButton.value = `delete-device-${device.id}`;
trashButton.id = `delete-device-${device.id}`;
const optionsButton = document.createElement("button");
optionsButton.setAttribute("class", "options");
optionsButton.value = `options-device-${device.id}`;
optionsButton.id = `options-device-${device.id}`;
trashCell.appendChild(optionsButton);
trashCell.appendChild(trashButton);
row.appendChild(trashCell);
tbody.appendChild(row);
});
};
window.addEventListener("resize", function (event) {
tableHeight = document.getElementById("table-area").offsetHeight;
rowHeight = 60;
rowsPerPage = Math.floor(tableHeight / rowHeight) - 2;
createTable();
createPagination();
});
const createPagination = () => {
const count = document.getElementById("count");
count.textContent = `Всего результатов: ${filteredDevices.length}`;
const pagination = document.getElementById("pagination");
pagination.innerHTML = "";
const pageCount = Math.ceil(filteredDevices.length / rowsPerPage);
for (let i = 1; i <= pageCount; i++) {
const pageLink = document.createElement("a");
pageLink.href = "#";
if (i === currentPage) {
document.querySelector("#device-all").checked = false;
pageLink.classList.add("active");
}
pageLink.textContent = i;
pageLink.addEventListener("click", (event) => {
event.preventDefault();
currentPage = i - 1;
currentPage = i;
createTable();
createPagination();
});
pagination.appendChild(pageLink);
}
// var currentPageSpan = document.createElement("span");
// currentPageSpan.textContent = currentPage;
// pagination.appendChild(currentPageSpan);
// Добавляем кнопки "Next" и "Previous"
// const prevButton = document.createElement("button");
// prevButton.innerText = "Previous";
// prevButton.onclick = () => {
// if (currentPage === 1) return;
// currentPage--;
// createTable();
// };
// pagination.appendChild(prevButton);
// const nextButton = document.createElement("button");
// nextButton.innerText = "Next";
// nextButton.onclick = () => {
// if (currentPage === pageCount) return;
// currentPage++;
// createTable();
// };
// pagination.appendChild(nextButton);
};
const applyFilterAndSearch = () => {
const searchValue = searchInput.value.toLowerCase();
const groupFilters = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter:checked')
).map((checkbox) => checkbox.value);
filteredDevices = devices.filter((device) => {
const searchString =
`${device.group} ${device.name} ${device.plate} ${device.number} ${device.serial} ${device.sim} ${device.channels} ${device.ip} ${device.port}`.toLowerCase();
const matchGroup =
groupFilters.length === 0 || groupFilters.includes(device.group);
const matchSearch = !searchValue || searchString.includes(searchValue);
return matchGroup && matchSearch;
});
currentPage = 1;
createTable();
createPagination();
};
const searchInput = document.getElementById("table-search");
searchInput.addEventListener("input", applyFilterAndSearch);
const filterCheckboxes = Array.from(
document.querySelectorAll('input[type="checkbox"].device-filter')
);
filterCheckboxes.forEach((checkbox) => {
checkbox.addEventListener("change", applyFilterAndSearch);
});
createTable();
createPagination();

1570
static/styles/main.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,251 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Устройства</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div class="selected"><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<span>Устройства</span>
</div>
<nav>
<a href="/devices">Список устройств</a>
<a class="selected" href="/devices/drivers">Водители</a>
<a href="/devices/newdevice">Добавить устройство</a>
<a href="/devices/newdriver">Добавить водителя</a>
<a class="update" href="/devices/update">Обновление ПО</a>
</nav>
<section class="bg">
<section class="content">
<section class="for-table">
<section class="organisation">
<h1>Организация</h1>
<ul class="area">
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-1" class="checkbox-input" hidden checked><label for="name-1" class="checkbox-label">Группа 1</label>
<ul class="area-devices" id="devices-1">
<li class="device"><img><input type="checkbox" id="1-device-1" class="checkbox-input device-filter" value="1-device-1" hidden checked><label for="1-device-1" class="checkbox-label"><div class="checkmark"></div>Трамваи</label></li>
<li class="device"><img><input type="checkbox" id="1-device-2" class="checkbox-input device-filter" value="1-device-2" hidden checked><label for="1-device-2" class="checkbox-label"><div class="checkmark"></div>Маршрутки</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-2" class="checkbox-input" hidden checked><label for="name-2" class="checkbox-label">Группа 2</label>
<ul class="area-devices" id="devices-2">
<li class="device"><img><input type="checkbox" id="2-device-1" class="checkbox-input device-filter" value="2-device-1" hidden checked><label for="2-device-1" class="checkbox-label"><div class="checkmark"></div>Трамваи</label></li>
<li class="device"><img><input type="checkbox" id="2-device-2" class="checkbox-input device-filter" value="2-device-2" hidden checked><label for="2-device-2" class="checkbox-label"><div class="checkmark"></div>Электробусы</label></li>
<li class="device"><img><input type="checkbox" id="2-device-3" class="checkbox-input device-filter" value="2-device-3" hidden checked><label for="2-device-3" class="checkbox-label"><div class="checkmark"></div>Троллейбусы</label></li>
<li class="device"><img><input type="checkbox" id="2-device-4" class="checkbox-input device-filter" value="2-device-4" hidden checked><label for="2-device-4" class="checkbox-label"><div class="checkmark"></div>Старые ТС</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-3" class="checkbox-input" hidden checked><label for="name-3" class="checkbox-label">Другое</label>
<ul class="area-devices" id="devices-3">
<li class="device"><img><input type="checkbox" id="3-device-1" class="checkbox-input device-filter" value="3-device-1" hidden checked><label for="3-device-1" class="checkbox-label"><div class="checkmark"></div>Маршрутки</label></li>
</ul>
</li>
</ul>
</section>
<section id="table-area" class="table">
<h1>Список водителей</h1>
<input id="table-search" class="search" type="text" placeholder="Поиск">
<table id="deviceTable">
<thead>
<tr>
<th><input id="device-all" type="checkbox"><label for="device-all"><div class="checkmark"></div></label></th>
<th>ID</th>
<th>Имя</th>
<th>Фамилия</th>
<th>Номер ТС</th>
<th>Номер телефона</th>
<th>Почта</th>
<th>Карта водителя</th>
<th><button id="delete-device-all" value="delete-device-all" class="trash"></button></th>
</tr>
</thead>
<tbody>
<!-- Сюда будут добавляться строки таблицы -->
</tbody>
</table>
</section>
<div id="count">
<!-- Сюда добавится итоговое количество результатов -->
</div>
<div id="pagination">
<!-- Сюда будут добавляться ссылки для переключения между страницами -->
</div>
</section>
</section>
</section>
</section>
<script src="../scripts/table-drivers.js"></script>
<script src="../scripts/jquery.min.js"></script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
const checkboxes = document.querySelectorAll('.organisation .checkbox-input');
checkboxes.forEach((checkbox) => {
applyFilterAndSearch();
checkbox.addEventListener('change', function() {
document.querySelector('#device-all').checked = false;
applyFilterAndSearch();
const devices = this.parentNode.querySelector('.area-devices');
if (this.checked) {
devices.style.display = 'block';
// Активируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = true;
applyFilterAndSearch();
});
} else {
devices.style.display = 'none';
applyFilterAndSearch();
// Деактивируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
}
// Деактивируем дочерние чекбоксы, если родительский чекбокс не выбран
if (!this.checked) {
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
devices.style.display = 'none';
}
});
});
</script>
<script>
var table = document.querySelector('#deviceTable');
var tableCheckboxAll = table.querySelector('#device-all');
var tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
tableCheckboxAll.addEventListener('click', function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
if (tableCheckboxAll.checked) {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = true;
});
} else {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = false;
});
}
});
$('#deviceTable').click( function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
for (var i = 0; i < tableCheckboxes.length; i++) {
tableCheckboxes[i].addEventListener('click', function(event) {
for (var j = 0; j < tableCheckboxes.length; j++) {
if (!tableCheckboxes[j].checked || tableCheckboxes[j].disabled) {
tableCheckboxAll.checked = false;
return;
}
}
tableCheckboxAll.checked = true;
});
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,251 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Устройства</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div class="selected"><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<span>Устройства</span>
</div>
<nav>
<a class="selected" href="/devices">Список устройств</a>
<a href="/devices/drivers">Водители</a>
<a href="/devices/newdevice">Добавить устройство</a>
<a href="/devices/newdriver">Добавить водителя</a>
<a class="update" href="/devices/update">Обновление ПО</a>
</nav>
<section class="bg">
<section class="content">
<section class="for-table">
<section class="organisation">
<h1>Организация</h1>
<ul class="area">
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-1" class="checkbox-input" hidden checked><label for="name-1" class="checkbox-label">Группа 1</label>
<ul class="area-devices" id="devices-1">
<li class="device"><img><input type="checkbox" id="1-device-1" class="checkbox-input device-filter" value="1-device-1" hidden checked><label for="1-device-1" class="checkbox-label"><div class="checkmark"></div>Трамваи</label></li>
<li class="device"><img><input type="checkbox" id="1-device-2" class="checkbox-input device-filter" value="1-device-2" hidden checked><label for="1-device-2" class="checkbox-label"><div class="checkmark"></div>Маршрутки</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-2" class="checkbox-input" hidden checked><label for="name-2" class="checkbox-label">Группа 2</label>
<ul class="area-devices" id="devices-2">
<li class="device"><img><input type="checkbox" id="2-device-1" class="checkbox-input device-filter" value="2-device-1" hidden checked><label for="2-device-1" class="checkbox-label"><div class="checkmark"></div>Трамваи</label></li>
<li class="device"><img><input type="checkbox" id="2-device-2" class="checkbox-input device-filter" value="2-device-2" hidden checked><label for="2-device-2" class="checkbox-label"><div class="checkmark"></div>Электробусы</label></li>
<li class="device"><img><input type="checkbox" id="2-device-3" class="checkbox-input device-filter" value="2-device-3" hidden checked><label for="2-device-3" class="checkbox-label"><div class="checkmark"></div>Троллейбусы</label></li>
<li class="device"><img><input type="checkbox" id="2-device-4" class="checkbox-input device-filter" value="2-device-4" hidden checked><label for="2-device-4" class="checkbox-label"><div class="checkmark"></div>Старые ТС</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-3" class="checkbox-input" hidden checked><label for="name-3" class="checkbox-label">Другое</label>
<ul class="area-devices" id="devices-3">
<li class="device"><img><input type="checkbox" id="3-device-1" class="checkbox-input device-filter" value="3-device-1" hidden checked><label for="3-device-1" class="checkbox-label"><div class="checkmark"></div>Маршрутки</label></li>
</ul>
</li>
</ul>
</section>
<section id="table-area" class="table">
<h1>Список устройств</h1>
<input id="table-search" class="search" type="text" placeholder="Поиск">
<table id="deviceTable">
<thead>
<tr>
<th><input id="device-all" type="checkbox"><label for="device-all"><div class="checkmark"></div></label></th>
<th>Группа</th>
<th>Номерной знак</th>
<th>Серийный номер</th>
<th>Номер SIM-карты</th>
<th>Кол-во каналов</th>
<th>IP-адрес</th>
<th>Порт</th>
<th><button id="delete-device-all" value="delete-device-all" class="trash"></button></th>
</tr>
</thead>
<tbody>
<!-- Сюда будут добавляться строки таблицы -->
</tbody>
</table>
</section>
<div id="count">
<!-- Сюда добавится итоговое количество результатов -->
</div>
<div id="pagination">
<!-- Сюда будут добавляться ссылки для переключения между страницами -->
</div>
</section>
</section>
</section>
</section>
<script src="../scripts/table.js"></script>
<script src="../scripts/jquery.min.js"></script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
const checkboxes = document.querySelectorAll('.organisation .checkbox-input');
checkboxes.forEach((checkbox) => {
applyFilterAndSearch();
checkbox.addEventListener('change', function() {
document.querySelector('#device-all').checked = false;
applyFilterAndSearch();
const devices = this.parentNode.querySelector('.area-devices');
if (this.checked) {
devices.style.display = 'block';
// Активируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = true;
applyFilterAndSearch();
});
} else {
devices.style.display = 'none';
applyFilterAndSearch();
// Деактивируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
}
// Деактивируем дочерние чекбоксы, если родительский чекбокс не выбран
if (!this.checked) {
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
devices.style.display = 'none';
}
});
});
</script>
<script>
var table = document.querySelector('#deviceTable');
var tableCheckboxAll = table.querySelector('#device-all');
var tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
tableCheckboxAll.addEventListener('click', function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
if (tableCheckboxAll.checked) {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = true;
});
} else {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = false;
});
}
});
$('#deviceTable').click( function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
for (var i = 0; i < tableCheckboxes.length; i++) {
tableCheckboxes[i].addEventListener('click', function(event) {
for (var j = 0; j < tableCheckboxes.length; j++) {
if (!tableCheckboxes[j].checked || tableCheckboxes[j].disabled) {
tableCheckboxAll.checked = false;
return;
}
}
tableCheckboxAll.checked = true;
});
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,490 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Устройства</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div class="selected"><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<span>Устройства</span>
</div>
<nav>
<a href="/devices">Список устройств</a>
<a href="/devices/drivers">Водители</a>
<a class="selected" href="/devices/newdevice">Добавить устройство</a>
<a href="/devices/newdriver">Добавить водителя</a>
<a class="update" href="/devices/update">Обновление ПО</a>
</nav>
<section class="bg">
<section class="content">
<section class="for-new">
<section class="stages">
<input name="newStage" type="radio" value="details" id="stage-details" checked><label for="stage-details">Детали</label>
<div class="vertical-line"></div>
<input name="newStage" type="radio" value="sim" id="stage-sim"><label for="stage-sim">SIM - Карта</label>
<div class="vertical-line"></div>
<input name="newStage" type="radio" value="ts" id="stage-ts"><label for="stage-ts">Транспортное средство</label>
<div class="vertical-line"></div>
<input name="newStage" type="radio" value="equipment" id="stage-equipment"><label for="stage-equipment">Оборудование</label>
</section>
</section>
<section id="add-new-container" class="add-new">
<form>
<div id="details" class="new-parameters active">
<h1>Детали устройства</h1>
<h2>Сперва самое необходимое</h2>
<div class="horizontal-line"></div>
<div class="parameters-inputs">
<div class="parameters-input">
<label for="parameters-plate">Номерной знак<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="plateNumber" type="text" id="parameters-plate" placeholder="Номер номерного знака" required>
</div>
<div class="parameters-input">
<label for="parameters-plateColor">Цвет номерного знака<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<select name="plateColor" id="parameters-plateColor">
<option value="blue">Синий</option>
<option value="yellow">Жёлтый</option>
<option value="white">Белый</option>
</select>
</div>
<div class="parameters-input">
<label for="parameters-serial">Серийный номер<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="serialNumber" type="text" id="parameters-serial" placeholder="Серийный номер устройства" required>
</div>
<div class="parameters-input">
<label for="parameters-channels">Количество каналов<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="channelsAmount" type="text" id="parameters-channels" placeholder="Кол-во каналов устройства" required>
</div>
<div class="parameters-input">
<label for="parameters-protocol">Протокол<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<select name="connectionProtocol" id="parameters-protocol">
<option value="N9M">N9M</option>
</select>
</div>
<div class="parameters-input">
<label for="parameters-ip">IP-адрес<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="IPAddress" type="text" id="parameters-ip" placeholder="IP-адрес сервера" required>
</div>
<div class="parameters-input">
<label for="parameters-group">Группа<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="deviceGroup" type="text" id="parameters-group" placeholder="Название группы" required>
</div>
<div class="parameters-input">
<label for="parameters-port">Порт<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="serverPort" type="text" id="parameters-port" placeholder="Порт сервера" required>
</div>
</div>
<div class="horizontal-line"></div>
<button id="continue-details" type="button">Продолжить</button>
</div>
<div id="sim" class="new-parameters">
<h1>Настройки SIM-карты</h1>
<h2>Для связи с устройством</h2>
<div class="horizontal-line"></div>
<div class="parameters-inputs">
<div class="parameters-input">
<label for="parameters-sim">Номер SIM-карты<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="sumNumber" type="text" id="parameters-sim" placeholder="Номер SIM-карты" required>
</div>
<div class="parameters-input">
<label for="parameters-sim-imei">IMEI<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="simIMEI" type="text" id="parameters-sim-imei" placeholder="IMEI SIM-карты" required>
</div>
<div class="parameters-input">
<label for="parameters-sim-imsi">IMSI<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="simIMSI" type="text" id="parameters-sim-imsi" placeholder="IMSI SIM-карты" required>
</div>
<div class="parameters-input">
<label for="parameters-sim-module">Тип сетевого модуля<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<select name="simModule" id="parameters-sim-module">
<option value="GPRS">GPRS</option>
<option value="CDMA">CDMA</option>
<option value="EVDO">EVDO</option>
<option value="WCDMA">WCDMA</option>
<option value="EDGE">EDGE</option>
<option value="TDSCDMA">TDSCDMA</option>
<option value="LTE-TDD">LTE-TDD</option>
<option value="LTE-FDD">LTE-FDD</option>
</select>
</div>
</div>
<div class="horizontal-line"></div>
<button id="continue-sim" type="button">Продолжить</button>
</div>
<div id="ts" class="new-parameters">
<h1>Детали транспортного средства</h1>
<h2>Технические характеристики и не только</h2>
<div class="horizontal-line"></div>
<div class="parameters-inputs">
<div class="parameters-input">
<label for="parameters-trasnsport-type">Тип автомобиля<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<select name="transportType" id="parameters-trasnsport-type" onchange="truncateText(this)">
<option value="1">Пассажирский подвижной состав</option>
<option value="2">Большой автобус</option>
<option value="3">Средний автобус</option>
<option value="4">Микроавтобус</option>
<option value="5">Лимузин</option>
<option value="6">Большой спальный автобус</option>
<option value="7">Спальный автобус среднего размера</option>
<option value="8">Обычный грузовик</option>
<option value="9">Большой обычный грузовик</option>
<option value="10">Среднегабаритный обычный грузовик</option>
<option value="11">Маленький обычный грузовик</option>
<option value="12">Специальная транспортировочная машина</option>
<option value="13">Контейнерная тележка</option>
<option value="14">Большой транспортировочный автомобиль</option>
<option value="15">Изометрический вагон</option>
<option value="16">Спецтехника для перевозки грузовых автомобилей</option>
<option value="17">Танкер</option>
<option value="18">Тягач</option>
<option value="19">Прицеп</option>
<option value="20">Транспортер</option>
<option value="21">Другая спецтехника</option>
<option value="22">Автомобиль для перевозки опасных грузов</option>
<option value="23">Сельскохозяйственная машина</option>
</select>
</div>
<div class="parameters-input">
<label for="parameters-trasnsport-factory">Номер завода<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportFactory" type="text" id="parameters-trasnsport-factory" placeholder="Номер завода ТС" required>
</div>
<div class="parameters-input">
<label for="parameters-transport-strength">Несущая способность<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportStrength" type="text" id="parameters-transport-strength" placeholder="Несущая способность (тонны)" required>
</div>
<div class="parameters-input">
<label for="parameters-transport-engine">Номер двигателя<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportEngine" type="text" id="parameters-transport-engine" placeholder="Номер двигателя ТС" required>
</div>
<div class="parameters-input">
<label for="parameters-transport-stanina">Номер станины<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportStanina" type="text" id="parameters-transport-stanina" placeholder="Номер станины ТС" required>
</div>
<div class="parameters-input">
<label for="parameters-trasnsport-fuel">Тип топливного масла<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<select name="transportFuel" id="parameters-trasnsport-fuel">
<option value="gasoline">Бензин</option>
<option value="diesel">Дизельное топливо</option>
<option value="naturalGas">Природный газ</option>
<option value="liquefiedGas">Сжиженный газ</option>
<option value="electric">Электрическое</option>
<option value="other">Прочие</option>
</select>
</div>
<div class="parameters-input">
<div class="parameters-transport-certificate">
<label for="parameters-transport-certificate">Свид-ство о дорожной перевозке<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportCertificate" type="text" id="parameters-transport-certificate" placeholder="Номер свидетельства" required>
</div>
</div>
<div class="parameters-input">
<div class="pparameters-trasnsport-category">
<label for="parameters-trasnsport-category">Техническая категория<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<select name="transportCategory" id="parameters-trasnsport-category">
<option value="1">Категория 1</option>
<option value="2">Категория 2</option>
<option value="3">Категория 3</option>
<option value="other">Не достает стандарта</option>
</select>
</div>
</div>
<div class="parameters-input">
<label for="parameters-transport-expire">Срок действия<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportExpire" type="date" id="parameters-transport-expire" required>
</div>
<div class="parameters-input">
<label for="parameters-transport-consumption">Расход топлива на 100 км<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportConsumption" type="text" id="parameters-transport-consumption" placeholder="Расход топлива в литрах" required>
</div>
<div class="parameters-input">
<label for="parameters-transport-province">Провинция<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportProvince" type="text" id="parameters-transport-province" placeholder="Провинция" required>
</div>
<div class="parameters-input">
<label for="parameters-transport-city">Город<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="transportCity" type="text" id="parameters-transport-city" placeholder="Город" required>
</div>
</div>
<div class="horizontal-line"></div>
<button id="continue-ts" type="button">Продолжить</button>
</div>
<div id="equipment" class="new-parameters">
<h1>Информация о оборудовании</h1>
<h2>Технические моменты</h2>
<div class="horizontal-line"></div>
<div class="parameters-inputs">
<div class="parameters-input">
<label for="parameters-equipment-name">Имя устройства<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="equipmentName" type="text" id="parameters-equipment-name" placeholder="Имя пользовательского устройства" required>
</div>
<div class="parameters-input">
<label for="parameters-equipment-password">Пароль устройства<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="equipmentPassword" type="text" id="parameters-equipment-password" placeholder="Пароль устройства" required>
</div>
<div class="parameters-input">
<label for="parameters-equipment-number">Номер партии<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="equipmentNumber" type="text" id="parameters-equipment-number" placeholder="Заводской номер партии" required>
</div>
<div class="parameters-input">
<label for="parameters-equipment-released">Дата выпуска<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="equipmentReleased" type="date" id="parameters-equipment-released" required>
</div>
<div class="parameters-input">
<label for="parameters-device-installer">Установщик<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="equipmentInstaller" type="text" id="parameters-device-installer" placeholder="ФИО установщика" required>
</div>
<div class="parameters-input">
<label for="parameters-equipment-installed">Дата монтажа<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="equipmentInstalled" type="date" id="parameters-equipment-installed" required>
</div>
<label for="parameters-device-description">Внешнее описание<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="equipmentDescription" type="text" id="parameters-device-description" placeholder="Внешнее описание " required>
</div>
<div class="horizontal-line"></div>
<button>Сохранить</button>
</div>
</form>
</section>
</section>
</section>
</section>
<script src="../scripts/jquery.min.js"></script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
$("#continue-details").click(function () {
document.getElementById("stage-sim").checked = true;
});
$("#continue-sim").click(function () {
document.getElementById("stage-ts").checked = true;
});
$("#continue-ts").click(function () {
document.getElementById("stage-equipment").checked = true;
});
</script>
<script>
const container = document.getElementById('new-parameters');
const content1 = document.getElementById('details');
const content2 = document.getElementById('sim');
const content3 = document.getElementById('ts');
const content4 = document.getElementById('equipment');
const btn1 = document.getElementById('continue-details');
const btn2 = document.getElementById('continue-sim');
const btn3 = document.getElementById('continue-ts');
const radioButtons = document.querySelectorAll('input[type="radio"][name="newStage"]');
const duration = 100;
let activeContent = content1;
function switchContent(newContent) {
fadeOut(activeContent, () => {
fadeIn(newContent);
activeContent = newContent;
});
}
function fadeIn(element) {
element.style.opacity = 0;
element.style.display = 'block';
let start = performance.now();
function animate(time) {
let timeFraction = (time - start) / duration;
if (timeFraction > 1) {
element.style.opacity = 1;
} else {
element.style.opacity = timeFraction;
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
function fadeOut(element, callback) {
element.style.opacity = 1;
let start = performance.now();
function animate(time) {
let timeFraction = (time - start) / duration;
if (timeFraction > 1) {
element.style.opacity = 0;
element.style.display = 'none';
if (callback) {
callback();
}
} else {
element.style.opacity = 1 - timeFraction;
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
btn1.addEventListener('click', () => {
if (activeContent === content1) {
switchContent(content2);
} else {
switchContent(content1);
}
});
btn2.addEventListener('click', () => {
if (activeContent === content2) {
switchContent(content3);
} else {
switchContent(content2);
}
});
btn3.addEventListener('click', () => {
if (activeContent === content3) {
switchContent(content4);
} else {
switchContent(content3);
}
});
for (let radioButton of radioButtons) {
radioButton.addEventListener('change', () => {
if (radioButton.value === 'details') {
switchContent(content1);
} else if (radioButton.value === 'sim') {
switchContent(content2);
} else if (radioButton.value === 'ts') {
switchContent(content3);
} else if (radioButton.value === 'equipment') {
switchContent(content4);
}
});
}
</script>
<script>
function truncateText(select) {
var maxLength = 30;
var option = select.options[select.selectedIndex];
if (option.text.length > maxLength) {
option.text = option.text.substring(0, maxLength) + '...';
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,295 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Устройства</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div class="selected"><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<span>Устройства</span>
</div>
<nav>
<a href="/devices">Список устройств</a>
<a href="/devices/drivers">Водители</a>
<a href="/devices/newdevice">Добавить устройство</a>
<a class="selected" href="/devices/newdriver">Добавить водителя</a>
<a class="update" href="/devices/update">Обновление ПО</a>
</nav>
<section class="bg">
<section class="content">
<section class="for-new">
<section class="stages">
<input name="newStage" type="radio" value="main" id="stage-main" checked><label for="stage-main">Основная информация</label>
<div class="vertical-line"></div>
<input name="newStage" type="radio" value="details" id="stage-details"><label for="stage-details">Детали</label>
</section>
</section>
<section id="add-new-container" class="add-new">
<form>
<div id="main" class="new-parameters drivers active">
<h1>Основная информация</h1>
<h2>Сперва самое необходимое</h2>
<div class="horizontal-line"></div>
<label for="parameters-plate">Фотография<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<div id="upload-photo" class="upload-input">
<img src="../img/upload.svg">
<span class="upload-text">Загрузить фотографию водителя</span>
<span class="upload-description">PNG, JPG (макс 20 мб)</span>
</div>
<input id="input-upload-photo" type="file" name="upload-file" style="display: none;">
<div class="parameters-inputs">
<label for="driver-name">Имя<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="driverName" type="text" id="driver-name" placeholder="Имя водителя" required>
<label for="driver-surname">Фамилия<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="driverSurname" type="text" id="driver-surname" placeholder="Фамилия водителя" required>
<label for="driver-card">Карта водителя<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="driverCard" type="text" id="driver-card" placeholder="Номер карты водителя" required>
</div>
<div class="horizontal-line"></div>
<button id="continue-main" type="button">Продолжить</button>
</div>
<div id="details" class="new-parameters drivers">
<h1>Детальная информация</h1>
<h2>Для удобства в идентификации</h2>
<div class="horizontal-line"></div>
<div class="parameters-inputs">
<label for="driver-gender">Пол<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<select name="driverGender" id="driver-gender">
<option value="male">Мужской</option>
<option value="female">Женский</option>
</select>
<label for="driver-license">Водительское удостоверение<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="driverLicense" type="text" id="driver-license" placeholder="Номер водительского удостоверения" required>
<label for="driver-passport">Удостоверение личности<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="driverPassport" type="text" id="driverPassport" placeholder="Номер удостоверения личности" required>
<label for="driver-phone">Мобильный телефон<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="driverPhone" type="text" id="driver-phone" placeholder="Номер мобильного телефона" required>
<label for="driver-description">Примечание<span style="color: rgba(255, 69, 58, 1);">*</span></label>
<input name="driverDescription" type="text" id="driver-description" placeholder="Примечание" required>
</div>
<div class="horizontal-line"></div>
<button>Сохранить</button>
</div>
</form>
</section>
</section>
</section>
</section>
<script src="../scripts/jquery.min.js"></script>
<script>
const fileSelect = document.getElementById("upload-photo");
const fileElem = document.getElementById("input-upload-photo");
fileSelect.addEventListener(
"click",
(e) => {
if (fileElem) {
fileElem.click();
}
},
false
);
</script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
$("#continue-main").click(function () {
document.getElementById("stage-details").checked = true;
});
</script>
<script>
const container = document.getElementById('new-parameters');
const content1 = document.getElementById('main');
const content2 = document.getElementById('details');
const btn1 = document.getElementById('continue-main');
const radioButtons = document.querySelectorAll('input[type="radio"][name="newStage"]');
const duration = 100;
let activeContent = content1;
function switchContent(newContent) {
fadeOut(activeContent, () => {
fadeIn(newContent);
activeContent = newContent;
});
}
function fadeIn(element) {
element.style.opacity = 0;
element.style.display = 'block';
let start = performance.now();
function animate(time) {
let timeFraction = (time - start) / duration;
if (timeFraction > 1) {
element.style.opacity = 1;
} else {
element.style.opacity = timeFraction;
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
function fadeOut(element, callback) {
element.style.opacity = 1;
let start = performance.now();
function animate(time) {
let timeFraction = (time - start) / duration;
if (timeFraction > 1) {
element.style.opacity = 0;
element.style.display = 'none';
if (callback) {
callback();
}
} else {
element.style.opacity = 1 - timeFraction;
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
btn1.addEventListener('click', () => {
if (activeContent === content1) {
switchContent(content2);
} else {
switchContent(content1);
}
});
for (let radioButton of radioButtons) {
radioButton.addEventListener('change', () => {
if (radioButton.value === 'main') {
switchContent(content1);
} else if (radioButton.value === 'details') {
switchContent(content2);
}
});
}
</script>
<script>
function truncateText(select) {
var maxLength = 30;
var option = select.options[select.selectedIndex];
if (option.text.length > maxLength) {
option.text = option.text.substring(0, maxLength) + '...';
}
}
</script>
</body>
</html>

106
static/templates/index.html Normal file
View File

@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, introductory scale=1">
<title>Панель управления</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<div class="page-transition"></div>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div class="selected"><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<img src="../img/cars.svg"><span>Сводка по 351 ТС</span>
</div>
<section class="bg">
<section class="content">
<div class="graph left">
<h1>Предупреждения</h1>
<span>10 д</span>
<div class="chart">
<canvas id="chart-warnings"></canvas>
</div>
</div>
<div class="graph right">
<h1>Позиционирование</h1>
<span>10 д</span>
<div class="chart">
<canvas id="chart-positions"></canvas>
</div>
</div>
</section>
</section>
</section>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="../scripts/graphs.js"></script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
</body>
</html>

420
static/templates/live.html Normal file
View File

@ -0,0 +1,420 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Трансляция</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div class="selected"><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<span>Прямые трансляции</span>
</div>
<nav>
<a class="selected" href="/live">Трансляции</a>
</nav>
<section class="bg">
<section class="content">
<section class="for-table">
<section class="organisation">
<h1>Организация</h1>
<ul class="area">
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-1" class="checkbox-input" hidden checked><label for="name-1" class="checkbox-label">Группа 1</label>
<ul class="area-devices" id="devices-1">
<li class="device"><img><input type="checkbox" id="0001" class="checkbox-input device-filter" value="0001" hidden checked><label for="0001" class="checkbox-label"><div class="checkmark"></div>0001</label></li>
<li class="device"><img><input type="checkbox" id="0002" class="checkbox-input device-filter" value="0002" hidden checked><label for="0002" class="checkbox-label"><div class="checkmark"></div>0002</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-2" class="checkbox-input" hidden checked><label for="name-2" class="checkbox-label">Группа 2</label>
<ul class="area-devices" id="devices-2">
<li class="device"><img><input type="checkbox" id="0003" class="checkbox-input device-filter" value="0003" hidden checked><label for="0003" class="checkbox-label"><div class="checkmark"></div>0003</label></li>
<li class="device"><img><input type="checkbox" id="0004" class="checkbox-input device-filter" value="0004" hidden checked><label for="0004" class="checkbox-label"><div class="checkmark"></div>0004</label></li>
<li class="device"><img><input type="checkbox" id="0005" class="checkbox-input device-filter" value="0005" hidden checked><label for="0005" class="checkbox-label"><div class="checkmark"></div>0005</label></li>
<li class="device"><img><input type="checkbox" id="0006" class="checkbox-input device-filter" value="0006" hidden checked><label for="0006" class="checkbox-label"><div class="checkmark"></div>0006</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-3" class="checkbox-input" hidden checked><label for="name-3" class="checkbox-label">Другое</label>
<ul class="area-devices" id="devices-3">
<li class="device"><img><input type="checkbox" id="0007" class="checkbox-input device-filter" value="0007" hidden checked><label for="0007" class="checkbox-label"><div class="checkmark"></div>0007</label></li>
</ul>
</li>
</ul>
</section>
<section class="table">
<div id="signals-list" class="signals-list">
<h1>Сигналы ТС - 17</h1>
<svg id="left-slider" class="left-slider" xmlns="http://www.w3.org/2000/svg" width="19" height="19" fill="none" viewBox="0 0 11 19">
<path fill="#000" fill-opacity=".75" d="M0 9.495c0 .273.101.514.315.722l8.92 8.477a.981.981 0 0 0 .73.295c.585 0 1.035-.427 1.035-.995 0-.285-.124-.525-.304-.711L2.508 9.495l8.188-7.789c.18-.186.304-.437.304-.71C11 .425 10.55 0 9.965 0c-.292 0-.54.098-.73.284L.314 8.773A.955.955 0 0 0 0 9.495Z"/>
</svg>
<input class="search" type="text" placeholder="Поиск">
<ul>
<li>
<input type="radio" name="signal" id="signal-1" hidden checked>
<label for="signal-1">
<h2>Водитель отвлекся</h2>
<span>ID 346</span>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
</svg>11-03-2023 12:44</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
</svg>59.956626,30.234408</p>
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
</svg>Виталий Гаспарян</p>
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
</svg>+7 999 123 45 67</p>
</label>
</li>
<li>
<input type="radio" name="signal" id="signal-2" hidden>
<label for="signal-2">
<h2>Усталость</h2>
<span>ID 352</span>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
</svg>11-03-2023 11:07</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
</svg>59.878256,30.31962</p>
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
</svg>Михаил Гукасян</p>
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
</svg>+7 909 133 55 67</p>
</label>
</li>
<li>
<input type="radio" name="signal" id="signal-3" hidden>
<label for="signal-3">
<h2>Разговор по телефону</h2>
<span>ID 349</span>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
</svg>11-03-2023 11:17</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
</svg>59.959926,30.42224</p>
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
</svg>Валерий Сараев</p>
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
</svg>+7 909 123 45 67</p>
</label>
</li>
<li>
<input type="radio" name="signal" id="signal-4" hidden>
<label for="signal-4">
<h2>Курение за рулём</h2>
<span>ID 347</span>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
</svg>11-03-2023 10:06</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
</svg>59.956626,30.234408</p>
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
</svg>Екатерина Миненко</p>
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
</svg>+7 909 133 55 67</p>
</label>
</li>
<!-- <li>
<input type="radio" name="signal" id="signal-5" hidden>
<label for="signal-5">
<h2>Водитель отвлекся</h2>
<span>ID 346</span>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
</svg>11-03-2023 12:44</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
</svg>59.956626,30.234408</p>
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
</svg>Виталий Гаспарян</p>
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
</svg>+7 999 123 45 67</p>
</label>
</li>
<li>
<input type="radio" name="signal" id="signal-6" hidden>
<label for="signal-6">
<h2>Водитель отвлекся</h2>
<span>ID 346</span>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
</svg>11-03-2023 12:44</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
</svg>59.956626,30.234408</p>
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
</svg>Виталий Гаспарян</p>
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
</svg>+7 999 123 45 67</p>
</label>
</li>
<li>
<input type="radio" name="signal" id="signal-7" hidden>
<label for="signal-7">
<h2>Водитель отвлекся</h2>
<span>ID 346</span>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
</svg>11-03-2023 12:44</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
</svg>59.956626,30.234408</p>
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
</svg>Виталий Гаспарян</p>
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
</svg>+7 999 123 45 67</p>
</label>
</li> -->
</ul>
</div>
<div class="map">
<div id="map"></div>
</div>
</section>
</section>
</section>
</section>
</section>
<script src="../scripts/table-reports.js"></script>
<script src="../scripts/jquery.min.js"></script>
<!-- <style>
#map {
height: 100%;
width: 100%;
display: inline-block;
float: right;
}
</style> -->
<script src="https://cdn.jsdelivr.net/npm/leaflet/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet-routing-machine/dist/leaflet-routing-machine.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-routing-machine/dist/leaflet-routing-machine.css" />
<script>
function initMap() {
// Координаты начальной точки
var startPoint = L.latLng(55.769042, 37.647840);
// Координаты конечной точки
var endPoint = L.latLng(55.769723, 37.659341);
// Создание объекта карты
var map = L.map('map').setView(startPoint, 12);
// Добавление слоя OpenStreetMap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Прокладка маршрута
var control = L.Routing.control({
waypoints: [
startPoint,
endPoint
],
routeWhileDragging: true,
show: false,
}).addTo(map);
// Удаление кнопки виджета маршрута
document.querySelector('.leaflet-routing-container').style.display = 'none';
}
</script>
<script>initMap();</script>
<script>
const panel = document.getElementById('signals-list');
const slider = document.getElementById('left-slider');
slider.addEventListener('click', () => {
panel.classList.toggle('hide');
});
</script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
const checkboxes = document.querySelectorAll('.organisation .checkbox-input');
checkboxes.forEach((checkbox) => {
applyFilterAndSearch();
checkbox.addEventListener('change', function() {
document.querySelector('#device-all').checked = false;
applyFilterAndSearch();
const devices = this.parentNode.querySelector('.area-devices');
if (this.checked) {
devices.style.display = 'block';
// Активируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = true;
applyFilterAndSearch();
});
} else {
devices.style.display = 'none';
applyFilterAndSearch();
// Деактивируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
}
// Деактивируем дочерние чекбоксы, если родительский чекбокс не выбран
if (!this.checked) {
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
devices.style.display = 'none';
}
});
});
</script>
<script>
var table = document.querySelector('#deviceTable');
var tableCheckboxAll = table.querySelector('#device-all');
var tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
tableCheckboxAll.addEventListener('click', function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
if (tableCheckboxAll.checked) {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = true;
});
} else {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = false;
});
}
});
$('#deviceTable').click( function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
for (var i = 0; i < tableCheckboxes.length; i++) {
tableCheckboxes[i].addEventListener('click', function(event) {
for (var j = 0; j < tableCheckboxes.length; j++) {
if (!tableCheckboxes[j].checked || tableCheckboxes[j].disabled) {
tableCheckboxAll.checked = false;
return;
}
}
tableCheckboxAll.checked = true;
});
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Авторизация</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<section class="form right">
<form enctype="multipart/form-data" method="post" action="/postsignin">
<h1 style="margin-bottom: 40px;">Добро пожаловать в Аргус</h1>
<label for="login">Логин<span>*</span></label>
<input title="Введите логин" placeholder="Введите логин" name="login" type="text" required>
<label for="password">Пароль<span>*</span></label>
<input title="Введите пароль" placeholder="Введите пароль" name="password" type="password" required>
<button onclick="window.location.href='/'" type="button">Войти</button>
</form>
</section>
<video class="animation left" autoplay muted loop>
<source src="../img/traffic.mp4" type="video/mp4">
</video>
<span class="copyright left"><a href="https://dribbble.com/shots/15608015-Traffic">Видеоматериал создан Igor Kozak на Dribbble</a></span>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Установка</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<section class="form left">
<form enctype="multipart/form-data" method="post" action="/postsignin">
<h1>Добро пожаловать в Аргус</h1>
<h2>Приступим к созданию организации</h2>
<label for="name">Название<span>*</span></label>
<input title="Название вашей организации" placeholder="Название вашей организации" name="name" type="text" required>
<label for="login">Логин администратора<span>*</span></label>
<input title="Логин для панели управления" placeholder="Логин для панели управления" name="login" type="text" required>
<label for="password">Пароль администратора<span>*</span></label>
<input title="Пароль для панели управления" placeholder="Пароль для панели управления" name="password" type="password" required>
<label for="repassword">Подтверждение<span>*</span></label>
<input title="Повторите пароль" placeholder="Повторите пароль" name="repassword" type="password" required>
<button onclick="window.location.href='/'" type="button">Установить</button>
</form>
</section>
<video class="animation right" autoplay muted loop>
<source src="../img/traffic.mp4" type="video/mp4">
</video>
<span class="copyright right"><a href="https://dribbble.com/shots/15608015-Traffic">Видеоматериал создан Igor Kozak на Dribbble</a></span>
</body>
</html>

View File

@ -0,0 +1,376 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Отчёты</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div class="selected"><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<span>Отчёты</span>
</div>
<nav>
<a class="return-name" href="/reports">
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="17" fill="none" viewBox="0 0 10 17">
<g clip-path="url(#a)">
<path fill="#8086F9" d="M0 8.477a.88.88 0 0 0 .273.644l7.745 7.568a.84.84 0 0 0 .634.264c.508 0 .899-.38.899-.889a.917.917 0 0 0-.264-.634l-7.11-6.953 7.11-6.954A.936.936 0 0 0 9.551.89.876.876 0 0 0 8.652 0a.869.869 0 0 0-.634.254L.273 7.832A.864.864 0 0 0 0 8.477Z"/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h9.551v16.963H0z"/>
</clipPath>
</defs>
</svg>
Вернуться</a>
</nav>
<section class="bg">
<section class="content">
<section class="for-table">
<section class="report">
<div class="report-top">
<h1>Список предупреждений</h1>
<div class="export">
<img src="../img/share.svg">
<span>Экспорт</span>
</div>
</div>
<div class="report-left">
<div class="report-info">
<ul>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 19 17">
<path fill="#000" fill-opacity=".75" d="M1.632 16.172c.741 0 1.203-.473 1.203-1.246V1.573C2.835.8 2.373.327 1.632.327.88.327.429.8.429 1.573v13.353c0 .773.45 1.246 1.203 1.246ZM6.896 16h4.264c4.62 0 7.337-2.879 7.337-7.777 0-4.888-2.728-7.724-7.337-7.724H6.896c-.752 0-1.204.473-1.204 1.246v13.009c0 .773.452 1.246 1.204 1.246Zm1.203-2.084V2.572h2.836c3.276 0 5.102 2.02 5.102 5.672 0 3.663-1.815 5.672-5.102 5.672H8.099Z"/>
</svg>346</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 21 23">
<path fill="#000" fill-opacity=".75" d="M0 17.614c0 .813.614 1.347 1.656 1.347h4.63c.087 2.147 1.744 4.028 4.059 4.028 2.325 0 3.982-1.87 4.07-4.028h4.629c1.03 0 1.656-.534 1.656-1.346 0-1.113-1.119-2.115-2.062-3.105-.724-.768-.922-2.348-1.01-3.627-.076-4.385-1.195-7.211-4.113-8.28C13.142 1.147 11.968 0 10.345 0c-1.613 0-2.798 1.146-3.16 2.604-2.918 1.068-4.037 3.894-4.113 8.278-.088 1.28-.286 2.86-1.01 3.628C1.108 15.5 0 16.502 0 17.614Zm2.128-.333v-.134c.198-.323.856-.979 1.426-1.624.79-.89 1.163-2.326 1.262-4.496.088-4.862 1.514-6.41 3.39-6.932.274-.067.427-.2.438-.49.033-1.157.691-1.97 1.7-1.97 1.02 0 1.668.813 1.712 1.97.01.29.153.423.428.49 1.886.523 3.313 2.07 3.4 6.932.099 2.17.472 3.605 1.25 4.496.582.645 1.23 1.301 1.427 1.624v.134H2.128Zm5.869 1.68h4.706c-.088 1.513-1.031 2.459-2.358 2.459-1.317 0-2.271-.946-2.348-2.46Z"/>
</svg>Водитель отвлекся</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 23 23">
<path fill="#000" fill-opacity=".75" d="M6.93 17.14c.609 0 1.105-.507 1.105-1.116 0-.608-.496-1.104-1.105-1.104-.608 0-1.104.496-1.104 1.104 0 .61.496 1.116 1.104 1.116ZM4.992 12.6c.62 0 1.116-.496 1.116-1.105a1.109 1.109 0 0 0-2.22 0c0 .609.507 1.105 1.104 1.105Zm1.916-4.53c.608 0 1.104-.508 1.104-1.105 0-.62-.496-1.104-1.104-1.104-.609 0-1.104.484-1.104 1.104 0 .597.495 1.105 1.104 1.105Zm4.575-1.984a1.12 1.12 0 0 0 1.104-1.104c0-.62-.507-1.116-1.104-1.116a1.109 1.109 0 0 0 0 2.22Zm6.491 6.514c.597 0 1.104-.496 1.104-1.105 0-.608-.507-1.104-1.104-1.104-.62 0-1.104.496-1.104 1.104 0 .609.484 1.105 1.104 1.105Zm-1.938 4.541c.608 0 1.104-.507 1.104-1.116 0-.608-.496-1.104-1.104-1.104-.609 0-1.105.496-1.105 1.104 0 .61.496 1.116 1.105 1.116ZM9.69 13.23c.913.89 2.164.687 2.919-.372l4.406-6.153c.406-.563-.191-1.15-.755-.755l-6.209 4.35c-1.07.744-1.262 2.006-.36 2.93Zm1.803 9.759c6.288 0 11.495-5.218 11.495-11.495C22.989 5.206 17.77 0 11.483 0 5.206 0 0 5.206 0 11.494 0 17.771 5.218 22.99 11.494 22.99Zm0-1.916a9.532 9.532 0 0 1-9.567-9.579c0-5.319 4.237-9.578 9.556-9.578 5.319 0 9.59 4.26 9.59 9.578a9.542 9.542 0 0 1-9.579 9.579Z"/>
</svg>34 км/ч</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 23 22">
<path fill="#000" fill-opacity=".75" d="M3.624 21.269h15.764c2.412 0 3.612-1.2 3.612-3.577V3.6C23 1.223 21.8.023 19.388.023H3.624C1.212.023 0 1.212 0 3.601v14.09c0 2.39 1.212 3.578 3.624 3.578Zm-.173-1.858c-1.028 0-1.593-.542-1.593-1.616V6.913c0-1.062.565-1.616 1.593-1.616h16.087c1.027 0 1.604.554 1.604 1.616v10.882c0 1.074-.577 1.616-1.604 1.616H3.45Zm5.804-9.97h.681c.404 0 .531-.116.531-.52V8.24c0-.404-.127-.53-.53-.53h-.682c-.404 0-.542.126-.542.53v.68c0 .405.138.52.542.52Zm3.832 0h.68c.405 0 .543-.116.543-.52V8.24c0-.404-.138-.53-.542-.53h-.681c-.404 0-.543.126-.543.53v.68c0 .405.139.52.543.52Zm3.831 0h.681c.404 0 .543-.116.543-.52V8.24c0-.404-.139-.53-.543-.53h-.68c-.405 0-.532.126-.532.53v.68c0 .405.127.52.531.52ZM5.424 13.213h.67c.415 0 .542-.116.542-.52v-.68c0-.404-.127-.52-.543-.52h-.669c-.415 0-.542.116-.542.52v.68c0 .404.127.52.542.52Zm3.831 0h.681c.404 0 .531-.116.531-.52v-.68c0-.404-.127-.52-.53-.52h-.682c-.404 0-.542.116-.542.52v.68c0 .404.138.52.542.52Zm3.832 0h.68c.405 0 .543-.116.543-.52v-.68c0-.404-.138-.52-.542-.52h-.681c-.404 0-.543.116-.543.52v.68c0 .404.139.52.543.52Zm3.831 0h.681c.404 0 .543-.116.543-.52v-.68c0-.404-.139-.52-.543-.52h-.68c-.405 0-.532.116-.532.52v.68c0 .404.127.52.531.52ZM5.424 16.999h.67c.415 0 .542-.127.542-.53v-.682c0-.404-.127-.519-.543-.519h-.669c-.415 0-.542.115-.542.52v.68c0 .404.127.531.542.531Zm3.831 0h.681c.404 0 .531-.127.531-.53v-.682c0-.404-.127-.519-.53-.519h-.682c-.404 0-.542.115-.542.52v.68c0 .404.138.531.542.531Zm3.832 0h.68c.405 0 .543-.127.543-.53v-.682c0-.404-.138-.519-.542-.519h-.681c-.404 0-.543.115-.543.52v.68c0 .404.139.531.543.531Z"/>
</svg>11-03-2023</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 23 23">
<path fill="#000" fill-opacity=".75" d="M5.6 12.711h5.883c.44 0 .789-.338.789-.788V4.327c0-.44-.35-.777-.789-.777a.765.765 0 0 0-.777.777v6.818H5.6a.768.768 0 0 0-.79.778c0 .45.339.788.79.788Zm5.894 10.278c6.288 0 11.495-5.218 11.495-11.495C22.989 5.206 17.77 0 11.483 0 5.206 0 0 5.206 0 11.494 0 17.771 5.218 22.99 11.494 22.99Zm0-1.916a9.532 9.532 0 0 1-9.567-9.579c0-5.319 4.237-9.578 9.556-9.578 5.319 0 9.59 4.26 9.59 9.578a9.542 9.542 0 0 1-9.579 9.579Z"/>
</svg>12:44</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 8 23">
<path fill="#000" fill-opacity=".75" d="M0 3.947a3.913 3.913 0 0 0 2.952 3.81v9.715c0 3.089.555 4.774.974 4.774.429 0 .973-1.675.973-4.774V7.757a3.913 3.913 0 0 0 2.963-3.81A3.94 3.94 0 0 0 3.926 0C1.748 0 0 1.78 0 3.947Zm2.806.22c-.723 0-1.35-.629-1.35-1.361 0-.723.627-1.34 1.35-1.34.732 0 1.34.617 1.34 1.34 0 .732-.608 1.36-1.34 1.36Z"/>
</svg>59.956626,30.234408</li>
</ul>
</div>
<div class="driver-info">
<ul>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 22 23">
<path fill="#000" fill-opacity=".75" d="M2.99 23h15.337c2.025 0 2.99-.61 2.99-1.952 0-3.197-4.04-7.821-10.653-7.821C4.04 13.226 0 17.85 0 21.047 0 22.39.964 23 2.99 23Zm-.574-1.842c-.317 0-.452-.086-.452-.342 0-2.001 3.1-5.747 8.7-5.747 5.589 0 8.688 3.746 8.688 5.747 0 .256-.122.342-.44.342H2.416Zm8.248-9.444c2.904 0 5.271-2.587 5.271-5.735 0-3.124-2.355-5.576-5.27-5.576-2.893 0-5.272 2.501-5.272 5.6.012 3.136 2.367 5.71 5.271 5.71Zm0-1.843c-1.781 0-3.306-1.708-3.306-3.868 0-2.123 1.5-3.758 3.306-3.758 1.818 0 3.307 1.61 3.307 3.734 0 2.16-1.513 3.892-3.307 3.892Z"/>
</svg>Виталий Гаспарян</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 23 23">
<path fill="#000" fill-opacity=".75" d="M17.053 23c2.053 0 3.402-.551 4.587-1.888.093-.094.187-.2.27-.293.703-.786 1.031-1.56 1.031-2.3 0-.844-.492-1.63-1.536-2.357l-3.413-2.369c-1.056-.727-2.287-.81-3.272.164l-.904.903c-.27.27-.504.282-.762.117-.633-.398-1.912-1.513-2.78-2.38-.914-.903-1.794-1.912-2.263-2.651-.153-.27-.141-.493.129-.762l.891-.904c.985-.985.903-2.228.176-3.272l-2.37-3.413C6.112.551 5.326.07 4.48.06 3.741.047 2.967.387 2.182 1.09l-.294.258C.551 2.545 0 3.894 0 5.923c0 3.354 2.064 7.436 5.853 11.224C9.618 20.912 13.71 23 17.053 23Zm.012-1.806c-2.99.058-6.826-2.24-9.864-5.266-3.06-3.05-5.465-7.014-5.407-10.005.024-1.29.481-2.404 1.396-3.202.082-.07.141-.129.223-.188.352-.305.727-.469 1.067-.469.34 0 .645.13.868.481l2.276 3.413c.246.364.27.774-.094 1.138L6.498 8.128c-.81.81-.75 1.794-.165 2.58.669.903 1.83 2.217 2.733 3.108.892.904 2.31 2.17 3.226 2.85.786.587 1.77.646 2.58-.164l1.032-1.032c.364-.364.762-.34 1.138-.105l3.413 2.275c.352.235.48.528.48.88 0 .34-.163.715-.468 1.067l-.188.223c-.798.915-1.912 1.36-3.214 1.384Z"/>
</svg>+7 999 123 45 67</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 23 18">
<path fill="#000" fill-opacity=".75" d="M3.27 17.969h16.772c1.875 0 2.958-1.084 2.958-3.23V3.24C23 1.105 21.906.022 19.73.022H2.957C1.083.02 0 1.094 0 3.24v11.5c0 2.156 1.094 3.229 3.27 3.229Zm-.062-1.594c-1.041 0-1.614-.552-1.614-1.635V3.24c0-1.073.573-1.625 1.614-1.625h16.584c1.02 0 1.614.552 1.614 1.635v11.5c0 1.073-.593 1.625-1.614 1.625H3.208Zm8.313-4.604c.729 0 1.437-.302 2.166-1.021l8.459-8.312-1.084-1.094-8.28 8.177c-.449.448-.855.646-1.261.646-.417 0-.823-.209-1.26-.646L1.937 1.302.843 2.396l8.51 8.354c.73.719 1.427 1.02 2.167 1.02Zm9.437 4.833 1.084-1.094-6.74-6.656-1.083 1.084 6.74 6.666ZM.99 15.521l1.083 1.094 6.75-6.677-1.094-1.084-6.74 6.667Z"/>
</svg>gosparyan@mail.ru</li>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 23 18">
<path fill="#000" fill-opacity=".75" d="M4.633 5.91h6.292c.38 0 .682-.311.682-.692a.67.67 0 0 0-.682-.673H4.633a.656.656 0 0 0-.673.673c0 .38.283.693.673.693Zm0 2.605h4.604c.38 0 .683-.302.683-.683a.679.679 0 0 0-.683-.682H4.633a.664.664 0 0 0-.673.682c0 .38.283.683.673.683Zm12.076.264a2.333 2.333 0 0 0 2.33-2.341 2.333 2.333 0 0 0-2.33-2.341 2.342 2.342 0 0 0 0 4.682ZM3.063 17.957h16.874c2.049 0 3.063-1.004 3.063-3.014V3.023C23 1.015 21.986 0 19.937 0H3.063C1.024 0 0 1.014 0 3.024v11.92c0 2.009 1.024 3.013 3.063 3.013Zm.02-1.57c-.976 0-1.513-.517-1.513-1.532V3.112c0-1.015.537-1.542 1.512-1.542h16.836c.965 0 1.512.527 1.512 1.542v11.743c0 1.015-.547 1.532-1.512 1.532H3.082Z"/>
</svg>RUD0000000000111</li>
</ul>
</div>
<div class="speedometr">
<h1>Скорость</h1>
<span>км/ч</span>
<div>
<canvas id="speed"></canvas>
</div>
</div>
<div class="video-controls">
<div class="controls">
<span id="current-time">00:00</span>
<button id="play-pause-btn">
<svg id="play-icon" xmlns="http://www.w3.org/2000/svg" width="23" height="25" fill="none" viewBox="0 0 23 25">
<path fill="#0B0B0B" d="M1.77 25c.59 0 1.091-.236 1.681-.575l17.198-9.941c1.224-.723 1.652-1.195 1.652-1.977 0-.781-.428-1.253-1.652-1.961L3.451.59C2.861.25 2.36.03 1.77.03.678.03 0 .856 0 2.139v20.737C0 24.16.678 25 1.77 25Z"/>
</svg>
<svg id="pause-icon" xmlns="http://www.w3.org/2000/svg" width="19" height="25" fill="none" viewBox="0 0 19 25">
<path fill="#0B0B0B" d="M2.134 25h3.483c1.408 0 2.134-.736 2.134-2.163V2.163C7.751.706 7.025.015 5.617 0H2.134C.726 0 0 .736 0 2.163v20.674C-.015 24.264.712 25 2.134 25Zm11.264 0h3.468C18.274 25 19 24.264 19 22.837V2.163C19 .706 18.274 0 16.866 0h-3.468c-1.423 0-2.134.736-2.134 2.163v20.674c0 1.427.711 2.163 2.134 2.163Z"/>
</svg>
</button>
<span id="remaining-time">-00:00</span>
</div>
<div id="progress-bar">
<div id="progress"></div>
</div>
</div>
</div>
<video id="my-video" src="../test_video.MP4"></video>
<div id="map"></div>
</section>
<style>
#map {
height: 100%;
width: calc(100% - 450px - 514px);
display: inline-block;
float: right;
}
</style>
<!-- <div id="map"></div> -->
<script src="https://cdn.jsdelivr.net/npm/leaflet/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet-routing-machine/dist/leaflet-routing-machine.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-routing-machine/dist/leaflet-routing-machine.css" />
<script>
function initMap() {
// Координаты начальной точки
var startPoint = L.latLng(55.769042, 37.647840);
// Координаты конечной точки
var endPoint = L.latLng(55.769723, 37.659341);
// Создание объекта карты
var map = L.map('map').setView(startPoint, 12);
// Добавление слоя OpenStreetMap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Прокладка маршрута
var control = L.Routing.control({
waypoints: [
startPoint,
endPoint
],
routeWhileDragging: true,
show: false,
}).addTo(map);
// Удаление кнопки виджета маршрута
document.querySelector('.leaflet-routing-container').style.display = 'none';
}
</script>
<script>initMap();</script>
</section>
</section>
</section>
</section>
<script src="../scripts/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const video = document.getElementById('my-video');
const playPauseButton = document.getElementById('play-pause-btn');
const progressBar = document.getElementById('progress-bar');
const progress = document.getElementById('progress');
const currentTimeDisplay = document.getElementById('current-time');
const remainingTimeDisplay = document.getElementById('remaining-time');
const playIcon = document.getElementById('play-icon');
const pauseIcon = document.getElementById('pause-icon');
playPauseButton.addEventListener('click', togglePlayPause);
progressBar.addEventListener('click', seek);
function togglePlayPause() {
if (video.paused) {
video.play();
playIcon.style.display = 'none';
pauseIcon.style.display = 'inline-block';
} else {
video.pause();
playIcon.style.display = 'inline-block';
pauseIcon.style.display = 'none';
}
}
function updateProgressBar() {
const progressPercentage = (video.currentTime / video.duration) * 100;
progress.style.width = `${progressPercentage}%`;
const currentTime = formatTime(video.currentTime);
currentTimeDisplay.textContent = currentTime;
const remainingTime = formatTime(video.duration - video.currentTime);
remainingTimeDisplay.textContent = `-${remainingTime}`;
if (video.duration === video.currentTime) {
progress.style.borderRadius = '50px';
playIcon.style.display = 'inline-block';
pauseIcon.style.display = 'none';
} else {
progress.style.borderRadius = '50px 0 0 50px';
}
}
function seek(event) {
const progressWidth = progressBar.clientWidth;
const clickX = event.offsetX;
const seekTime = (clickX / progressWidth) * video.duration;
video.currentTime = seekTime;
}
function formatTime(time) {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
const formattedTime = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
return formattedTime;
}
video.addEventListener('timeupdate', updateProgressBar);
</script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
Chart.defaults.color = "rgba(0, 0, 0, 0.4)";
Chart.defaults.font.size = 15;
Chart.defaults.font.weight = 400;
var speedData = {
labels: [
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
],
datasets: [
{
label: "Скорость",
borderColor: "#8086F9",
fill: false,
data: [
17, 21, 40, 30, 43, 38, 40, 21, 24, 28, 26,
],
pointStyle: false,
pointRadius: 25,
pointHoverRadius: 25,
tension: 0.4,
},
],
};
var speedOptions = {
plugins: {
legend: {
display: false,
},
},
labelStep: "3",
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
stacked: true,
grid: {
display: true,
color: "#D9D9D9",
},
ticks: {
stepSize: 10,
},
},
x: {
grid: {
display: false,
},
},
},
};
new Chart("speed", {
type: "line",
data: speedData,
options: speedOptions,
});
</script>
</body>
</html>

View File

@ -0,0 +1,248 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Отчёты</title>
<link rel="stylesheet" href="../styles/main.css" />
</head>
<body>
<header>
<h1>Аргус</h1>
<h2><span>/</span> Название организации</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>Тестовое Имя</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div class="selected"><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/">
<div><img src="../img/play.svg">Записи</div>
</a>
<a class="settings" href="/">
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<div class="name">
<span>Отчёты</span>
</div>
<nav>
<a class="selected" href="/reports">Предупреждения</a>
</nav>
<section class="bg">
<section class="content">
<section class="for-table">
<section class="organisation">
<h1>Организация</h1>
<ul class="area">
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-1" class="checkbox-input" hidden checked><label for="name-1" class="checkbox-label">Группа 1</label>
<ul class="area-devices" id="devices-1">
<li class="device"><img><input type="checkbox" id="0001" class="checkbox-input device-filter" value="0001" hidden checked><label for="0001" class="checkbox-label"><div class="checkmark"></div>0001</label></li>
<li class="device"><img><input type="checkbox" id="0002" class="checkbox-input device-filter" value="0002" hidden checked><label for="0002" class="checkbox-label"><div class="checkmark"></div>0002</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-2" class="checkbox-input" hidden checked><label for="name-2" class="checkbox-label">Группа 2</label>
<ul class="area-devices" id="devices-2">
<li class="device"><img><input type="checkbox" id="0003" class="checkbox-input device-filter" value="0003" hidden checked><label for="0003" class="checkbox-label"><div class="checkmark"></div>0003</label></li>
<li class="device"><img><input type="checkbox" id="0004" class="checkbox-input device-filter" value="0004" hidden checked><label for="0004" class="checkbox-label"><div class="checkmark"></div>0004</label></li>
<li class="device"><img><input type="checkbox" id="0005" class="checkbox-input device-filter" value="0005" hidden checked><label for="0005" class="checkbox-label"><div class="checkmark"></div>0005</label></li>
<li class="device"><img><input type="checkbox" id="0006" class="checkbox-input device-filter" value="0006" hidden checked><label for="0006" class="checkbox-label"><div class="checkmark"></div>0006</label></li>
</ul>
</li>
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-3" class="checkbox-input" hidden checked><label for="name-3" class="checkbox-label">Другое</label>
<ul class="area-devices" id="devices-3">
<li class="device"><img><input type="checkbox" id="0007" class="checkbox-input device-filter" value="0007" hidden checked><label for="0007" class="checkbox-label"><div class="checkmark"></div>0007</label></li>
</ul>
</li>
</ul>
<div class="area-time-range">
<div class="time-range"><label for="timeRangeStart">с</label><input id="timeRangeStart" name="timeRangeStart" type="datetime-local"></div>
<div class="time-range"><label for="timeRangeEnd">до</label><input id="timeRangeEnd" name="timeRangeEnd" type="datetime-local"></div>
</div>
</section>
<section id="table-area" class="table">
<h1>Список предупреждений</h1>
<input id="table-search" class="search" type="text" placeholder="Поиск">
<table id="deviceTable">
<thead>
<tr>
<th><input id="device-all" type="checkbox"><label for="device-all"><div class="checkmark"></div></label></th>
<th>Наименование</th>
<th>ID</th>
<th>Номерной знак</th>
<th>Серийный номер</th>
<th>Время</th>
<th>Местоположение</th>
<th><button id="share-device-all" value="share-device-all" class="share" onclick="location.href = '/reports/346';"></button></th>
</tr>
</thead>
<tbody>
<!-- Сюда будут добавляться строки таблицы -->
</tbody>
</table>
</section>
<div id="count">
<!-- Сюда добавится итоговое количество результатов -->
</div>
<div id="pagination">
<!-- Сюда будут добавляться ссылки для переключения между страницами -->
</div>
</section>
</section>
</section>
</section>
<script src="../scripts/table-reports.js"></script>
<script src="../scripts/jquery.min.js"></script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
const checkboxes = document.querySelectorAll('.organisation .checkbox-input');
checkboxes.forEach((checkbox) => {
applyFilterAndSearch();
checkbox.addEventListener('change', function() {
document.querySelector('#device-all').checked = false;
applyFilterAndSearch();
const devices = this.parentNode.querySelector('.area-devices');
if (this.checked) {
devices.style.display = 'block';
// Активируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = true;
applyFilterAndSearch();
});
} else {
devices.style.display = 'none';
applyFilterAndSearch();
// Деактивируем дочерние чекбоксы
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
}
// Деактивируем дочерние чекбоксы, если родительский чекбокс не выбран
if (!this.checked) {
const childCheckboxes = devices.querySelectorAll('.device-filter');
childCheckboxes.forEach((childCheckbox) => {
childCheckbox.checked = false;
applyFilterAndSearch();
});
devices.style.display = 'none';
}
});
});
</script>
<script>
var table = document.querySelector('#deviceTable');
var tableCheckboxAll = table.querySelector('#device-all');
var tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
tableCheckboxAll.addEventListener('click', function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
if (tableCheckboxAll.checked) {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = true;
});
} else {
tableCheckboxes.forEach((tableCheckbox) => {
tableCheckbox.checked = false;
});
}
});
$('#deviceTable').click( function(event) {
table = document.querySelector('#deviceTable');
tableCheckboxes = table.querySelectorAll('tbody input[type="checkbox"]');
for (var i = 0; i < tableCheckboxes.length; i++) {
tableCheckboxes[i].addEventListener('click', function(event) {
for (var j = 0; j < tableCheckboxes.length; j++) {
if (!tableCheckboxes[j].checked || tableCheckboxes[j].disabled) {
tableCheckboxAll.checked = false;
return;
}
}
tableCheckboxAll.checked = true;
});
}
});
</script>
</body>
</html>

BIN
static/test_video.MP4 Normal file

Binary file not shown.