Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 54b3ef19f0 | |||
| b7c9882144 | |||
| 1ce9ca12b8 | |||
| 30e3e8e1a7 | |||
| f47194f1fc | |||
| 784d6a34dc | |||
| 9f2283f72c | |||
| 8a6503b7be | |||
| 7ff95f1af1 | |||
| 00a55362b4 | |||
| 9b9d2093e3 | |||
| 00a96a2244 | |||
| cc8422b049 | |||
| 733c13b77e | |||
| 1f8c295e61 | |||
| cd78fa0241 | |||
| 7a55134cf5 | |||
| e0e1062912 | |||
| c54337597c | |||
| 4d53fe830b | |||
| 041f75a828 | |||
| 4ffe93cba0 | |||
| ffb8826ea8 | |||
| 41cf84ee99 | |||
| 4297a3c424 | |||
| d1bca0d0a3 |
19
.eslintrc.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"extends": ["airbnb-base", "prettier"],
|
||||||
|
"plugins": ["prettier", "html"],
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 12,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"prettier/prettier": "error",
|
||||||
|
"no-console": "off",
|
||||||
|
"import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
|
||||||
|
"no-param-reassign": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
2
.gitignore
vendored
@@ -5,6 +5,8 @@
|
|||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
!.vscode/*.code-snippets
|
!.vscode/*.code-snippets
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
# Local History for Visual Studio Code
|
||||||
.history/
|
.history/
|
||||||
|
|||||||
8
.prettierrc
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"singleQuote": false,
|
||||||
|
"printWidth": 120,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"useTabs": false,
|
||||||
|
"endOfLine": "auto"
|
||||||
|
}
|
||||||
23
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
// Используйте IntelliSense, чтобы узнать о возможных атрибутах.
|
||||||
|
// Наведите указатель мыши, чтобы просмотреть описания существующих атрибутов.
|
||||||
|
// Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"name": "Debug",
|
||||||
|
"request": "launch",
|
||||||
|
"url": "http://localhost:5173"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"name": "Start",
|
||||||
|
"request": "launch",
|
||||||
|
"runtimeExecutable": "npm",
|
||||||
|
"runtimeArgs": ["run-script", "start"],
|
||||||
|
"console": "integratedTerminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
37
account.html
@@ -1,37 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Личный кабинет</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="menu">
|
|
||||||
<a href="index.html">
|
|
||||||
<img src="img/manga.png" alt="ЛОГО">
|
|
||||||
</a>
|
|
||||||
<p>надо будет прикрепить, чтобы не двигался при прокрутке</p>
|
|
||||||
<p>Тут возможно будет каталог</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input">
|
|
||||||
<form class="form">
|
|
||||||
<div class="form-row input">
|
|
||||||
<p>Введите номер телефона</p>
|
|
||||||
<input type="tel" placeholder="Телефон" id="number" name="number_acc">
|
|
||||||
</div>
|
|
||||||
<div class="form-row input">
|
|
||||||
<p>Введите пароль</p>
|
|
||||||
<input type="text" placeholder="Пароль" id="password" name="password_acc">
|
|
||||||
</div>
|
|
||||||
<div class="form-row input">
|
|
||||||
<button type="submit">Вход</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
29
author.html
@@ -1,29 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Авторство</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="menu">
|
|
||||||
<a href="index.html">
|
|
||||||
<img src="img/manga.png" alt="ЛОГО">
|
|
||||||
</a>
|
|
||||||
<p>каталог возможно</p>
|
|
||||||
</div>
|
|
||||||
<div class="author">
|
|
||||||
|
|
||||||
<img src="img/ХаяоМиядзаки.png" alt="">
|
|
||||||
<div class="description">
|
|
||||||
<h3>Автор: Хаяо Миядзаки</h3>
|
|
||||||
<p>посвящено автору и тп. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Consequuntur quod harum voluptate architecto, sit eaque, voluptatibus excepturi deleniti consequatur porro vero dolorem dolorum vitae laborum libero et veritatis sapiente a?</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #0f0630;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
color: #f0ffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: bisque;
|
|
||||||
}
|
|
||||||
|
|
||||||
div {
|
|
||||||
background-color: #312b46;
|
|
||||||
width: 1300px;
|
|
||||||
margin: 0 auto 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.author {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
width: 700px;
|
|
||||||
margin-top: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icons {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
|
|
||||||
width: 150px;
|
|
||||||
margin: 0 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.read{
|
|
||||||
width: 500px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
69
html/account.html
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Личный кабинет</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT" crossorigin="anonymous">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
|
||||||
|
<link href="css/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!-- маска на телефон + звездочки на пароль + длина пароля -->
|
||||||
|
|
||||||
|
<body class="bg-dark text-light">
|
||||||
|
|
||||||
|
<header class=" py-3 bg-custom-dark">
|
||||||
|
<div class="container d-flex align-items-center">
|
||||||
|
<a href="index.html" class="me-3">
|
||||||
|
<img src="../img/manga.png" alt="ЛОГО" height="50" />
|
||||||
|
</a>
|
||||||
|
<h1 class="h5 mb-0 text-light">Личный кабинет</h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="container my-5">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-6 bg-secondary p-4 rounded bg-custom-dark">
|
||||||
|
<form id="loginForm">
|
||||||
|
<h2 class="text-center mb-4">
|
||||||
|
<i class="bi bi-person-circle me-2"></i>Вход в систему
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="number" class="form-label">
|
||||||
|
<i class="bi bi-telephone-fill me-2"></i>Номер телефона
|
||||||
|
</label>
|
||||||
|
<input type="tel" class="form-control" id="number" name="number_acc" placeholder="+7 (___) ___-__-__" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<label for="password" class="form-label">
|
||||||
|
<i class="bi bi-lock-fill me-2"></i>Пароль
|
||||||
|
</label>
|
||||||
|
<input type="password" class="form-control" id="password" name="password_acc" placeholder="Пароль" required minlength="4">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-grid">
|
||||||
|
<button type="submit" class="btn btn-warning">
|
||||||
|
<i class="bi bi-box-arrow-in-right me-2"></i>Войти
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="text-center py-4 text-light mt-5 bg-custom-dark">
|
||||||
|
<p><i class="bi bi-journal-text me-2"></i>Все права защищены, 2025</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- маска + карточка пользователя -->
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
74
html/add_book.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Добавить книгу</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT" crossorigin="anonymous">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
|
||||||
|
<link href="css/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-dark text-light"></body>
|
||||||
|
|
||||||
|
<header class=" py-3 bg-custom-dark">
|
||||||
|
<div class="container d-flex align-items-center">
|
||||||
|
<a class="navbar-brand" href="index.html">
|
||||||
|
<img src="img/manga.png" alt="ЛОГО" height="50">
|
||||||
|
</a>
|
||||||
|
<h1 class="h5 ms-4 mb-0 text-light">Добавить книгу</h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="container bg-custom-dark mt-5">
|
||||||
|
<form id="bookForm">
|
||||||
|
<input type="hidden" id="bookId" />
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="title" class="form-label">Название книги</label>
|
||||||
|
<input type="text" id="title" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="description" class="form-label">Описание книги</label>
|
||||||
|
<textarea id="description" class="description"></textarea>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="authorId" class="form-label">Автор</label>
|
||||||
|
<select id="authorId" class="form-select" required></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="statusId" class="form-label">Статус</label>
|
||||||
|
<select id="statusId" class="form-select" required></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="cover" class="form-label">Обложка (файл)</label>
|
||||||
|
<img id="coverPreview" src="" alt="Превью обложки" class="mt-2" style="max-height: 150px; display:none;" />
|
||||||
|
<input type="file" id="cover" name="cover" accept="image/*" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||||
|
<button type="button" id="cancelBtn" class="btn btn-secondary ms-2">Отмена</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="text-center py-4 text-light mt-5 bg-custom-dark">
|
||||||
|
<p><i class="bi bi-journal-text me-2"></i>Все права защищены, 2025</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script type="module" src="../src/main.js"></script>
|
||||||
|
<script type="module" src="/mvc/controller.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
62
html/author.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Авторство</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<link href="css/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-dark text-light">
|
||||||
|
|
||||||
|
<!-- Навигация -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-custom-dark px-3">
|
||||||
|
<a class="navbar-brand" href="index.html">
|
||||||
|
<img src="img/manga.png" alt="ЛОГО" height="50">
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown"
|
||||||
|
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Переключить навигацию">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse ms-3" id="navbarNavDropdown">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<a href="account.html" class="btn btn-outline-warning">Вход</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Информация об авторе -->
|
||||||
|
<main class="container mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4 text-center">
|
||||||
|
<img class="img-fluid rounded" src="img/ХаяоМиядзаки.png" alt="Хаяо Миядзаки">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h3>Автор: Хаяо Миядзаки</h3>
|
||||||
|
<p>Посвящено автору и т.п. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur quod harum
|
||||||
|
voluptate architecto, sit eaque, voluptatibus excepturi deleniti consequatur porro vero dolorem dolorum
|
||||||
|
vitae laborum libero et veritatis sapiente a?</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- Футер -->
|
||||||
|
<footer class="bg-custom-dark text-light text-center py-4 mt-5">
|
||||||
|
<p>Спасибо, что посетили наш сайт, если возникли вопросы, обращайтесь к нам на почту <a href="mailto:manga@manga.scom" class="text-warning">manga@manga.scom</a></p>
|
||||||
|
<p>Если вас интересуют наши соц.сети, то вот они:</p>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<a href="https://vk.com/ded_moroz1509" class="me-3">
|
||||||
|
<img src="img/VK0.png" alt="VK" height="30">
|
||||||
|
</a>
|
||||||
|
<!-- Добавить другие иконки соцсетей здесь -->
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- JS Bootstrap -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
52
html/css/style.css
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
.bg-custom-dark {
|
||||||
|
background-color: #0f0630 !important;
|
||||||
|
color: #f0ffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-block {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #f0ffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-fluid {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-news .card {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 120px;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow: hidden; /* Запретить скролл */
|
||||||
|
resize: none; /* Запретить изменение размера */
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
64
html/database/data.json
Normal file
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 558 KiB After Width: | Height: | Size: 558 KiB |
BIN
html/img/VK.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
html/img/VK0.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 453 KiB After Width: | Height: | Size: 453 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
116
html/index.html
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Манга онлайн</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<link href="css/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-dark">
|
||||||
|
|
||||||
|
<!-- Навигация -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-custom-dark px-3">
|
||||||
|
<a class="navbar-brand" href="index.html">
|
||||||
|
<img src="img/manga.png" alt="ЛОГО" height="50">
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown"
|
||||||
|
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Переключить навигацию">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse ms-3" id="navbarNavDropdown">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="catalogDropdown" role="button" data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false">
|
||||||
|
Каталог
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="catalogDropdown">
|
||||||
|
<li><a class="dropdown-item" href="#">Жанр 1</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Жанр 2</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Жанр 3</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Жанр 4</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<a href="account.html" class="btn btn-outline-warning">Вход</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Основное содержимое -->
|
||||||
|
<div class="container mt-5 bg-custom-dark p-3 rounded">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h3>Наши произведения</h3>
|
||||||
|
<a href="add_book.html" class="btn btn-success">
|
||||||
|
<i class="bi bi-plus-circle me-2"></i>Добавить книгу
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="booksContainer" class="row row-cols-1 row-cols-md-3 g-3">
|
||||||
|
<!-- Здесь динамически будут отображаться книги -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Новости -->
|
||||||
|
<div class="news mt-5">
|
||||||
|
<h3 class="text-center">Наши новости:</h3>
|
||||||
|
<section class="row row-cols-1 row-cols-sm-3 row-cols-md-3 g-4">
|
||||||
|
<div class="col d-flex justify-content-center">
|
||||||
|
<div class="card">
|
||||||
|
<a href="news.html">
|
||||||
|
<img src="img/новость.jpg" class="card-img-top" alt="Новость 1">
|
||||||
|
</a>
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">Новость 1</h4>
|
||||||
|
<p class="card-text">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Libero laborum possimus itaque quibusdam beatae ipsam odit sed? Vel blanditiis repellendus, ea nam, incidunt odio sit amet sequi nihil, laudantium aspernatur!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col d-flex justify-content-center">
|
||||||
|
<div class="card">
|
||||||
|
<a href="news.html">
|
||||||
|
<img src="img/новость.jpg" class="card-img-top" alt="Новость 2">
|
||||||
|
</a>
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">Новость 2</h4>
|
||||||
|
<p class="card-text">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Libero laborum possimus itaque quibusdam beatae ipsam odit sed? Vel blanditiis repellendus, ea nam, incidunt odio sit amet sequi nihil, laudantium aspernatur!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col d-flex justify-content-center">
|
||||||
|
<div class="card">
|
||||||
|
<a href="news.html">
|
||||||
|
<img src="img/новость.jpg" class="card-img-top" alt="Новость 3">
|
||||||
|
</a>
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">Новость 3</h4>
|
||||||
|
<p class="card-text">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Libero laborum possimus itaque quibusdam beatae ipsam odit sed? Vel blanditiis repellendus, ea nam, incidunt odio sit amet sequi nihil, laudantium aspernatur!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Футер -->
|
||||||
|
<footer class="bg-custom-dark text-light text-center py-4 mt-5">
|
||||||
|
<p>Спасибо, что посетили наш сайт, если возникли вопросы, обращайтесь к нам на почту <a href="mailto:manga@manga.scom" class="text-warning">manga@manga.scom</a></p>
|
||||||
|
<p>Если вас интересуют наши соц.сети, то вот они:</p>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<a href="https://vk.com/ded_moroz1509" class="me-3">
|
||||||
|
<img src="img/VK0.png" alt="VK" height="30">
|
||||||
|
</a>
|
||||||
|
<!-- Добавьте другие иконки соцсетей здесь -->
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- JS Bootstrap -->
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script type="module" src="../src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
76
html/manga.html
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Манга</title>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT" crossorigin="anonymous">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
|
||||||
|
<link href="css/style.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-dark text-light d-flex flex-column min-vh-100">
|
||||||
|
|
||||||
|
<!-- Навигация -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-custom-dark px-3">
|
||||||
|
<a class="navbar-brand" href="index.html">
|
||||||
|
<img src="img/manga.png" alt="ЛОГО" height="50">
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown"
|
||||||
|
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Переключить навигацию">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse ms-3" id="navbarNavDropdown">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
</ul>
|
||||||
|
<a href="account.html" class="btn btn-outline-warning">Вход</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Контент -->
|
||||||
|
<main class="container my-5 flex-grow-1">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8 text-center">
|
||||||
|
<figure class="figure">
|
||||||
|
<img src="img/заглушка.jpg" class="figure-img img-fluid rounded" alt="Заглушка">
|
||||||
|
<figcaption class="figure-caption text-light">Заглушка</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<p class="mt-4">Здесь будет сама инфа о манге</p>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center gap-3 mt-3">
|
||||||
|
<a href="author.html" class="btn btn-primary"><i class="bi bi-person-lines-fill me-2"></i>Про автора</a>
|
||||||
|
<a href="reading.html" class="btn btn-success"><i class="bi bi-book me-2"></i>Читать</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="bg-custom-dark text-light text-center py-4">
|
||||||
|
<div class="container">
|
||||||
|
<p>Спасибо, что посетили наш сайт, если возникли вопросы, обращайтесь к нам на почту
|
||||||
|
<a href="mailto:manga@manga.scom" class="text-warning">manga@manga.scom</a>
|
||||||
|
</p>
|
||||||
|
<p>Если вас интересуют наши соц.сети, то вот они:</p>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<a href="https://vk.com/ded_moroz1509" class="me-3">
|
||||||
|
<img src="img/VK0.png" alt="VK" height="30">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- JS Bootstrap -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Твой модуль JS -->
|
||||||
|
<script type="modal" src="/html/src/main.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
16
html/mvc/api/client.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
const BASE_URL = "http://localhost:5174"; // Порт json-server
|
||||||
|
|
||||||
|
async function request(path, method = "GET", body = null) {
|
||||||
|
const options = { method, headers: { "Content-Type": "application/json" } };
|
||||||
|
if (body) options.body = JSON.stringify(body);
|
||||||
|
|
||||||
|
const response = await fetch(`${BASE_URL}/${path}`, options);
|
||||||
|
if (!response.ok) throw new Error(`Ошибка запроса: ${response.status}`);
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getAllItems = (entity) => request(entity);
|
||||||
|
export const getItem = (entity, id) => request(`${entity}/${id}`);
|
||||||
|
export const createItem = (entity, data) => request(entity, "POST", data);
|
||||||
|
export const updateItem = (entity, id, data) => request(`${entity}/${id}`, "PATCH", data);
|
||||||
|
export const deleteItem = (entity, id) => request(`${entity}/${id}`, "DELETE");
|
||||||
128
html/mvc/controller.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import model from "./model";
|
||||||
|
import view from "./view";
|
||||||
|
|
||||||
|
const controller = {
|
||||||
|
// Инициализация главной страницы (index.html)
|
||||||
|
async initIndexPage() {
|
||||||
|
await this.loadAuthorsAndStatuses();
|
||||||
|
await this.loadAndRenderBooks();
|
||||||
|
|
||||||
|
// Делегирование событий на контейнер с книгами
|
||||||
|
const booksContainer = document.getElementById("booksContainer");
|
||||||
|
if (booksContainer) {
|
||||||
|
booksContainer.addEventListener("click", async (e) => {
|
||||||
|
const { id } = e.target.dataset;
|
||||||
|
if (e.target.classList.contains("delete-btn")) {
|
||||||
|
if (confirm("Удалить книгу?")) {
|
||||||
|
try {
|
||||||
|
await model.deleteBook(id);
|
||||||
|
view.showAlert("Книга удалена");
|
||||||
|
await this.loadAndRenderBooks();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
view.showAlert("Ошибка при удалении книги", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (e.target.classList.contains("edit-btn")) {
|
||||||
|
// При редактировании перенаправляем на add_book.html?id=...
|
||||||
|
window.location.href = `add_book.html?id=${id}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Инициализация страницы добавления/редактирования (add_book.html)
|
||||||
|
async initAddBookPage() {
|
||||||
|
await this.loadAuthorsAndStatuses();
|
||||||
|
view.bindCoverInput();
|
||||||
|
|
||||||
|
// Если есть id в URL — значит редактирование
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const editingId = params.get("id");
|
||||||
|
if (editingId) {
|
||||||
|
try {
|
||||||
|
const book = await model.getBook(editingId);
|
||||||
|
view.fillBookForm(book);
|
||||||
|
document.getElementById("bookId").value = editingId;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
view.showAlert("Ошибка при загрузке книги", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сохранение формы
|
||||||
|
const bookForm = document.getElementById("bookForm");
|
||||||
|
if (bookForm) {
|
||||||
|
bookForm.addEventListener("submit", async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
const bookData = await view.getBookFormData();
|
||||||
|
const id = document.getElementById("bookId").value;
|
||||||
|
if (id) {
|
||||||
|
await model.updateBook(id, bookData);
|
||||||
|
view.showAlert("Книга обновлена");
|
||||||
|
} else {
|
||||||
|
await model.addBook(bookData);
|
||||||
|
view.showAlert("Книга добавлена");
|
||||||
|
}
|
||||||
|
view.resetBookForm();
|
||||||
|
document.getElementById("bookId").value = "";
|
||||||
|
window.location.href = "index.html";
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
view.showAlert("Ошибка при сохранении книги", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Кнопка "Отмена"
|
||||||
|
const cancelBtn = document.getElementById("cancelBtn");
|
||||||
|
if (cancelBtn) {
|
||||||
|
cancelBtn.addEventListener("click", () => {
|
||||||
|
window.location.href = "index.html";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Загрузка авторов и статусов для селектов
|
||||||
|
async loadAuthorsAndStatuses() {
|
||||||
|
try {
|
||||||
|
const authors = await model.getAuthors();
|
||||||
|
const statuses = await model.getStatuses();
|
||||||
|
const authorSelect = document.getElementById("authorId");
|
||||||
|
const statusSelect = document.getElementById("statusId");
|
||||||
|
if (authorSelect) view.renderAuthorOptions(authors, authorSelect);
|
||||||
|
if (statusSelect) view.renderStatusOptions(statuses, statusSelect);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
view.showAlert("Ошибка при загрузке авторов или статусов", true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Загрузка и рендер книг на главной
|
||||||
|
async loadAndRenderBooks() {
|
||||||
|
try {
|
||||||
|
const books = await model.getBooks();
|
||||||
|
const authors = await model.getAuthors();
|
||||||
|
const statuses = await model.getStatuses();
|
||||||
|
|
||||||
|
const booksWithDetails = books.map((book) => {
|
||||||
|
const author = authors.find((a) => String(a.id) === String(book.authorId));
|
||||||
|
const status = statuses.find((s) => String(s.id) === String(book.statusId));
|
||||||
|
return {
|
||||||
|
...book,
|
||||||
|
authorName: author ? author.name : "Неизвестен",
|
||||||
|
statusName: status ? status.name : "Неизвестен",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const booksContainer = document.getElementById("booksContainer");
|
||||||
|
if (booksContainer) view.renderBooks(booksWithDetails, booksContainer);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
view.showAlert("Ошибка при загрузке книг", true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default controller;
|
||||||
39
html/mvc/model.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { getAllItems, getItem, createItem, updateItem, deleteItem } from "./api/client";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// Книги
|
||||||
|
getBooks() {
|
||||||
|
return getAllItems("books");
|
||||||
|
},
|
||||||
|
getBook(id) {
|
||||||
|
return getItem("books", id);
|
||||||
|
},
|
||||||
|
addBook(book) {
|
||||||
|
return createItem("books", book);
|
||||||
|
},
|
||||||
|
updateBook(id, data) {
|
||||||
|
return updateItem("books", id, data);
|
||||||
|
},
|
||||||
|
deleteBook(id) {
|
||||||
|
return deleteItem("books", id);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Авторы
|
||||||
|
getAuthors() {
|
||||||
|
return getAllItems("authors");
|
||||||
|
},
|
||||||
|
|
||||||
|
// Статусы
|
||||||
|
getStatuses() {
|
||||||
|
return getAllItems("statuses");
|
||||||
|
},
|
||||||
|
addStatus(status) {
|
||||||
|
return createItem("statuses", status);
|
||||||
|
},
|
||||||
|
updateStatus(id, data) {
|
||||||
|
return updateItem("statuses", id, data);
|
||||||
|
},
|
||||||
|
deleteStatus(id) {
|
||||||
|
return deleteItem("statuses", id);
|
||||||
|
},
|
||||||
|
};
|
||||||
148
html/mvc/view.js
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
const view = {
|
||||||
|
renderAuthorOptions(authors, selectElement) {
|
||||||
|
selectElement.innerHTML = '<option value="">Выберите автора</option>';
|
||||||
|
authors.forEach((author) => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = author.id;
|
||||||
|
option.textContent = author.name;
|
||||||
|
selectElement.appendChild(option);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderStatusOptions(statuses, selectElement) {
|
||||||
|
selectElement.innerHTML = '<option value="">Выберите статус</option>';
|
||||||
|
statuses.forEach((status) => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = status.id;
|
||||||
|
option.textContent = status.name;
|
||||||
|
selectElement.appendChild(option);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderBooks(books, container) {
|
||||||
|
container.innerHTML = "";
|
||||||
|
books.forEach((book) => {
|
||||||
|
// определяем класс для статуса
|
||||||
|
let statusClass = "text-muted fw-bold";
|
||||||
|
switch ((book.statusName || "").toLowerCase()) {
|
||||||
|
case "вышла":
|
||||||
|
statusClass = "text-success fw-bold";
|
||||||
|
break;
|
||||||
|
case "не вышла":
|
||||||
|
statusClass = "text-danger fw-bold";
|
||||||
|
break;
|
||||||
|
case "не переведена":
|
||||||
|
statusClass = "text-warning fw-bold";
|
||||||
|
break;
|
||||||
|
case "прочитана":
|
||||||
|
statusClass = "text-primary fw-bold";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusClass = "text-muted fw-bold";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.className = "card mb-3";
|
||||||
|
div.innerHTML = `
|
||||||
|
<a href="manga.html">
|
||||||
|
<img src="${book.cover || "img/заглушка.jpg"}" class="card-img-top shadow mt-2" alt="Обложка книги" style="max-height:300px; object-fit:contain; ">
|
||||||
|
</a>
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">${book.title}</h5>
|
||||||
|
<p class="card-text">${book.description}</p>
|
||||||
|
<p class="card-text"><small class="text-muted">Автор: ${book.authorName || "Неизвестен"}</small></p>
|
||||||
|
<p class="card-text"><small class="${statusClass}">Статус: ${book.statusName || "Неизвестен"}</small></p>
|
||||||
|
<button data-id="${book.id}" class="btn btn-danger btn-sm delete-btn">Удалить</button>
|
||||||
|
<a href="add_book.html?id=${book.id}" class="btn btn-warning btn-sm edit-btn">Редактировать</a>
|
||||||
|
</div>`;
|
||||||
|
container.appendChild(div);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
bindCoverInput() {
|
||||||
|
const coverInput = document.getElementById("cover");
|
||||||
|
const coverPreview = document.getElementById("coverPreview");
|
||||||
|
|
||||||
|
coverInput.addEventListener("change", () => {
|
||||||
|
const file = coverInput.files[0];
|
||||||
|
if (!file) {
|
||||||
|
coverPreview.style.display = "none";
|
||||||
|
coverPreview.src = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
coverPreview.src = e.target.result;
|
||||||
|
coverPreview.style.display = "block";
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async getBookFormData() {
|
||||||
|
const coverInput = document.getElementById("cover");
|
||||||
|
let coverData = "";
|
||||||
|
|
||||||
|
if (coverInput.files.length > 0) {
|
||||||
|
coverData = await new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => resolve(reader.result);
|
||||||
|
reader.onerror = () => reject(new Error("Ошибка чтения файла обложки"));
|
||||||
|
reader.readAsDataURL(coverInput.files[0]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Если форма редактирования, и файл не поменяли, можно брать существующий cover (или пустую строку)
|
||||||
|
coverData = document.getElementById("cover").dataset.currentCover || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: document.getElementById("title").value.trim(),
|
||||||
|
description: document.getElementById("description").value.trim(),
|
||||||
|
authorId: parseInt(document.getElementById("authorId").value, 10),
|
||||||
|
statusId: parseInt(document.getElementById("statusId").value, 10),
|
||||||
|
cover: coverData,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
fillBookForm(book) {
|
||||||
|
document.getElementById("title").value = book.title || "";
|
||||||
|
document.getElementById("description").value = book.description || "";
|
||||||
|
document.getElementById("authorId").value = book.authorId || "";
|
||||||
|
document.getElementById("statusId").value = book.statusId || "";
|
||||||
|
|
||||||
|
// Запоминаем текущую обложку в дата-атрибут для использования при сохранении
|
||||||
|
const coverInput = document.getElementById("cover");
|
||||||
|
coverInput.value = ""; // Очистить input файл
|
||||||
|
coverInput.dataset.currentCover = book.cover || "";
|
||||||
|
|
||||||
|
// Показываем превью
|
||||||
|
const coverPreview = document.getElementById("coverPreview");
|
||||||
|
if (book.cover) {
|
||||||
|
coverPreview.src = book.cover;
|
||||||
|
coverPreview.style.display = "block";
|
||||||
|
} else {
|
||||||
|
coverPreview.style.display = "none";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resetBookForm() {
|
||||||
|
document.getElementById("bookForm").reset();
|
||||||
|
const coverPreview = document.getElementById("coverPreview");
|
||||||
|
coverPreview.style.display = "none";
|
||||||
|
coverPreview.src = "";
|
||||||
|
},
|
||||||
|
|
||||||
|
showAlert(message, isError = false) {
|
||||||
|
alert(isError ? `Ошибка: ${message}` : `Успех: ${message}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
confirm(message) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const result = confirm(message);
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default view;
|
||||||
62
html/news.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Новость</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
|
||||||
|
<link href="css/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-dark">
|
||||||
|
|
||||||
|
<!-- Навигация -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-custom-dark px-3">
|
||||||
|
<a class="navbar-brand" href="index.html">
|
||||||
|
<img src="img/manga.png" alt="ЛОГО" height="50">
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown"
|
||||||
|
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Переключить навигацию">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse ms-3" id="navbarNavDropdown">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<a href="account.html" class="btn btn-outline-warning">Вход</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container container-news mt-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card">
|
||||||
|
<img src="img/новость.jpg" class="card-img-top" alt="Новость">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Новость</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Beatae exercitationem eligendi error.
|
||||||
|
Architecto voluptatum eaque, nostrum ea a consequuntur, deleniti dolor provident sequi dicta culpa
|
||||||
|
magnam delectus amet distinctio autem?
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<footer class="bg-custom-dark text-center py-4 text-light mt-5 bg-custom-dark">
|
||||||
|
<p><i class="bi bi-journal-text me-2"></i>Все права защищены, 2025</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Подключаем Bootstrap JS и Popper -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
61
html/reading.html
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Читать мангу...</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<link href="css/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-dark text-light">
|
||||||
|
|
||||||
|
<!-- Навигация -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-custom-dark px-3">
|
||||||
|
<a class="navbar-brand" href="index.html">
|
||||||
|
<img src="img/manga.png" alt="ЛОГО" height="50">
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown"
|
||||||
|
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Переключить навигацию">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse ms-3" id="navbarNavDropdown">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<a href="account.html" class="btn btn-outline-warning">Вход</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Чтение манги -->
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<h3>Читать мангу...</h3>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<img class="img-reading mx-2" src="img/SL1.png" alt="Манга страница 1">
|
||||||
|
<img class="img-reading mx-2" src="img/SL2.png" alt="Манга страница 2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Футер -->
|
||||||
|
<footer class="bg-custom-dark text-light text-center py-4 mt-5">
|
||||||
|
<p>Спасибо, что посетили наш сайт, если возникли вопросы, обращайтесь к нам на почту <a href="mailto:manga@manga.scom" class="text-warning">manga@manga.scom</a></p>
|
||||||
|
<p>Если вас интересуют наши соц.сети, то вот они:</p>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<a href="https://vk.com/ded_moroz1509" class="me-3">
|
||||||
|
<img src="img/VK0.png" alt="VK" height="30">
|
||||||
|
</a>
|
||||||
|
<!-- Добавить другие иконки соцсетей здесь -->
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- JS Bootstrap -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
17
html/src/main.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import "bootstrap";
|
||||||
|
import "bootstrap-icons/font/bootstrap-icons.css";
|
||||||
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import Inputmask from "inputmask";
|
||||||
|
import controller from "../mvc/controller";
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const phoneInput = document.getElementById("number");
|
||||||
|
if (phoneInput) {
|
||||||
|
Inputmask("+7 (999) 999-99-99").mask(phoneInput);
|
||||||
|
}
|
||||||
|
if (document.getElementById("booksContainer")) {
|
||||||
|
controller.initIndexPage();
|
||||||
|
} else if (document.getElementById("bookForm")) {
|
||||||
|
controller.initAddBookPage();
|
||||||
|
}
|
||||||
|
});
|
||||||
112
index.html
@@ -1,112 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Заголовок страницы</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="menu">
|
|
||||||
<a href="index.html">
|
|
||||||
<img src="img/manga.png" alt="ЛОГО">
|
|
||||||
</a>
|
|
||||||
<p>надо будет прикрепить, чтобы не двигался при прокрутке</p>
|
|
||||||
<p>Тут возможно будет каталог</p>
|
|
||||||
<a href="account.html">вход</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="main">
|
|
||||||
<h3>Наши произведения</h3>
|
|
||||||
<section class="icons"><!--секция с обложками-->
|
|
||||||
<div class="icon">
|
|
||||||
<a href="manga.html">
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="icon">
|
|
||||||
<a href="manga.html">
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="icon">
|
|
||||||
<a href="manga.html">
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="icon">
|
|
||||||
<a href="manga.html">
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="icon">
|
|
||||||
<a href="manga.html">
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="icon">
|
|
||||||
<a href="manga.html">
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="icon">
|
|
||||||
<a href="manga.html">
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="news">
|
|
||||||
<h3>Наши новости:</h3>
|
|
||||||
<section class="card-news"><!--секция с новостями-->
|
|
||||||
<div class="card">
|
|
||||||
<a href="news.html">
|
|
||||||
<img src="img/новость.jpg" alt="">
|
|
||||||
</a>
|
|
||||||
<div class="description-news">
|
|
||||||
<h4>Новость 1</h4>
|
|
||||||
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Libero laborum possimus itaque quibusdam beatae ipsam odit sed? Vel blanditiis repellendus,
|
|
||||||
ea nam, incidunt odio sit amet sequi nihil, laudantium aspernatur!</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<a href="news.html">
|
|
||||||
<img src="img/новость.jpg" alt="">
|
|
||||||
</a>
|
|
||||||
<div class="description-news">
|
|
||||||
<h4>Новость 2</h4>
|
|
||||||
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Libero laborum possimus itaque quibusdam beatae ipsam odit sed? Vel blanditiis repellendus,
|
|
||||||
ea nam, incidunt odio sit amet sequi nihil, laudantium aspernatur!</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
32
manga.html
@@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>сама манга?</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="menu">
|
|
||||||
<a href="index.html">
|
|
||||||
<img src="img/manga.png" alt="ЛОГО">
|
|
||||||
</a>
|
|
||||||
<p>надо будет прикрепить, чтобы не двигался при прокрутке</p>
|
|
||||||
<p>Тут возможно будет каталог</p>
|
|
||||||
<a href="account.html">вход</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<figure>
|
|
||||||
<img src="img/заглушка.jpg" alt="">
|
|
||||||
<figcaption>Заглушка</figcaption>
|
|
||||||
</figure>
|
|
||||||
<p>здесь будет сама инфа о манге</p>
|
|
||||||
<a href="author.html">про автора</a>
|
|
||||||
<a href="reading.html">Читать</a>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
27
news.html
@@ -1,27 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Новость</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="menu">
|
|
||||||
<a href="index.html">
|
|
||||||
<img src="img/manga.png" alt="ЛОГО">
|
|
||||||
</a>
|
|
||||||
<p>надо будет прикрепить, чтобы не двигался при прокрутке</p>
|
|
||||||
<p>Тут возможно будет каталог</p>
|
|
||||||
<a href="account.html">вход</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<img src="img/новость.jpg" alt="">
|
|
||||||
<p>Новость Lorem, ipsum dolor sit amet consectetur adipisicing elit. Beatae exercitationem eligendi error. Architecto voluptatum eaque, nostrum ea a consequuntur, deleniti dolor provident sequi dicta culpa magnam delectus amet distinctio autem?</p>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
5672
package-lock.json
generated
Normal file
31
package.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "int-prog",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"start": "npm-run-all --parallel backend vite",
|
||||||
|
"vite": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"serve": "http-server -p 3000 ./html/",
|
||||||
|
"backend": "json-server ./html/database/data.json -p 5174",
|
||||||
|
"prod": "npm-run-all build serve --parallel backend serve",
|
||||||
|
"lint": "eslint . --ext js --report-unused-disable-directives --max-warnings 0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bootstrap": "5.3.3",
|
||||||
|
"bootstrap-icons": "^1.11.3",
|
||||||
|
"inputmask": "^5.0.9"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "8.56.0",
|
||||||
|
"eslint-config-airbnb-base": "15.0.0",
|
||||||
|
"eslint-config-prettier": "10.0.2",
|
||||||
|
"eslint-plugin-html": "8.1.2",
|
||||||
|
"eslint-plugin-import": "2.31.0",
|
||||||
|
"eslint-plugin-prettier": "5.2.3",
|
||||||
|
"http-server": "14.1.1",
|
||||||
|
"json-server": "^1.0.0-beta.3",
|
||||||
|
"npm-run-all": "4.1.5",
|
||||||
|
"vite": "6.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
28
reading.html
@@ -1,28 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Читать мангу...</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="menu">
|
|
||||||
<a href="index.html">
|
|
||||||
<img src="img/manga.png" alt="ЛОГО">
|
|
||||||
</a>
|
|
||||||
<p>надо будет прикрепить, чтобы не двигался при прокрутке</p>
|
|
||||||
<p>Тут возможно будет каталог</p>
|
|
||||||
<a href="account.html">вход</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="read">
|
|
||||||
<img src="img/SL1.png" alt="">
|
|
||||||
<img src="img/SL2.png" alt="">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
19
vite.config.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { resolve } from "path";
|
||||||
|
import { defineConfig } from "vite";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
root: resolve(__dirname, "html"),
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
input: {
|
||||||
|
main: resolve(__dirname, "html/index.html"),
|
||||||
|
page2: resolve(__dirname, "html/account.html"),
|
||||||
|
page3: resolve(__dirname, "html/author.html"),
|
||||||
|
page4: resolve(__dirname, "html/manga.html"),
|
||||||
|
page5: resolve(__dirname, "html/news.html"),
|
||||||
|
page6: resolve(__dirname, "html/reading.html"),
|
||||||
|
page7: resolve(__dirname, "add_book"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||