This commit is contained in:
DyCTaTOR 2023-11-24 01:31:26 +04:00
parent 9a15b51b6e
commit 983edb4fac
30 changed files with 9404 additions and 0 deletions

20
Lab3/.eslintrc.json Normal file
View File

@ -0,0 +1,20 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": "airbnb-base",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"quotes": "off",
"indent": "off",
"no-console": "off",
"no-use-before-define": "off",
"no-alert": "off",
"no-restricted-globals": "off",
"quote-props": "off"
}
}

45
Lab3/.gitignore vendored Normal file
View File

@ -0,0 +1,45 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# Compiled output
/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
# System files
.DS_Store
Thumbs.db
# Ignore dist
dist/

15
Lab3/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// Используйте IntelliSense, чтобы узнать о возможных атрибутах.
// Наведите указатель мыши, чтобы просмотреть описания существующих атрибутов.
// Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "msedge",
"request": "launch",
"name": "Запустить Microsoft Edge на localhost",
"url": "http://localhost:5173/index.html",
"webRoot": "${workspaceFolder}"
}
]
}

Binary file not shown.

114
Lab3/admin.html Normal file
View File

@ -0,0 +1,114 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Абитуриенту</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
</head>
<body class="h-100 d-flex flex-column" background = "./images/BackGr.png">
<header>
<nav class = "headStyleNavBar navbar-text navbar-dark w-100">
<div class = "text-center">
<img src = "./images/logo2.png" alt = "logo2" width="70">
<span class = "headStyle">
<b>Ульяновский Государственный Политехнический Университет</b>
</span>
</div>
</nav>
<nav class="headStyleNavBar2 navbar navbar-expand-md">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav">
<a class="heasdStyle nav-link" href="./index.html"><span class = "headStyle">Новости</span></a>
<a class="heasdStyle nav-link active" href="./page2.html"><span class = "headStyle">Об университете</span></a>
<a class="heasdStyle nav-link" href="./page3.html"><span class = "headStyle">Абитуриенту</span></a>
<a class = "heasdStyle nav-link" href = "./page4.html"><span class = "headStyle">Вход</span></a>
<a class = "nav-link" href = "./page5.html"><span class = "headStyle">Контакты</span></a>
</div>
</div>
</div>
</nav>
</header>
<main class="container p-2 text-center">
<span class = "mainSt">
<b>Новости</b>
</span>
<div class="btn-group" role="group">
<button id="items-add" class="btn btn-info">Добавить товар (диалог)</button>
</div>
<div class="tbb1 p-3 table-responsive-md mt-4 row justify-content-start">
<table id = "items-table" class="table col-lg2 w-75 table-striped">
<thead>
<th scope = "col"></th>
<th scope = "col" class = "">Дата добавления</th>
<th scope = "col" class ="w-50">Название</th>
<th scope = "col" class = "w-75">Описание</th>
<th scope = "col"></th>
<th scope = "col"></th>
</thead>
<tbody></tbody>
</table>
</div>
</main>
<footer class=" headStyleNavBar footer mt-5 d-flex flex-shrink-0 justify-content-center align-items-center">
Адреса: ул. Северный Венец, 32; ул. Андрея Блаженного, 3
</footer>
<div id="items-update" class="modal fade" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog">
<form id="items-form" class="needs-validation" novalidate>
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="items-update-title"></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="text-center">
<img id="image-preview" src="https://via.placeholder.com/200" class="rounded"
alt="placeholder">
</div>
<input id="items-line-id" type="number" hidden>
<div class="mb-2">
<label for="date" class="form-label">Дата</label>
<input id="date" class="form-control" name="date" type = "date" required>
</div>
<div class="mb-2">
<label class="form-label" for="name">Название</label>
<input id="name" name="name" class="form-control" type = "text"
required>
</div>
<div class="mb-2">
<label class="form-label" for="description">Описание</label>
<input id="description" name="description" class="form-control" type="text"
required>
</div>
<div class="mb-2">
<label class="form-label" for="image">Изображение</label>
<input id="image" type="file" name="image" class="form-control" accept="image/*">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="submit" class="btn btn-primary">Сохранить</button>
</div>
</div>
</form>
</div>
</div>
<script type = "module">
import validation from "./js/validation";
import { linesForm } from "./js/lines";
document.addEventListener('DOMContentLoaded', () => {
validation();
linesForm();
});
</script>
</body>
</html>

18
Lab3/data.json Normal file

File diff suppressed because one or more lines are too long

BIN
Lab3/images/BackGr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

BIN
Lab3/images/New1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

BIN
Lab3/images/New2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

BIN
Lab3/images/New3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
Lab3/images/New4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

BIN
Lab3/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
Lab3/images/logo2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

59
Lab3/index.html Normal file
View File

@ -0,0 +1,59 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Новости</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
</head>
<body class="h-100 d-flex flex-column" background = "./images/BackGr.png">
<header>
<nav class = "headStyleNavBar navbar-text navbar-dark w-100">
<div class = "text-center">
<img src = "./images/logo2.png" alt = "logo2" width="70">
<span class = "headStyle">
<b>Ульяновский Государственный Политехнический Университет</b>
</span>
</div>
</nav>
<nav class="headStyleNavBar2 navbar navbar-expand-md">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav">
<a class="heasdStyle nav-link" href="./index.html"><span class = "headStyle">Новости</span></a>
<a class="heasdStyle nav-link active" href="./page2.html"><span class = "headStyle">Об университете</span></a>
<a class="heasdStyle nav-link" href="./page3.html"><span class = "headStyle">Абитуриенту</span></a>
<a class = "heasdStyle nav-link" href = "./page4.html"><span class = "headStyle">Вход</span></a>
<a class = "nav-link" href = "./page5.html"><span class = "headStyle">Контакты</span></a>
</div>
</div>
</div>
</nav>
<div class = "container col text-center">
<span class = "mainSt">Новости</span>
<div class="text-center">
<button class="btn btn-primary w-auto" type="button" onclick ="location.href='admin.html';">
Добавить новость</button>
</div>
</div>
</header>
<div class = "row">
<footer class="headStyleNavBar footer mt-5 d-flex flex-shrink-0 justify-content-center align-items-center">
Адреса: ул. Северный Венец, 32; ул. Андрея Блаженного, 3
</footer>
</div>
<script type = "module">
import { UpdateNews } from "./js/lines";
document.addEventListener('DOMContentLoaded', () => {
UpdateNews();
});
</script>
</body>
</html>

46
Lab3/js/banner.js Normal file
View File

@ -0,0 +1,46 @@
// модуль для смены изображения в баннере по таймеру
import "../css/banner.css";
// указывается блок, в котором будет баннер
// блок должен содержать изображения
function myBanner(root) {
console.info("Loaded");
// получение всех изображений внутри баннера
const banners = document.querySelectorAll(`${root} img`);
// всем изображениям устанавливается класс banner-hide
// если были другие классы, то они будут удалены
for (let i = 0; i < banners.length; i += 1) {
banners[i].setAttribute("class", "banner-hide");
}
let old = banners.length - 1;
let current = 0;
// функция меняет изображения в цикле
// изображение с классом banner-show будет показано
// изображение с классом banner-hide будет скрыто
// функция запускает таймер, который через 5 секунд
// запускает функцию, снова создается таймер и т. д.
function loop() {
banners[current].setAttribute("class", "banner-show");
banners[old].setAttribute("class", "banner-hide");
console.info("Banner changed");
old = current;
current += 1;
if (current === banners.length) {
current = 0;
}
setTimeout(loop, 5000);
}
loop();
}
export default myBanner;

60
Lab3/js/lines-modal.js Normal file
View File

@ -0,0 +1,60 @@
// Модуль для работы с модальным окном
// импорт компонента Modal из bootstrap
import { Modal } from "bootstrap";
import { cntrls, imagePlaceholder } from "./lines-ui";
// поиск модального окна на странице
const modal = document.getElementById("items-update");
// если он найден, то создается экземпляр компонента Modal
// для программного управления модальным окном
const myModal = modal ? new Modal(modal, {}) : null;
// поиск тега с заголовком модального кона для его смены
const modalTitle = document.getElementById("items-update-title");
// обнуление значений модального окна, т. к.
// используется одно окно для всех операций
function resetValues() {
cntrls.lineId.value = "";
cntrls.itemDate.value = "";
cntrls.itemName.value = "";
cntrls.itemDescription.value = "";
cntrls.itemImage.value = "";
cntrls.imagePreview.src = imagePlaceholder;
}
// функция для показа модального окна
// перед показом происходит заполнение формы для редактирования
// если объект item не пуст
export function showUpdateModal(item) {
modalTitle.innerHTML = item === null ? "Добавить" : "Изменить";
console.info(item);
if (item) {
cntrls.lineId.value = item.id;
cntrls.itemDate.value = item.itemsId;
cntrls.itemName.value = item.name;
cntrls.itemDescription.value = item.description;
// заполнение превью
// Если пользователь выбрал изображение, то оно загружается
// в тэг image с id image - preview
// иначе устанавливается заглушка, адрес которой указан в imagePlaceholder
cntrls.imagePreview.src = item.image ? item.image : imagePlaceholder;
} else {
resetValues();
}
myModal.show();
}
// функция для скрытия модального окна
export function hideUpdateModal() {
resetValues();
// удаление класса was-validated для скрытия результатов валидации
cntrls.form.classList.remove("was-validated");
myModal.hide();
}

80
Lab3/js/lines-rest-api.js Normal file
View File

@ -0,0 +1,80 @@
// модуль для работы с REST API сервера
// адрес сервера
const serverUrl = "http://localhost:8081";
// функция возвращает объект нужной структуры для отправки на сервер
function createLineObject(itemDate, itemName, itemDescription, itemImage) {
return {
date: itemDate,
name: itemName,
description: itemDescription,
image: itemImage,
};
}
// обращение к серверу для получения всех записей (get)
export async function getAllLines() {
const response = await fetch(`${serverUrl}/lines`);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
// обращение к серверу для создания записи (post)
// объект отправляется в теле запроса (body)
export async function createLine(itemDate, itemName, description, image) {
const itemObject = createLineObject(itemDate, itemName, description, image);
const options = {
method: "POST",
body: JSON.stringify(itemObject),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
};
const response = await fetch(`${serverUrl}/lines`, options);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
// обращение к серверу для обновления записи по id (put)
// объект отправляется в теле запроса (body)
// id передается в качестве части пути URL get-запроса
export async function updateLine(id, itemDate, itemName, description, image) {
const itemObject = createLineObject(itemDate, itemName, description, image);
const options = {
method: "PUT",
body: JSON.stringify(itemObject),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
};
const response = await fetch(`${serverUrl}/lines/${id}`, options);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
// обращение к серверу для удаления записи по id (delete)
// id передается в качестве части пути URL get-запроса
export async function deleteLine(id) {
const options = {
method: "DELETE",
};
const response = await fetch(`${serverUrl}/lines/${id}`, options);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}

91
Lab3/js/lines-ui.js Normal file
View File

@ -0,0 +1,91 @@
// модуль для работы с элементами управления
// объект для удобного получения элементов
// при обращении к атрибуту объекта вызывается
// нужная функция для поиска элемента
export const cntrls = {
button: document.getElementById("items-add"),
table: document.querySelector("#items-table tbody"),
form: document.getElementById("items-form"),
lineId: document.getElementById("items-line-id"),
itemDate: document.getElementById("date"),
itemName: document.getElementById("name"),
itemDescription: document.getElementById("description"),
itemImage: document.getElementById("image"),
imagePreview: document.getElementById("image-preview"),
};
// Дефолтное превью
export const imagePlaceholder = "https://via.placeholder.com/310x200";
// функция создает тег option для select
// <option value="" selected>name</option>
export function createItemsOption(name, value = "", isSelected = false) {
const option = document.createElement("option");
option.value = value || "";
option.selected = isSelected;
option.text = name;
return option;
}
// функция создает ссылку (a) для таблицы
// содержимое тега a заполняется необходимой иконкой (icon)
// при нажатии вызывается callback
// ссылка "оборачивается" тегом td
// <td><a href="#" onclick="callback()"><i class="fa-solid icon"></i></a></td>
function createTableAnchor(icon, callback) {
const i = document.createElement("i");
i.classList.add("fa-solid", icon);
const a = document.createElement("a");
a.href = "#";
a.appendChild(i);
a.onclick = (event) => {
// чтобы в URL не добавлялась решетка
event.preventDefault();
event.stopPropagation();
callback();
};
const td = document.createElement("td");
td.appendChild(a);
return td;
}
// функция создает колонку таблицы с текстом value
// <td>value</td>
function createTableColumn(value) {
const td = document.createElement("td");
td.textContent = value;
return td;
}
// функция создает строку таблицы
// <tr>
// <th scope="row">index + 1</th>
// <td>item.items.name</td>
// <td>parseFloat(item.price).toFixed(2))</td>
// <td>item.count</td>
// <td>parseFloat(item.sum).toFixed(2))</td>
// <td><a href="#" onclick="editCallback()"><i class="fa-solid fa-pencil"></i></a></td>
// <td><a href="#" onclick="editPageCallback()"><i class="fa-solid fa-pen-to-square"></i></a></td>
// <td><a href="#" onclick="deleteCallback()"><i class="fa-solid fa-trash"></i></a></td>
// </tr>
export function createTableRow(item, index, editCallback, editPageCallback, deleteCallback) {
const rowNumber = document.createElement("th");
rowNumber.scope = "row";
rowNumber.textContent = index + 1;
const row = document.createElement("tr");
row.id = `line-${item.id}`;
row.appendChild(rowNumber);
row.appendChild(createTableColumn(item.date));
row.appendChild(createTableColumn(item.name));
row.appendChild(createTableColumn(item.description));
// редактировать в модальном окне
row.appendChild(createTableAnchor("fa-pencil", editCallback));
// удаление
row.appendChild(createTableAnchor("fa-trash", deleteCallback));
return row;
}

289
Lab3/js/lines.js Normal file
View File

@ -0,0 +1,289 @@
// модуль с логикой
import { hideUpdateModal, showUpdateModal } from "./lines-modal";
import {
// getAllItemTypes,
createLine, deleteLine, getAllLines, updateLine,
} from "./lines-rest-api";
import {
// createItemsOption,
cntrls, createTableRow, imagePlaceholder,
} from "./lines-ui";
// async function drawItemsSelect() {
// // вызов метода REST API для получения списка типов товаров
// const data = await getAllItemTypes();
// // очистка содержимого select
// // удаляется все, что находится между тегами <select></select>
// // но не атрибуты
// cntrls.itemDate.innerHTML = "";
// // пустое значение
// cntrls.itemDate.appendChild(createItemsOption("Выберите значение", "", true));
// // цикл по результату ответа от сервера
// // используется лямбда-выражение
// // (item) => {} аналогично function(item) {}
// data.forEach((item) => {
// cntrls.itemDate.appendChild(createItemsOption(item.name, item.id));
// });
// }
async function drawLinesTable() {
console.info("Try to load data");
if (!cntrls.table) {
return;
}
// вызов метода REST API для получения всех записей
const data = await getAllLines();
// очистка содержимого table
// удаляется все, что находится между тегами <table></table>
// но не атрибуты
cntrls.table.innerHTML = "";
// цикл по результату ответа от сервера
// используется лямбда-выражение
// (item, index) => {} аналогично function(item, index) {}
data.forEach((item, index) => {
cntrls.table.appendChild(
createTableRow(
item,
index,
// функции передаются в качестве параметра
// это очень удобно, так как аргументы функций доступны только
// в данном месте кода и не передаются в сервисные модули
() => showUpdateModal(item),
() => removeLine(item.id),
),
);
});
}
async function addLine(item, itemName, description, image) {
console.info("Try to add item");
// вызов метода REST API для добавления записи
const data = await createLine(item, itemName, description, image);
console.info("Added");
console.info(data);
// загрузка и заполнение table
drawLinesTable();
}
async function editLine(id, item, itemName, description, image) {
console.info("Try to update item");
// вызов метода REST API для обновления записи
const data = await updateLine(id, item, itemName, description, image);
console.info("Updated");
console.info(data);
// загрузка и заполнение table
drawLinesTable();
}
async function removeLine(id) {
if (!confirm("Do you really want to remove this item?")) {
console.info("Canceled");
return;
}
console.info("Try to remove item");
// вызов метода REST API для удаления записи
const data = await deleteLine(id);
console.info(data);
// загрузка и заполнение table
drawLinesTable();
}
// функция для получения содержимого файла в виде base64 строки
// https://ru.wikipedia.org/wiki/Base64
async function readFile(file) {
const reader = new FileReader();
// создание Promise-объекта для использования функции
// с помощью await (асинхронно) без коллбэков (callback)
// https://learn.javascript.ru/promise
return new Promise((resolve, reject) => {
// 2. "Возвращаем" содержимое когда файл прочитан
// через вызов resolve
// Если не использовать Promise, то всю работу по взаимодействию
// с REST API пришлось бы делать в обработчике (callback) функции
// onloadend
reader.onloadend = () => {
const fileContent = reader.result;
// Здесь могла бы быть работа с REST API
// Чтение заканчивает выполняться здесь
resolve(fileContent);
};
// 3. Возвращаем ошибку
reader.onerror = () => {
// Или здесь в случае ошибки
reject(new Error("oops, something went wrong with the file reader."));
};
// Шаг 1. Сначала читаем файл
// Чтение начинает выполняться здесь
reader.readAsDataURL(file);
});
}
// функция для обновления блока с превью выбранного изображения
async function updateImagePreview() {
// получение выбранного файла
// возможен выбор нескольких файлов, поэтому необходимо получить только первый
const file = cntrls.itemImage.files[0];
// чтение содержимого файла в виде base64 строки
const fileContent = await readFile(file);
console.info("base64 ", fileContent);
// обновление атрибута src для тега img с id image-preview
cntrls.imagePreview.src = fileContent;
}
// Функция для обработки создания и редактирования элементов таблицы через модальное окно
// Если хотите делать через страницу, то удалите эту функцию
export function linesForm() {
console.info("linesForm");
// загрузка и заполнение select со списком товаров
// drawItemsSelect();
// загрузка и заполнение table
drawLinesTable();
// Вызов функции обновления превью изображения при возникновении
// события oncahnge в тэге input с id image
cntrls.itemImage.addEventListener("change", () => updateImagePreview());
// обработчик события нажатия на кнопку для показа модального окна
cntrls.button.addEventListener("click", () => showUpdateModal(null));
// обработчик события отправки формы
// возникает при нажатии на кнопку (button) с типом submit
// кнопка должна находится внутри тега form
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
// отключение стандартного поведения формы при отправке
// при отправке страница обновляется и JS перестает работать
event.preventDefault();
event.stopPropagation();
// если форма не прошла валидацию, то ничего делать не нужно
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
// Получение выбранного пользователем изображения в виде base64 строки
// Если пользователь ничего не выбрал, то не нужно сохранять в БД
// дефолтное изображение
if (cntrls.imagePreview.src !== imagePlaceholder) {
// Загрузка содержимого атрибута src тэга img с id image-preview
// Здесь выполняется HTTP запрос с типом GET
console.info("imagePreview.src");
console.info(cntrls.imagePreview.src);
const result = await fetch(cntrls.imagePreview.src);
// Получение из HTTP-ответа бинарного содержимого
const blob = await result.blob();
// Получение base64 строки для файла
// Здесь выполняется Promise из функции readFile
// Promise позволяет писать линейный код для работы с асинхронными методами
// без использования обработчиков (callback) с помощью await
imageBase64 = await readFile(blob);
}
// получение id строки для редактирования
// это значение содержится в скрытом input
const currentId = cntrls.lineId.value;
// если значение id не задано,
// то необходимо выполнить добавление записи
// иначе обновление записи
if (!currentId) {
await addLine(
cntrls.itemDate.value,
cntrls.itemName.value,
cntrls.itemDescription.value,
imageBase64,
);
} else {
await editLine(
currentId,
cntrls.itemDate.value,
cntrls.itemName.value,
cntrls.itemDescription.value,
imageBase64,
);
}
// после выполнения добавления/обновления модальное окно скрывается
hideUpdateModal();
});
}
/* <div class = "row">
<div class = "col mt-4">
<div class = "rectNews d-flex flex-column">
<img class ="imageNew1" src = "./images/New1.png" alt = "New1" width = "100%">
<div class = "rectNewsTextBox">
<span class = "rectNewsText">
<b>УлГТУ вошёл в топ-250 лучших вузов</b>
</span>
</div>
</div>
</div>
<div class = "col mt-4">
<div class = "rectNews d-flex flex-column position-relative">
<img src = "./images/New2.png" alt = "New2" width="100%">
<div class = "rectNewsTextBox">
<span class = "rectNewsText">
<b>Мосты в будущее будут видны из УлГТУ</b>
</span>
</div>
</div>
</div>
</div>
<div class ="row">
<div class ="col mt-5">
<div class = "rectNews d-flex flex-column position-relative">
<img src = "./images/New3.png" alt = "New3" width="100%">
<div class = "rectNewsTextBox">
<span class = "rectNewsText">
<b>Поправки в системе работы приёмной комиссии</b>
</span>
</div>
</div>
</div>
<div class = "col mt-5">
<div class = "rectNews d-flex flex-column position-relative">
<img src = "./images/New4.png" alt = "New4" width="100%">
<div class = "rectNewsTextBox">
<span class = "rectNewsText">
<b>Студенты возвращаются к учёбе после зимней сессии позже, чем раньше</b>
</span>
</div>
</div>
<span class = "d-flex"><p></p></span>
</div>
</div> */
async function UpdateNew(div1, item) {
const div2 = document.createElement("div");
div2.setAttribute("class", "col mt-4");
const div3 = document.createElement("div");
div3.setAttribute("class", "rectNews d-flex flex-column");
const image = document.createElement("image");
image.setAttribute("src", item.image);
image.setAttribute("width", "100%");
image.setAttribute("alt", item.name);
const div4 = document.createElement("div");
div4.setAttribute("class", "rectNewsTextBox text-center");
const span1 = document.createElement("span");
span1.setAttribute("class", "rectNewsText");
span1.textContent = item.description;
div1.appendChild(div2);
div2.appendChild(div3);
div3.appendChild(image);
div3.appendChild(div4);
div4.appendChild(span1);
}
export async function UpdateNews() {
const data = await getAllLines();
const div1 = document.createElement("div");
div1.setAttribute("class", "row");
data.forEach((item, index) => {
console.info(index);
UpdateNew(div1, item);
if (index % 2 !== 0) {
document.body.appendChild(div1);
}
});
document.body.appendChild(div1);
}

25
Lab3/js/validation.js Normal file
View File

@ -0,0 +1,25 @@
// модуль используется для валидации форма на странице
function validation() {
// поиск всех форма с классом .needs-validation
const forms = document.querySelectorAll("form.needs-validation");
for (let i = 0; i < forms.length; i += 1) {
const form = forms[i];
// для каждой формы добавляется обработчик события отправки
form.addEventListener("submit", (event) => {
// если форма не прошла валидацию
// то выключить стандартное действие
if (!form.checkValidity()) {
event.preventDefault();
// предотвращает распространение preventDefault
// на другие объекты
event.stopPropagation();
}
// добавляет к форме класс was-validated
form.classList.add("was-validated");
});
}
}
export default validation;

7988
Lab3/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
Lab3/package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "int-prog",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "vite",
"serve": "http-server -p 3000 ./dist/",
"build": "vite build",
"rest": "json-server --watch data.json -p 8081",
"dev": "npm-run-all --parallel rest start",
"prod": "npm-run-all build serve"
},
"dependencies": {
"@fortawesome/fontawesome-free": "6.4.2",
"bootstrap": "5.3.2"
},
"devDependencies": {
"eslint": "^8.53.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.28.1",
"http-server": "14.1.1",
"json-server": "0.17.4",
"npm-run-all": "4.1.5",
"vite": "4.4.9"
}
}

77
Lab3/page2.html Normal file
View File

@ -0,0 +1,77 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Об университете</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
</head>
<body class="h-100 d-flex flex-column" background = "./images/BackGr.png">
<header>
<nav class = "headStyleNavBar navbar-text navbar-dark w-100">
<div class = "text-center">
<img src = "./images/logo2.png" alt = "logo2" width="70">
<span class = "headStyle">
<b>Ульяновский Государственный Политехнический Университет</b>
</span>
</div>
</nav>
<nav class="headStyleNavBar2 navbar navbar-expand-md">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav">
<a class="heasdStyle nav-link" href="./index.html"><span class = "headStyle">Новости</span></a>
<a class="heasdStyle nav-link active" href="./page2.html"><span class = "headStyle">Об университете</span></a>
<a class="heasdStyle nav-link" href="./page3.html"><span class = "headStyle">Абитуриенту</span></a>
<a class = "heasdStyle nav-link" href = "./page4.html"><span class = "headStyle">Вход</span></a>
<a class = "nav-link" href = "./page5.html"><span class = "headStyle">Контакты</span></a>
</div>
</div>
</div>
</nav>
</header>
<main class="container-fluid d-flex p-2">
<div class = "rectPage2">
<span class = "mainSt text-center">
<b>История</b>
</span>
<p>
<span class = "stylePage2LargeSymbol">
И</span>
<span class = "stylePage2">
стория Ульяновского государственного технического университета началась в 1957 году,
когда согласно постановлению Совета министров РСФСР от 6 сентября 1957 года и приказу
Министерства высшего образования СССР от 18 сентября 1957 года в городе Ульяновске
был организован вечерний политехнический институт на базе вечернего факультета
Куйбышевского индустриального института.
</span>
</p>
<div class = "styleParagraph">
<span class = "stylePage2">
Было организовано пять кафедр: «Марксизм-ленинизм», «Высшая математика и теоретическая механика»,
«Начертательная геометрия и черчение», «Физика и химия», «Иностранные языки».
</span>
</div>
<div class = "styleParagraph">
<span class = "stylePage2">
Первым ректором вечернего политехнического института стал кандидат технических наук,
доцент Иван Шабанов, его заместителем кандидат технических наук, профессор, доктор
технических наук Леонид Худобин. Штатное расписание института было составлено на 48 человек,
с учетом профессорско-преподавательского состава, из которого только четыре человека имели ученую
степень и звание. Не было ни одного профессора, ни одного доктора наук.
</span>
</div>
</div>
</main>
<footer class=" headStyleNavBar footer mt-5 d-flex flex-shrink-0 justify-content-center align-items-center">
Адреса: ул. Северный Венец, 32; ул. Андрея Блаженного, 3
</footer>
</body>
</html>

93
Lab3/page3.html Normal file
View File

@ -0,0 +1,93 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Абитуриенту</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
</head>
<body class="h-100 d-flex flex-column" background = "./images/BackGr.png">
<header>
<nav class = "headStyleNavBar navbar-text navbar-dark w-100">
<div class = "text-center">
<img src = "./images/logo2.png" alt = "logo2" width="70">
<span class = "headStyle">
<b>Ульяновский Государственный Политехнический Университет</b>
</span>
</div>
</nav>
<nav class="headStyleNavBar2 navbar navbar-expand-md">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav">
<a class="heasdStyle nav-link" href="./index.html"><span class = "headStyle">Новости</span></a>
<a class="heasdStyle nav-link active" href="./page2.html"><span class = "headStyle">Об университете</span></a>
<a class="heasdStyle nav-link" href="./page3.html"><span class = "headStyle">Абитуриенту</span></a>
<a class = "heasdStyle nav-link" href = "./page4.html"><span class = "headStyle">Вход</span></a>
<a class = "nav-link" href = "./page5.html"><span class = "headStyle">Контакты</span></a>
</div>
</div>
</div>
</nav>
</header>
<main class="container p-2 text-center">
<footer class=" headStyleNavBar footer mt-5 d-flex flex-shrink-0 justify-content-center align-items-center">
Адреса: ул. Северный Венец, 32; ул. Андрея Блаженного, 3
</footer>
<label class = "mainSt d-flex justify-content-center" for="direction">
Направление</label>
<input class = "justify-content-md-center mb-3 w-50"
type="search"
id="direction"
name="direction"
required>
<div class="table-direction row justify-content-center">
<table id = "items-table" class="table table-spired col-lg2 w-75">
<thead>
<th scope = "col" class = "w-25">Код</th>
<th scope = "col" id="numb" class ="w-50">Направление</th>
<th scope = "col" class ="w-25">Кафедра</th>
<th scope = "col" class = "w-75">Предметы(ЕГЭ) по выбору</th>
</thead>
<tbody>
<tr>
<td>01.03.04</td>
<td>Мат. Моделирование</td>
<td>Прикладная математика</td>
<td>Иностранный язык, информатика, физика, химия</td>
</tr>
<tr>
<td>09.03.04</td>
<td>Программная инженерия</td>
<td>Информационные системы</td>
<td>Информатика, физика</td>
</tr>
<tr>
<td>02.03.01</td>
<td>Информационные системы и технологии</td>
<td>Измерительно-вычислительные комплексы</td>
<td>Информатика, физика</td>
</tr>
</tbody>
</table>
</div>
</main>
<script type="module">
import validation from "./js/validation";
import { linesForm } from "./js/lines";
document.addEventListener('DOMContentLoaded', () => {
validation();
linesForm();
});
</script>
</body>
</html>

65
Lab3/page4.html Normal file
View File

@ -0,0 +1,65 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Вход</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
</head>
<body class="h-100 d-flex flex-column" background = "./images/BackGr.png">
<header>
<nav class = "headStyleNavBar navbar-text navbar-dark w-100">
<div class = "text-center">
<img src = "./images/logo2.png" alt = "logo2" width="70">
<span class = "headStyle">
<b>Ульяновский Государственный Политехнический Университет</b>
</span>
</div>
</nav>
<nav class="headStyleNavBar2 navbar navbar-expand-md">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav">
<a class="heasdStyle nav-link" href="./index.html"><span class = "headStyle">Новости</span></a>
<a class="heasdStyle nav-link active" href="./page2.html"><span class = "headStyle">Об университете</span></a>
<a class="heasdStyle nav-link" href="./page3.html"><span class = "headStyle">Абитуриенту</span></a>
<a class = "heasdStyle nav-link" href = "./page4.html"><span class = "headStyle">Вход</span></a>
<a class = "nav-link" href = "./page5.html"><span class = "headStyle">Контакты</span></a>
</div>
</div>
</div>
</nav>
</header>
<main class = "container-fluid text-center">
<span class = "mainSt">
<b>Личный кабинет</b>
</span>
<div class="rectpage4 d-flex row justify-content-center">
<form class="col-md-4 m-0 w-auto" action="./page4.html" method="get">
<div class="mb-2">
<label class="form-label" for="login"><b>Логин</b></label>
<input id="login" name="login" class="form-control"
placeholder="dyctator" type="text" required>
</div>
<div class="mb-2">
<label class="form-label" for="password"><b>Пароль</b></label>
<input id="password" name="password" class="form-control" type="password" required>
</div>
<div class="text-center">
<button class="btn btn-primary w-auto" type="button">Войти</button>
</div>
</form>
</div>
</main>
<footer class=" headStyleNavBar footer mt-5 d-flex flex-shrink-0 justify-content-center align-items-center">
Адреса: ул. Северный Венец, 32; ул. Андрея Блаженного, 3
</footer>
</body>
</html>

50
Lab3/page5.html Normal file
View File

@ -0,0 +1,50 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Контакты</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
</head>
<body class="h-100 d-flex flex-column" background = "./images/BackGr.png">
<header>
<nav class = "headStyleNavBar navbar-text navbar-dark w-100">
<div class = "text-center">
<img src = "./images/logo2.png" alt = "logo2" width="70">
<span class = "headStyle">
<b>Ульяновский Государственный Политехнический Университет</b>
</span>
</div>
</nav>
<nav class="headStyleNavBar2 navbar navbar-expand-md">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav">
<a class="heasdStyle nav-link" href="./index.html"><span class = "headStyle">Новости</span></a>
<a class="heasdStyle nav-link active" href="./page2.html"><span class = "headStyle">Об университете</span></a>
<a class="heasdStyle nav-link" href="./page3.html"><span class = "headStyle">Абитуриенту</span></a>
<a class = "heasdStyle nav-link" href = "./page4.html"><span class = "headStyle">Вход</span></a>
<a class = "nav-link" href = "./page5.html"><span class = "headStyle">Контакты</span></a>
</div>
</div>
</div>
</nav>
</header>
<main class = "rectPage5 stsp container-fluid row justify-content-center">
<span class = "mainSt ">Контакты</span>
<span><p><i>Номер приёмной комиссии:</p>+7 925 876 67 43
<p>Номер ректората:</p>+7 925 876 67 43
<p>Электронная почта приёмной комисси:</p>priemnkomulstu@mail.ru</i></span>
</main>
<footer class=" headStyleNavBar footer mt-5 d-flex flex-shrink-0 justify-content-center align-items-center">
Адреса: ул. Северный Венец, 32; ул. Андрея Блаженного, 3
</footer>
</body>
</html>

5
Lab3/readme.md Normal file
View File

@ -0,0 +1,5 @@
npm install
npm start
npm run prod

64
Lab3/reduse.html Normal file
View File

@ -0,0 +1,64 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Абитуриенту</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
</head>
<body class="h-100 d-flex flex-column" background = "./images/BackGr.png">
<header>
<nav class = "headStyleNavBar navbar-text navbar-dark w-100">
<div class = "text-center">
<img src = "./images/logo2.png" alt = "logo2" width="70">
<span class = "headStyle">
<b>Ульяновский Государственный Политехнический Университет</b>
</span>
</div>
</nav>
<nav class="headStyleNavBar2 navbar navbar-expand-md">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav">
<a class="heasdStyle nav-link" href="./index.html"><span class = "headStyle">Новости</span></a>
<a class="heasdStyle nav-link active" href="./page2.html"><span class = "headStyle">Об университете</span></a>
<a class="heasdStyle nav-link" href="./page3.html"><span class = "headStyle">Абитуриенту</span></a>
<a class = "heasdStyle nav-link" href = "./page4.html"><span class = "headStyle">Вход</span></a>
<a class = "nav-link" href = "./page5.html"><span class = "headStyle">Контакты</span></a>
</div>
</div>
</div>
</nav>
</header>
<main class="container p-2 text-center">
<span class = "mainSt">
<b>Новости</b>
</span>
<div class="rectpage4 d-flex row justify-content-center">
<form class="col-md-4 m-0 w-auto" action="./page4.html" method="get">
<div class="mb-2">
<label class="form-label" for="name"><b>Название новости</b></label>
<input id="name" name="name" class="form-control"
placeholder="Например" type="text" required>
</div>
<div class="mb-2">
<label class="form-label" for="image"><b>Изображение</b></label>
<input id="image" name="image" class="form-control" type="file" required>
</div>
<div class="text-center">
<button class="btn btn-primary w-auto" type="button">Добавить новость</button>
</div>
</form>
</div>
</main>
<footer class=" headStyleNavBar footer mt-5 d-flex flex-shrink-0 justify-content-center align-items-center">
Адреса: ул. Северный Венец, 32; ул. Андрея Блаженного, 3
</footer>
</body>
</html>

160
Lab3/style.css Normal file
View File

@ -0,0 +1,160 @@
header nav {
background-color: #3c3c3c;
}
@media (max-width: 770px) {
.rectNews{
width: 270px !important;
height: 175px !important;
margin-left: 45 !important;
margin-top: 30 !important;
}
.rectNewsTextBox{
width : 270px !important;
}
.rectnewsText{
font-size : 13px !important;
}
.footer{
font-size: 12px;
}
.stsp{
margin-top: 0 !important;
}
.rectPage4{
width : 340px !important;
height : 210px !important;
}
}
@media (min-width: 771px){
.tbb1{
justify-content: center !important;
}
}
@media (max-width: 615px){
.rectPage5{
width : 370px !important;
height : 500px !important;
}
}
.headStyle{
color: #FFFFFF
}
.headStyleNavBar{
background-color: #454545;
}
.headStyleNavBar2{
background-color: #575757
}
.stsp{
font-size: 30px;
color: #333333;
text-align: center;
margin-top: 70;
}
.mainSt{
color: #060647;
font-size: 50px;
font-weight: 400;
}
.rectPage2{
color: #FFFFFF;
width: 1470px;
height: 900px;
border : 2px solid #000000;
background-color: #FFFFFF;
opacity: 0.8;
}
.rectPage4{
margin-left: auto;
margin-right: auto;
color: #FFFFFF;
width: 550px;
height: 300px;
border: 2px solid #000000;
background-color: #7c7474;
opacity: 0.8;
}
.rectPage5{
margin-left: auto;
margin-right: auto;
margin-top : auto;
margin-bottom : auto;
width: 600px;
height: 500px;
border: 2px solid #000000;
background-color: #FFFFFF;
opacity: 0.7;
}
.rectNews{
width:310px;
height:200px;
border : 2px solid #2582A3;
border-radius: 8%;
margin-left: 180;
margin-top: 9px;
margin-bottom:25px;
}
.stylePage2{
float : center;
margin-right: 7;
color: #063638;
font-size: 18px
}
.styleParagraph{
border-top: 2px solid #000000;
}
.styleBlack{
color : #000000;
}
.stylePage2LargeSymbol{
float : left;
margin-right: 7;
color: #118D94;
font-size: 50px;
line-height: 52px
}
.rectNewsTextBox{
width : 310px;
min-height : 50px;
border: 2px solid #000000;
background-color: #FFFFFF;
opacity: 0.7;
border-radius: 10% / 40%;
margin-top : 5px;
}
.rectNewsText{
color: #000000;
font-size: 15px;
font-weight: bold;
}
header nav a:hover {
text-decoration: underline;
}
footer {
position : fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
background-color: #9c9c9c;
height: 32px;
color: #ffffff;
font-size: 15px;
}
h1 {
font-size: 1.5em;
}
h2 {
font-size: 1.25em;
}
h3 {
font-size: 1.1em;
}

14
Lab3/vite.config.js Normal file
View File

@ -0,0 +1,14 @@
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
page2: resolve(__dirname, 'page2.html'),
page3: resolve(__dirname, 'page3.html'),
},
},
},
})