updated web
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Make (push) Successful in 10s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-CMake (push) Successful in 15s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Meson (push) Successful in 12s

This commit is contained in:
wt committed 2025-08-30 12:24:57 +07:00
1 parent b0758c5499
commit 4c4f92e43b
5 files changed
+357 -242

No files matched your search

+1 -2
View File
@@ -28,7 +28,6 @@
background-color: gray; background-color: gray;
backdrop-filter: blur(5px); backdrop-filter: blur(5px);
border-radius: 10px; border-radius: 10px;
/* box-shadow: -5px -5px 30px 30px gray; */
} }
.loginformheader { .loginformheader {
@@ -51,7 +50,7 @@
display: flex; display: flex;
} }
.loginforminputbodyflex>button { .loginforminputbodyflex > button {
margin: 10px; margin: 10px;
} }
+23 -9
View File
@@ -1,19 +1,33 @@
.message { * {
width: 100%; transition: 0.3s;
}
.notificationsection {
width: max-content;
height: 100vh;
position: fixed;
top: 10px;
right: 0;
pointer-events: none;
z-index: 16;
}
.notification {
width: max-content;
height: 0; height: 0;
overflow: hidden; overflow: hidden;
pointer-events: none; pointer-events: none;
z-index: 10; z-index: 10;
border-radius: 10px; border-radius: 10px;
position: fixed;
top: 0; top: 0;
left: 0; right: 0;
transition: 0.3s;
cursor: pointer; cursor: pointer;
opacity: 0.8; opacity: 0.8;
margin: 10px;
padding: 0 10px;
} }
.messagetextbox { .notificationtextbox {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: grid; display: grid;
@@ -22,19 +36,19 @@
pointer-events: none; pointer-events: none;
} }
.messagetext { .notificationtext {
width: 100%; width: 100%;
text-align: center; text-align: center;
pointer-events: none; pointer-events: none;
} }
.message.active.error { .notification.active.error {
pointer-events: all; pointer-events: all;
height: 10%; height: 10%;
background-color: rgb(233, 70, 70); background-color: rgb(233, 70, 70);
} }
.message.active.success { .notification.active.success {
pointer-events: all; pointer-events: all;
height: 10%; height: 10%;
background-color: rgb(76, 209, 76); background-color: rgb(76, 209, 76);
+218 -142
View File
@@ -1,155 +1,231 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/css/loginform.css"> <link rel="stylesheet" href="/css/loginform.css" />
<link rel="stylesheet" href="/css/message.css"> <link rel="stylesheet" href="/css/message.css" />
<link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap.min.css" />
<title>admin</title> <title>admin</title>
</head> </head>
<body> <body>
<div class="navbar navbar-expand-lg bg-body-tertiary gap-3 p-2"> <div class="navbar navbar-expand-lg bg-body-tertiary gap-3 p-2">
<button class="btn btn-danger" id="exitbutton">Exit</button> <button class="btn btn-danger" id="exitbutton">Exit</button>
<button class="btn btn-warning" id="adduserbutton">Adduser</button> <button class="btn btn-warning" id="adduserbutton">Adduser</button>
<h1 class="usernameheader"></h1> <h1 class="usernameheader"></h1>
<div class="form-check"> <div class="form-check">
<input type="checkbox" id="themecheckbox" class="form-check-input"> <input
<label for="themecheckbox" class="form-check-label">Dark theme</label> type="checkbox"
</div> id="themecheckbox"
</div> class="form-check-input"
/>
<label for="themecheckbox" class="form-check-label"
>Dark theme</label
>
</div>
</div>
<div class="form loginform" id="loginform"> <div class="form loginform" id="loginform">
<form class="formbody loginformbody" id="loginformbody"> <form class="formbody loginformbody" id="loginformbody">
<h1 class="loginformheader">Login</h1> <h1 class="loginformheader">Login</h1>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input type="text" required id="loginforminputusername" class="form-control" placeholder="John"> <input
<label for="loginforminputusername">Username</label> type="text"
required
id="loginforminputusername"
class="form-control"
placeholder="John"
/>
<label for="loginforminputusername">Username</label>
</div>
<div class="form-floating mb-3">
<input
type="password"
required
id="loginforminputpassword"
class="form-control"
placeholder="***"
/>
<label for="loginforminputpassword">Password</label>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary">login</button>
</div>
</form>
</div> </div>
<div class="form-floating mb-3">
<input type="password" required id="loginforminputpassword" class="form-control" placeholder="***">
<label for="loginforminputpassword">Password</label>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary">login</button>
</div>
</form>
</div>
<div class="form adduserform"> <div class="form adduserform">
<form class="formbody adduserformbody"> <form class="formbody adduserformbody">
<h1 class="loginformheader">Add User</h1> <h1 class="loginformheader">Add User</h1>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input type="text" required id="adduserformusername" class="form-control"> <input
<label for="adduserformusername">Username</label> type="text"
required
id="adduserformusername"
class="form-control"
/>
<label for="adduserformusername">Username</label>
</div>
<div class="form-floating mb-3">
<input
type="text"
required
id="adduserformemail"
class="form-control"
/>
<label for="adduserformemail">Email</label>
</div>
<div class="form-floating mb-3">
<input
type="password"
required
id="adduserformpassword"
class="form-control"
/>
<label for="adduserformpassword">Password</label>
</div>
<div class="form-floating mb-3">
<input
type="text"
required
id="adduserformgroup"
class="form-control"
/>
<label for="adduserformgroup">Group</label>
</div>
<div class="form-check">
<input
type="checkbox"
id="adduserformissuperuser"
class="form-check-input"
/>
<label for="adduserformissuperuser" class="form-check-label"
>Is Superuser</label
>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary">Add</button>
<button id="canceladduser" class="btn btn-primary">
Cancel
</button>
</div>
</form>
</div> </div>
<div class="form-floating mb-3">
<input type="text" required id="adduserformemail" class="form-control">
<label for="adduserformemail">Email</label>
</div>
<div class="form-floating mb-3">
<input type="password" required id="adduserformpassword" class="form-control">
<label for="adduserformpassword">Password</label>
</div>
<div class="form-floating mb-3">
<input type="text" required id="adduserformgroup" class="form-control">
<label for="adduserformgroup">Group</label>
</div>
<div class="form-check">
<input type="checkbox" id="adduserformissuperuser" class="form-check-input">
<label for="adduserformissuperuser" class="form-check-label">Is Superuser</label>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary">Add</button>
<button id="canceladduser" class="btn btn-primary">Cancel</button>
</div>
</form>
</div>
<div class="form changeuserform"> <div class="form changeuserform">
<form class="formbody changeuserformbody"> <form class="formbody changeuserformbody">
<h1 class="loginformheader">Change User Data</h1> <h1 class="loginformheader">Change User Data</h1>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input type="text" required id="changeuserformusername" class="form-control" placeholder="Username"> <input
<label for="changeuserformusername">Username</label> type="text"
required
id="changeuserformusername"
class="form-control"
placeholder="Username"
/>
<label for="changeuserformusername">Username</label>
</div>
<div class="form-floating mb-3">
<input
type="text"
id="changeuserformemail"
class="form-control"
placeholder="***"
/>
<label for="changeuserformemail">email</label>
</div>
<div class="form-floating mb-3">
<input
type="text"
required
id="changeuserformgroup"
class="form-control"
/>
<label for="changeuserformgroup">Group</label>
</div>
<div class="form-check">
<input
type="checkbox"
id="changeuserformissuperuser"
class="form-check-input"
/>
<label
for="changeuserformissuperuser"
class="form-check-label"
>Is Superuser</label
>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary">Change</button>
<button id="cancelchangeuser" class="btn btn-primary">
Cancel
</button>
</div>
</form>
</div> </div>
<div class="form-floating mb-3">
<input type="text" id="changeuserformemail" class="form-control" placeholder="***">
<label for="changeuserformemail">email</label>
</div>
<div class="form-floating mb-3">
<input type="text" required id="changeuserformgroup" class="form-control">
<label for="changeuserformgroup">Group</label>
</div>
<div class="form-check">
<input type="checkbox" id="changeuserformissuperuser" class="form-check-input">
<label for="changeuserformissuperuser" class="form-check-label">Is Superuser</label>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary">Change</button>
<button id="cancelchangeuser" class="btn btn-primary">Cancel</button>
</div>
</form>
</div>
<div class="form confirmform"> <div class="form confirmform">
<div class="formbody confirmformbody"> <div class="formbody confirmformbody">
<h1>Are you sure?</h1> <h1>Are you sure?</h1>
<div class="d-grid gap-2"> <div class="d-grid gap-2">
<button id="yes" class="btn btn-primary">Confirm</button> <button id="yes" class="btn btn-primary">Confirm</button>
<button id="no" class="btn btn-primary">Cancel</button> <button id="no" class="btn btn-primary">Cancel</button>
</div>
</div>
</div> </div>
</div>
</div>
<div class="form changepasswordform"> <div class="form changepasswordform">
<form class="formbody changepasswordformbody"> <form class="formbody changepasswordformbody">
<h1 class="loginformheader">Change Password</h1> <h1 class="loginformheader">Change Password</h1>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input type="text" required id="changepasswordnewpassword" class="form-control" placeholder="***"> <input
<label for="changepasswordnewpassword">New password</label> type="text"
required
id="changepasswordnewpassword"
class="form-control"
placeholder="***"
/>
<label for="changepasswordnewpassword">New password</label>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary">Change</button>
<button class="btn btn-primary" id="cancelchangepassword">
Cancel
</button>
</div>
</form>
</div> </div>
<div class="d-grid gap-2">
<button class="btn btn-primary">Change</button> <div class="notificationsection"></div>
<button class="btn btn-primary" id="cancelchangepassword">Cancel</button>
<div class="table">
<table class="table">
<thead class="alluserstablehead">
<tr>
<th>id</th>
<th>username</th>
<th>email</th>
<th>group</th>
<th>is_superuser</th>
<th>delete</th>
<th>change password</th>
<th>change user data</th>
</tr>
</thead>
<tbody id="alluserstablebody"></tbody>
</table>
</div> </div>
</form> <script src="/js/security.js"></script>
</div> <script src="/js/message.js"></script>
<script src="/js/routes.js"></script>
<div class="message"> <script src="/js/window.js"></script>
<div class="messagetextbox"> <script src="/js/theme.js"></script>
<h3 class="messagetext"></h3> <script src="/js/login.js"></script>
</div> <script src="/js/get_all_users.js"></script>
</div> <script src="/js/add_user.js"></script>
<script src="/js/del_user.js"></script>
<div class="table"> <script src="/js/change_password.js"></script>
<table class="table"> <script src="/js/change_user.js"></script>
<thead class="alluserstablehead"> <script src="/js/bootstrap.min.js"></script>
<tr> </body>
<th>id</th>
<th>username</th>
<th>email</th>
<th>group</th>
<th>is_superuser</th>
<th>delete</th>
<th>change password</th>
<th>change user data</th>
</tr>
</thead>
<tbody id="alluserstablebody"></tbody>
</table>
</div>
<script src="/js/security.js"></script>
<script src="/js/message.js"></script>
<script src="/js/routes.js"></script>
<script src="/js/window.js"></script>
<script src="/js/theme.js"></script>
<script src="/js/login.js"></script>
<script src="/js/get_all_users.js"></script>
<script src="/js/add_user.js"></script>
<script src="/js/del_user.js"></script>
<script src="/js/change_password.js"></script>
<script src="/js/change_user.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html> </html>
+84 -74
View File
@@ -1,83 +1,93 @@
const loginform = document.querySelector('#loginform') const loginform = document.querySelector("#loginform");
const loginformbody = document.querySelector('#loginformbody') const loginformbody = document.querySelector("#loginformbody");
const loginforminputusername = document.querySelector('#loginforminputusername') const loginforminputusername = document.querySelector(
const loginforminputpassword = document.querySelector('#loginforminputpassword') "#loginforminputusername",
const exitbutton = document.querySelector('#exitbutton') );
const usernameheader = document.querySelector('.usernameheader') const loginforminputpassword = document.querySelector(
"#loginforminputpassword",
);
const exitbutton = document.querySelector("#exitbutton");
const usernameheader = document.querySelector(".usernameheader");
if (localStorage.getItem("token") === null) { if (localStorage.getItem("token") === null) {
loginform.classList.add("active") loginform.classList.add("active");
} }
loginformbody.addEventListener('submit', (e) => { loginformbody.addEventListener("submit", (e) => {
e.preventDefault() e.preventDefault();
hashPassword(loginforminputpassword.value).then(hashedpassword => { hashPassword(loginforminputpassword.value).then((hashedpassword) => {
login(loginforminputusername.value, hashedpassword) login(loginforminputusername.value, hashedpassword);
}) });
}) });
const login = async (username, password) => { const login = async (username, password) => {
const response = await fetch(routes.login(), { const response = await fetch(routes.login(), {
method: 'POST', method: "POST",
headers: { headers: {
Accept: 'application/json', Accept: "application/json",
// 'Access-Control-Allow-Origin': '*', "Content-Type": "application/json",
'Content-Type': 'application/json', },
}, body: `{"username":"${username}","password":"${password}"}`,
// mode: 'no-cors', })
body: `{"username":"${username}","password":"${password}"}` .then((data) => data.json())
}).then(data => data.json()).then(jsondata => jsondata).catch((error) => { .then((jsondata) => jsondata)
if (error.message === "Unexpected end of JSON input") { .catch((error) => {
notification(`Ошибка на сервере: Создайте файл users.json и запишите в него первого пользователя`, "error") if (error.message === "Unexpected end of JSON input") {
} else { notification(
notification(`Ошибка на сервере: ${error}`, "error") `Ошибка на сервере: Создайте файл users.json и запишите в него первого пользователя`,
} "error",
}) );
if (response.error) { } else {
loginforminputusername.classList.add('is-invalid') notification(`Ошибка на сервере: ${error}`, "error");
loginforminputpassword.classList.add('is-invalid') }
notification("Неправильный логин или пароль", "error") });
} if (response.error) {
if (response.token) { loginforminputusername.classList.add("is-invalid");
notification("Успешно", "success") loginforminputpassword.classList.add("is-invalid");
loginform.classList.remove("active") notification("Неправильный логин или пароль", "error");
localStorage.setItem("token", response.token) }
await get_user_data() if (response.token) {
loginforminputusername.value = "" notification("Успешно", "success");
loginforminputpassword.value = "" loginform.classList.remove("active");
loginforminputusername.classList.remove('is-invalid') localStorage.setItem("token", response.token);
loginforminputpassword.classList.remove('is-invalid') await get_user_data();
} loginforminputusername.value = "";
} loginforminputpassword.value = "";
loginforminputusername.classList.remove("is-invalid");
loginforminputpassword.classList.remove("is-invalid");
}
};
const get_user_data = async () => { const get_user_data = async () => {
const response = await fetch(routes.user(), { const response = await fetch(routes.user(), {
method: "POST", method: "POST",
body: `{"token":"${localStorage.getItem("token")}"}` body: `{"token":"${localStorage.getItem("token")}"}`,
}).then(data => data.json()).then(jsondata => jsondata).catch((error) => { })
notification(`Ошибка на сервере: ${error}`, "error") .then((data) => data.json())
}) .then((jsondata) => jsondata)
if (response.is_superuser) { .catch((error) => {
await get_all_users() notification(`Ошибка на сервере: ${error}`, "error");
usernameheader.innerHTML = response.username });
} else { if (response.is_superuser) {
document.querySelector('#alluserstablebody').innerHTML = "" await get_all_users();
loginform.classList.add("active") usernameheader.innerHTML = response.username;
notification("Вы не можете войти потому что не являетесь администратором", "error") } else {
localStorage.clear() document.querySelector("#alluserstablebody").innerHTML = "";
} loginform.classList.add("active");
if (response.id) { notification(
localStorage.setItem("userdata", JSON.stringify(response)) "Вы не можете войти потому что не являетесь администратором",
} "error",
} );
localStorage.clear();
}
if (response.id) {
localStorage.setItem("userdata", JSON.stringify(response));
}
};
message.addEventListener('click', () => { exitbutton.addEventListener("click", () => {
message.classList.remove("active") localStorage.removeItem("token");
}) localStorage.removeItem("userdata");
loginform.classList.add("active");
exitbutton.addEventListener('click', () => { notification("Вы вышли", "success");
localStorage.removeItem('token') });
localStorage.removeItem('userdata')
loginform.classList.add('active')
notification('Вы вышли', "success")
})
+31 -15
View File
@@ -1,18 +1,34 @@
const message = document.querySelector('.message') const notificationsection = document.querySelector(".notificationsection");
const messagetext = document.querySelector('.messagetext')
const notification = (text, type) => { const notification = (text, type) => {
if (type === "error") { const notificationbox = document.createElement("div");
message.classList.remove('success') const notificationtextbox = document.createElement("div");
message.classList.add('error') const notificationtext = document.createElement("h3");
} else { notificationtext.classList.add("notificationtext");
message.classList.remove('error') notificationtextbox.append(notificationtext);
message.classList.add('success') notificationtextbox.classList.add("notificationtextbox");
} notificationtextbox.classList.add("card-header");
messagetext.innerHTML = text notificationbox.append(notificationtextbox);
message.classList.add('active') notificationbox.classList.add("notification");
notificationbox.addEventListener("click", () => {
notificationbox.classList.remove("active");
});
notificationsection.append(notificationbox);
if (type === "error") {
notificationbox.classList.remove("success");
notificationbox.classList.add("error");
} else {
notificationbox.classList.remove("error");
notificationbox.classList.add("success");
}
notificationtext.innerHTML = text;
setTimeout(() => {
notificationbox.classList.add("active");
}, 300);
setTimeout(() => {
notificationbox.classList.remove("active");
setTimeout(() => { setTimeout(() => {
message.classList.remove('active') notificationsection.removeChild(notificationbox);
}, 2000) }, 200);
} }, 3000);
};