5 Commits
1Lab ... Lab4

Author SHA1 Message Date
050e6f613d Загрузить файлы в «/» 2025-05-25 20:23:53 +04:00
3f9975f5dc Загрузить файлы в «/» 2025-05-08 14:08:39 +04:00
Roma
570546b918 4 лабараторная 2025-05-08 13:35:15 +04:00
Roma
20608c44bf 4 лабараторная 2025-04-20 19:05:00 +04:00
RomaEredavkin
e80a75b8c0 оно работает 2 лабараторная 2025-03-21 14:09:55 +04:00
98 changed files with 12889 additions and 477 deletions

17
.eslintrc.json Normal file
View File

@@ -0,0 +1,17 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:prettier/recommended"
],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"prettier/prettier": "error"
}
}

16
.gitignore vendored
View File

@@ -1,14 +1,2 @@
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
node_modules
node_modules

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"singleQuote": true,
"trailingComma": "all",
"tabWidth": 2
}

View File

@@ -1,44 +1,69 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкийАльбом</title>
<link rel="stylesheet" href="css/Style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкийАльбом</title>
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/node_modules/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<img class="cover" src="src/cover.png" alt="Логотип SweetyDisk"/>
<div class="table-container">
<table>
<tr>
<td><a href="File.html" class="button">Файлы</a></td>
</tr>
<tr>
<td><a href="Photo.html" class="button">Фото</a></td>
</tr>
<tr>
<td><a href="Album.html" class="button">Альбом</a></td>
</tr>
<tr>
<td><a href="Basket.html" class="button">Корзина</a></td>
</tr>
<tr>
<td><a href="index.html" class="button">На главную</a></td>
</tr>
</table>
<button class="upload-button" onclick="document.getElementById('file-input').click()">Загрузить</button>
<input type="file" id="file-input" style="display: none;">
<a href="Password.html" class="login-button">Вход</a>
</div>
<div class="file-container">
<img src="src/Album.png">
<img src="src/Album1.png">
<img src="src/Album2.png">
</div>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none" accept="image/*">
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Ваши Альбомы</h2>
<div class="album-container row row-cols-1 row-cols-md-3 g-4" id="albumContainer"></div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@@ -1,46 +1,65 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкаяКорзинка</title>
<link rel="stylesheet" href="css/Style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Корзина</title>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./node_modules/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<img class="cover" src="src/cover.png" alt="Логотип SweetyDisk"/>
<div class="table-container">
<table>
<tr>
<td><a href="File.html" class="button">Файлы</a></td>
</tr>
<tr>
<td><a href="Photo.html" class="button">Фото</a></td>
</tr>
<tr>
<td><a href="Album.html" class="button">Альбом</a></td>
</tr>
<tr>
<td><a href="Basket.html" class="button">Корзина</a></td>
</tr>
<tr>
<td><a href="index.html" class="button">На главную</a></td>
</tr>
</table>
<button class="upload-button" onclick="document.getElementById('file-input').click()">Загрузить</button>
<input type="file" id="file-input" style="display: none;">
<a href="Password.html" class="login-button">Вход</a>
</div>
<div class="file-container">
<img src="src/Cart.png">
<img src="src/Cart1.png">
<img src="src/Cart2.png">
</div>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 d-flex flex-column flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<a href="./index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="./File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="./Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="./Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
<a href="./Basket.html" class="btn btn-pink"><i class="bi bi-trash"></i> Корзина</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Корзина</h2>
<div class="mb-4 text-center">
<button class="btn btn-danger" id="clear-basket">Очистить корзину</button>
</div>
<div class="basket-container row row-cols-1 row-cols-md-3 g-4" id="basketContainer">
<!-- Элементы корзины будут добавлены через JavaScript -->
</div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>

110
File.html
View File

@@ -1,53 +1,69 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сладкие Файлы</title>
<link rel="stylesheet" href="css/Style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сладкие Файлы</title>
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/node_modules/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<img class="cover" src="src/cover.png" alt="Логотип SweetyDisk"/>
<div class="table-container">
<table>
<tr>
<td><a href="File.html" class="button">Файлы</a></td>
</tr>
<tr>
<td><a href="Photo.html" class="button">Фото</a></td>
</tr>
<tr>
<td><a href="Album.html" class="button">Альбом</a></td>
</tr>
<tr>
<td><a href="Basket.html" class="button">Корзина</a></td>
</tr>
<tr>
<td><a href="index.html" class="button">На главную</a></td>
</tr>
</table>
<button class="upload-button" onclick="document.getElementById('file-input').click()">Загрузить</button>
<input type="file" id="file-input" style="display: none;">
<a href="Password.html" class="login-button">Вход</a>
</div>
<div class="file-container">
<div class="image-wrapper">
<img src="src/File.png">
<p>photo.png</p>
</div>
<div class="image-wrapper">
<img src="src/File2.png">
<p>Отп зачет.docx</p>
</div>
<div class="image-wrapper">
<img src="src/File3.png">
<p>Яндекс Музыка</p>
</div>
</div>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none">
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Ваши Файлы</h2>
<div class="file-container row row-cols-1 row-cols-md-3 g-4" id="fileContainer"></div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@@ -1,21 +1,82 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкаяРегистрация</title>
<link rel="stylesheet" href="css/StylePass.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкаяРегистрация</title>
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/node_modules/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 d-flex flex-column flex-grow-1">
<!-- Шапка -->
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
<a href="Basket.html" class="btn btn-pink"><i class="bi bi-trash"></i> Корзина</a>
</div>
</nav>
</div>
</header>
<!-- Окно входа -->
<div class="login-container">
<h2>Вход на СладкийДиск</h2>
<form class="login-form">
<input type="text" placeholder="Логин" required>
<input type="password" placeholder="Пароль" required>
<a href="index.html" class="login-button">Войти</a>
</form>
</div>
<!-- Основное содержимое -->
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4">Вход на СладкийДиск</h2>
<div class="row justify-content-center">
<div class="col-md-6 col-lg-4">
<div class="card shadow">
<div class="card-body">
<form class="d-flex flex-column gap-3">
<div class="form-group">
<input type="text" class="form-control" placeholder="Логин" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Пароль" required>
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-box-arrow-in-right"></i> Войти</a>
</form>
</div>
</div>
</div>
</div>
</main>
<!-- Подвал -->
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 d-flex justify-content-md-end">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="text/javascript" src="/bootstrap/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript" src="/main.js"></script>
</body>
</html>

View File

@@ -1,45 +1,69 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкоеФото</title>
<link rel="stylesheet" href="css/Style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкоеФото</title>
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/node_modules/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<!-- Обложка -->
<img class="cover" src="src/cover.png" alt="Логотип SweetyDisk"/>
<!-- Табличка с кнопками -->
<div class="table-container">
<table>
<tr>
<td><a href="File.html" class="button">Файлы</a></td>
</tr>
<tr>
<td><a href="Photo.html" class="button">Фото</a></td>
</tr>
<tr>
<td><a href="Album.html" class="button">Альбом</a></td>
</tr>
<tr>
<td><a href="Basket.html" class="button">Корзина</a></td>
</tr>
<tr>
<td><a href="index.html" class="button">На главную</a></td>
</tr>
</table>
<button class="upload-button" onclick="document.getElementById('file-input').click()">Загрузить</button>
<input type="file" id="file-input" style="display: none;">
<!-- Кнопка "Вход" -->
<a href="Password.html" class="login-button">Вход</a>
</div>
<div class="file-container">
<img src="src/photo.png">
<img src="src/pass.png">
<img src="src/con23.png">
<img src="src/cono.png">
</div>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="/src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none" accept="image/*">
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Ваши Фото</h2>
<div class="photo-container row row-cols-1 row-cols-md-3 g-4" id="photoContainer"></div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>

308
Upload.html Normal file
View File

@@ -0,0 +1,308 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Загрузка | SweetyDisk</title>
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/node_modules/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="/styles.css">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 d-flex flex-column flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="/src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
</div>
<a href="/index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="/File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="/Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="/Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Загрузка и редактирование</h2>
<ul class="nav nav-tabs mb-4" id="uploadTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="upload-tab" data-bs-toggle="tab" data-bs-target="#upload" type="button" role="tab" aria-controls="upload" aria-selected="true">Загрузить</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="edit-album-tab" data-bs-toggle="tab" data-bs-target="#edit-album" type="button" role="tab" aria-controls="edit-album" aria-selected="false">Редактировать альбом</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="edit-photo-tab" data-bs-toggle="tab" data-bs-target="#edit-photo" type="button" role="tab" aria-controls="edit-photo" aria-selected="false">Редактировать фото</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="edit-file-tab" data-bs-toggle="tab" data-bs-target="#edit-file" type="button" role="tab" aria-controls="edit-file" aria-selected="false">Редактировать файл</button>
</li>
</ul>
<div class="tab-content" id="uploadTabContent">
<div class="tab-pane fade show active" id="upload" role="tabpanel" aria-labelledby="upload-tab">
<div class="card shadow mb-4">
<div class="card-body">
<h3 class="h5">Загрузить</h3>
<form id="uploadForm" class="row g-3">
<div class="col-12">
<label for="uploadType" class="form-label">Тип загрузки</label>
<select class="form-control" id="uploadType">
<option value="" disabled selected>Выберите тип</option>
<option value="album">Альбом</option>
<option value="photo">Фото</option>
<option value="file">Файл</option>
</select>
</div>
<div class="col-12 d-none" id="albumNameGroup">
<label for="albumName" class="form-label">Название альбома</label>
<input type="text" class="form-control" id="albumName">
</div>
<div class="col-12 d-none" id="albumDescriptionGroup">
<label for="albumDescription" class="form-label">Описание альбома</label>
<textarea class="form-control" id="albumDescription"></textarea>
</div>
<div class="col-12 d-none" id="albumCategoryGroup">
<label for="albumCategory" class="form-label">Категория</label>
<select class="form-control" id="albumCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12 d-none" id="albumVisibilityGroup">
<label for="albumVisibility" class="form-label">Видимость</label>
<select class="form-control" id="albumVisibility">
<option value="public">Публичный</option>
<option value="private">Приватный</option>
</select>
</div>
<div class="col-12 d-none" id="albumOwnerGroup">
<label for="albumOwner" class="form-label">Владелец</label>
<input type="text" class="form-control" id="albumOwner" placeholder="Имя пользователя">
</div>
<div class="col-12 d-none" id="albumTagsGroup">
<label for="albumTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="albumTags" placeholder="путешествия, семья">
</div>
<div class="col-12 d-none" id="photoDescriptionGroup">
<label for="photoDescription" class="form-label">Описание фото</label>
<textarea class="form-control" id="photoDescription"></textarea>
</div>
<div class="col-12 d-none" id="photoCategoryGroup">
<label for="photoCategory" class="form-label">Категория</label>
<select class="form-control" id="photoCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12 d-none" id="photoTypeGroup">
<label for="photoType" class="form-label">Тип фотографии</label>
<select class="form-control" id="photoType">
<option value="1">Черно-белая</option>
<option value="2">Цветная</option>
</select>
</div>
<div class="col-12 d-none" id="photoTagsGroup">
<label for="photoTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="photoTags" placeholder="природа, закат">
</div>
<div class="col-12 d-none" id="fileDescriptionGroup">
<label for="fileDescription" class="form-label">Описание файла</label>
<textarea class="form-control" id="fileDescription"></textarea>
</div>
<div class="col-12 d-none" id="fileCategoryGroup">
<label for="fileCategory" class="form-label">Категория</label>
<select class="form-control" id="fileCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12 d-none" id="fileTypeGroup">
<label for="fileType" class="form-label">Тип файла</label>
<select class="form-control" id="fileType">
<option value="1">Документ</option>
<option value="2">Архив</option>
</select>
</div>
<div class="col-12 d-none" id="fileTagsGroup">
<label for="fileTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="fileTags" placeholder="работа, проект">
</div>
<div class="col-12">
<label for="fileInput" class="form-label">Выберите файл</label>
<input type="file" class="form-control" id="fileInput" accept="image/*">
</div>
<div class="col-12 text-center">
<div id="dropZone" class="border p-4 rounded bg-light">
Перетащите файл сюда или кликните для выбора
</div>
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink" id="uploadBtn">Загрузить</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="edit-album" role="tabpanel" aria-labelledby="edit-album-tab">
<div class="card shadow">
<div class="card-body">
<h3 class="h5">Редактировать альбом</h3>
<form id="editAlbumForm" class="row g-3">
<input type="hidden" id="editAlbumId">
<div class="col-12">
<label for="editAlbumName" class="form-label">Название альбома</label>
<input type="text" class="form-control" id="editAlbumName">
</div>
<div class="col-12">
<label for="editAlbumDescription" class="form-label">Описание альбома</label>
<textarea class="form-control" id="editAlbumDescription"></textarea>
</div>
<div class="col-12">
<label for="editAlbumCategory" class="form-label">Категория</label>
<select class="form-control" id="editAlbumCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12">
<label for="editAlbumVisibility" class="form-label">Видимость</label>
<select class="form-control" id="editAlbumVisibility">
<option value="public">Публичный</option>
<option value="private">Приватный</option>
</select>
</div>
<div class="col-12">
<label for="editAlbumOwner" class="form-label">Владелец</label>
<input type="text" class="form-control" id="editAlbumOwner">
</div>
<div class="col-12">
<label for="editAlbumTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="editAlbumTags">
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink">Сохранить</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="edit-photo" role="tabpanel" aria-labelledby="edit-photo-tab">
<div class="card shadow">
<div class="card-body">
<h3 class="h5">Редактировать фото</h3>
<form id="editPhotoForm" class="row g-3">
<input type="hidden" id="editPhotoId">
<input type="hidden" id="editPhotoResolution">
<input type="hidden" id="editPhotoSize">
<div class="col-12">
<label for="editPhotoDescription" class="form-label">Описание фото</label>
<textarea class="form-control" id="editPhotoDescription"></textarea>
</div>
<div class="col-12">
<label for="editPhotoCategory" class="form-label">Категория</label>
<select class="form-control" id="editPhotoCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12">
<label for="editPhotoType" class="form-label">Тип фотографии</label>
<select class="form-control" id="editPhotoType">
<option value="1">Черно-белая</option>
<option value="2">Цветная</option>
</select>
</div>
<div class="col-12">
<label for="editPhotoTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="editPhotoTags" placeholder="природа, закат">
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink">Сохранить</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="edit-file" role="tabpanel" aria-labelledby="edit-file-tab">
<div class="card shadow">
<div class="card-body">
<h3 class="h5">Редактировать файл</h3>
<form id="editFileForm" class="row g-3">
<input type="hidden" id="editFileId">
<input type="hidden" id="editFileSize">
<input type="hidden" id="editFileFormat">
<div class="col-12">
<label for="editFileName" class="form-label">Название файла</label>
<input type="text" class="form-control" id="editFileName">
</div>
<div class="col-12">
<label for="editFileDescription" class="form-label">Описание файла</label>
<textarea class="form-control" id="editFileDescription"></textarea>
</div>
<div class="col-12">
<label for="editFileCategory" class="form-label">Категория</label>
<select class="form-control" id="editFileCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12">
<label for="editFileType" class="form-label">Тип файла</label>
<select class="form-control" id="editFileType">
<option value="1">Документ</option>
<option value="2">Архив</option>
</select>
</div>
<div class="col-12">
<label for="editFileTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="editFileTags" placeholder="работа, проект">
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink">Сохранить</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>

527
controller.js Normal file
View File

@@ -0,0 +1,527 @@
import Model from './model.js';
import View from './view.js';
class Controller {
constructor() {
this.model = new Model();
this.view = new View();
this.currentPage = window.location.pathname.split('/').pop() || 'index.html';
console.log('Controller initialized');
}
async init() {
console.log('Controller init called', this.currentPage);
if (this.currentPage === 'Album.html') {
await this.loadAlbums();
} else if (this.currentPage === 'Photo.html') {
await this.loadPhotos();
} else if (this.currentPage === 'File.html') {
await this.loadFiles();
} else if (this.currentPage === 'Upload.html') {
this.setupUploadForm();
this.setupEditForm();
} else if (this.currentPage === 'Basket.html') {
await this.loadBasket();
}
document.querySelectorAll('.upload-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.preventDefault();
console.log('Upload button clicked');
window.location.href = '/Upload.html';
});
});
}
async loadAlbums() {
try {
const albums = await this.model.fetchAlbums();
this.view.renderItems('#albumContainer', albums, 'album',
(item) => this.handleEditAlbum(item),
(item) => this.handleDeleteItem(item, 'album')
);
} catch (error) {
this.view.showAlert('Ошибка загрузки альбомов!', 'danger');
console.error(error);
}
}
async loadPhotos() {
try {
const photos = await this.model.fetchPhotos();
this.view.renderItems('#photoContainer', photos, 'photo',
(item) => this.handleEditPhoto(item),
(item) => this.handleDeleteItem(item, 'photo')
);
} catch (error) {
this.view.showAlert('Ошибка загрузки фотографий!', 'danger');
console.error(error);
}
}
async loadFiles() {
try {
const files = await this.model.fetchFiles();
this.view.renderItems('#fileContainer', files, 'file',
(item) => this.handleEditFile(item),
(item) => this.handleDeleteItem(item, 'file')
);
} catch (error) {
this.view.showAlert('Ошибка загрузки файлов!', 'danger');
console.error(error);
}
}
async loadBasket() {
try {
const basketItems = await this.model.fetchBasket();
console.log('Basket items loaded:', basketItems);
this.view.renderBasketItems('#basketContainer', basketItems,
(item) => this.handleRestoreFromBasket(item),
(item) => this.handleDeleteFromBasket(item)
);
document.getElementById('clear-basket')?.addEventListener('click', async () => {
try {
await this.model.clearBasket();
this.view.showAlert('Корзина очищена!', 'success');
await this.loadBasket();
} catch (error) {
this.view.showAlert('Ошибка при очистке корзины!', 'danger');
console.error(error);
}
});
} catch (error) {
this.view.showAlert('Ошибка загрузки корзины!', 'danger');
console.error(error);
}
}
setupUploadForm() {
const uploadForm = document.getElementById('uploadForm');
const uploadTypeSelect = document.getElementById('uploadType');
const albumNameGroup = document.getElementById('albumNameGroup');
const albumDescriptionGroup = document.getElementById('albumDescriptionGroup');
const albumCategoryGroup = document.getElementById('albumCategoryGroup');
const albumVisibilityGroup = document.getElementById('albumVisibilityGroup');
const albumOwnerGroup = document.getElementById('albumOwnerGroup');
const albumTagsGroup = document.getElementById('albumTagsGroup');
const photoDescriptionGroup = document.getElementById('photoDescriptionGroup');
const photoCategoryGroup = document.getElementById('photoCategoryGroup');
const photoTypeGroup = document.getElementById('photoTypeGroup');
const photoTagsGroup = document.getElementById('photoTagsGroup');
const fileDescriptionGroup = document.getElementById('fileDescriptionGroup');
const fileCategoryGroup = document.getElementById('fileCategoryGroup');
const fileTypeGroup = document.getElementById('fileTypeGroup');
const fileTagsGroup = document.getElementById('fileTagsGroup');
const fileInput = document.getElementById('fileInput');
const dropZone = document.getElementById('dropZone');
const uploadBtn = document.getElementById('uploadBtn');
if (!uploadForm) return;
uploadTypeSelect.addEventListener('change', () => {
albumNameGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'album');
albumDescriptionGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'album');
albumCategoryGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'album');
albumVisibilityGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'album');
albumOwnerGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'album');
albumTagsGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'album');
photoDescriptionGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'photo');
photoCategoryGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'photo');
photoTypeGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'photo');
photoTagsGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'photo');
fileDescriptionGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'file');
fileCategoryGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'file');
fileTypeGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'file');
fileTagsGroup.classList.toggle('d-none', uploadTypeSelect.value !== 'file');
fileInput.setAttribute('accept', uploadTypeSelect.value === 'file' ? '*' : 'image/*');
});
dropZone.addEventListener('click', () => fileInput.click());
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('bg-secondary');
});
dropZone.addEventListener('dragleave', () => dropZone.classList.remove('bg-secondary'));
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('bg-secondary');
fileInput.files = e.dataTransfer.files;
this.handleFileUpload(
e.dataTransfer.files,
uploadTypeSelect.value,
document.getElementById('albumName')?.value,
document.getElementById('albumDescription')?.value,
document.getElementById('albumCategory')?.value,
document.getElementById('albumVisibility')?.value,
document.getElementById('albumOwner')?.value,
document.getElementById('albumTags')?.value,
document.getElementById('photoDescription')?.value,
document.getElementById('photoCategory')?.value,
document.getElementById('photoType')?.value,
document.getElementById('photoTags')?.value,
document.getElementById('fileDescription')?.value,
document.getElementById('fileCategory')?.value,
document.getElementById('fileType')?.value,
document.getElementById('fileTags')?.value
);
});
fileInput.addEventListener('change', () => {
this.handleFileUpload(
fileInput.files,
uploadTypeSelect.value,
document.getElementById('albumName')?.value,
document.getElementById('albumDescription')?.value,
document.getElementById('albumCategory')?.value,
document.getElementById('albumVisibility')?.value,
document.getElementById('albumOwner')?.value,
document.getElementById('albumTags')?.value,
document.getElementById('photoDescription')?.value,
document.getElementById('photoCategory')?.value,
document.getElementById('photoType')?.value,
document.getElementById('photoTags')?.value,
document.getElementById('fileDescription')?.value,
document.getElementById('fileCategory')?.value,
document.getElementById('fileType')?.value,
document.getElementById('fileTags')?.value
);
});
uploadBtn.addEventListener('click', (e) => {
e.preventDefault();
fileInput.click();
});
uploadForm.addEventListener('submit', async (e) => {
e.preventDefault();
this.handleFileUpload(
fileInput.files,
uploadTypeSelect.value,
document.getElementById('albumName')?.value,
document.getElementById('albumDescription')?.value,
document.getElementById('albumCategory')?.value,
document.getElementById('albumVisibility')?.value,
document.getElementById('albumOwner')?.value,
document.getElementById('albumTags')?.value,
document.getElementById('photoDescription')?.value,
document.getElementById('photoCategory')?.value,
document.getElementById('photoType')?.value,
document.getElementById('photoTags')?.value,
document.getElementById('fileDescription')?.value,
document.getElementById('fileCategory')?.value,
document.getElementById('fileType')?.value,
document.getElementById('fileTags')?.value
);
});
}
async handleFileUpload(
files, uploadType, albumName, albumDescription, albumCategory, albumVisibility, albumOwner, albumTags,
photoDescription, photoCategory, photoType, photoTags,
fileDescription, fileCategory, fileType, fileTags
) {
const validImageTypes = ['image/png', 'image/jpeg'];
if (!uploadType) {
this.view.showAlert('Пожалуйста, выберите тип загрузки!', 'danger');
return;
}
if (uploadType === 'album' && (!albumName || !albumOwner || !albumTags)) {
this.view.showAlert('Название альбома, владелец и теги обязательны!', 'danger');
return;
}
if (uploadType === 'photo' && !photoTags) {
this.view.showAlert('Теги для фото обязательны!', 'danger');
return;
}
if (uploadType === 'file' && !fileTags) {
this.view.showAlert('Теги для файла обязательны!', 'danger');
return;
}
if (!files.length) {
this.view.showAlert('Выберите файл!', 'danger');
return;
}
Array.from(files).forEach(async (file) => {
if ((uploadType === 'photo' || uploadType === 'album') && !validImageTypes.includes(file.type)) {
this.view.showAlert('Для фото и альбомов разрешены только PNG или JPG!', 'danger');
return;
}
const reader = new FileReader();
reader.onload = async (event) => {
try {
let destination;
const fileSize = (file.size / 1024).toFixed(2); // Size in KB
const lastModified = new Date(file.lastModified).toISOString();
const fileFormat = file.name.split('.').pop().toLowerCase();
let resolution = '';
// Get image resolution for photos
if (uploadType === 'photo' || uploadType === 'album') {
const img = new Image();
img.src = event.target.result;
await new Promise(resolve => {
img.onload = () => {
resolution = `${img.width}x${img.height}`;
resolve();
};
});
}
if (uploadType === 'file') {
destination = '/File.html';
await this.model.createFile(
event.target.result,
file.name,
fileDescription || '',
fileCategory || '1',
fileType || '1',
fileSize,
fileFormat,
lastModified,
fileTags.split(',').map(tag => tag.trim())
);
this.view.showAlert('Файл загружен!', 'success');
} else if (uploadType === 'photo') {
destination = '/Photo.html';
await this.model.createPhoto(
event.target.result,
photoDescription || '',
photoCategory || '1',
photoType || '1',
resolution,
fileSize,
lastModified,
photoTags.split(',').map(tag => tag.trim())
);
this.view.showAlert('Фото загружено!', 'success');
} else if (uploadType === 'album') {
destination = '/Album.html';
await this.model.createAlbum(
albumName,
event.target.result,
albumDescription || '',
albumCategory || '1',
albumVisibility || 'public',
albumOwner,
lastModified,
albumTags.split(',').map(tag => tag.trim())
);
this.view.showAlert('Альбом создан!', 'success');
}
setTimeout(() => window.location.href = destination, 1000);
} catch (error) {
this.view.showAlert('Ошибка при загрузке!', 'danger');
console.error(error);
}
};
reader.readAsDataURL(file);
});
}
setupEditForm() {
const editAlbumForm = document.getElementById('editAlbumForm');
if (editAlbumForm) {
const urlParams = new URLSearchParams(window.location.search);
const albumId = urlParams.get('albumId');
const albumName = urlParams.get('albumName');
const albumDescription = urlParams.get('albumDescription');
const albumCategory = urlParams.get('albumCategory');
const albumVisibility = urlParams.get('albumVisibility');
const albumOwner = urlParams.get('albumOwner');
const albumTags = urlParams.get('albumTags');
if (albumId && albumName) {
document.getElementById('editAlbumId').value = albumId;
document.getElementById('editAlbumName').value = decodeURIComponent(albumName);
document.getElementById('editAlbumDescription').value = decodeURIComponent(albumDescription || '');
document.getElementById('editAlbumCategory').value = decodeURIComponent(albumCategory || '1');
document.getElementById('editAlbumVisibility').value = decodeURIComponent(albumVisibility || 'public');
document.getElementById('editAlbumOwner').value = decodeURIComponent(albumOwner || '');
document.getElementById('editAlbumTags').value = decodeURIComponent(albumTags || '');
document.querySelector('#edit-album-tab').click();
}
editAlbumForm.addEventListener('submit', async (e) => {
e.preventDefault();
const id = document.getElementById('editAlbumId').value;
const name = document.getElementById('editAlbumName').value;
const description = document.getElementById('editAlbumDescription').value;
const category = document.getElementById('editAlbumCategory').value;
const visibility = document.getElementById('editAlbumVisibility').value;
const owner = document.getElementById('editAlbumOwner').value;
const tags = document.getElementById('editAlbumTags').value;
if (!id || !name || !owner || !tags) {
this.view.showAlert('Название, владелец и теги обязательны!', 'danger');
return;
}
try {
await this.model.updateAlbum(id, name, description || '', category || '1', visibility || 'public', owner, new Date().toISOString(), tags.split(',').map(tag => tag.trim()));
this.view.showAlert('Альбом обновлён!', 'success');
this.view.clearForm('#editAlbumForm');
setTimeout(() => window.location.href = '/Album.html', 1000);
} catch (error) {
this.view.showAlert('Ошибка при обновлении альбома!', 'danger');
console.error(error);
}
});
}
const editPhotoForm = document.getElementById('editPhotoForm');
if (editPhotoForm) {
const urlParams = new URLSearchParams(window.location.search);
const photoId = urlParams.get('photoId');
const photoDescription = urlParams.get('photoDescription');
const photoCategory = urlParams.get('photoCategory');
const photoType = urlParams.get('photoType');
const photoResolution = urlParams.get('photoResolution');
const photoSize = urlParams.get('photoSize');
const photoTags = urlParams.get('photoTags');
if (photoId) {
document.getElementById('editPhotoId').value = photoId;
document.getElementById('editPhotoDescription').value = decodeURIComponent(photoDescription || '');
document.getElementById('editPhotoCategory').value = decodeURIComponent(photoCategory || '1');
document.getElementById('editPhotoType').value = decodeURIComponent(photoType || '1');
document.getElementById('editPhotoResolution').value = decodeURIComponent(photoResolution || '');
document.getElementById('editPhotoSize').value = decodeURIComponent(photoSize || '');
document.getElementById('editPhotoTags').value = decodeURIComponent(photoTags || '');
document.querySelector('#edit-photo-tab').click();
}
editPhotoForm.addEventListener('submit', async (e) => {
e.preventDefault();
const id = document.getElementById('editPhotoId').value;
const description = document.getElementById('editPhotoDescription').value;
const category = document.getElementById('editPhotoCategory').value;
const photoType = document.getElementById('editPhotoType').value;
const resolution = document.getElementById('editPhotoResolution').value;
const size = document.getElementById('editPhotoSize').value;
const tags = document.getElementById('editPhotoTags').value;
if (!id || !tags) {
this.view.showAlert('Теги обязательны!', 'danger');
return;
}
try {
await this.model.updatePhoto(id, description || '', category || '1', photoType || '1', resolution, size, new Date().toISOString(), tags.split(',').map(tag => tag.trim()));
this.view.showAlert('Фото обновлено!', 'success');
this.view.clearForm('#editPhotoForm');
setTimeout(() => window.location.href = '/Photo.html', 1000);
} catch (error) {
this.view.showAlert('Ошибка при обновлении фото!', 'danger');
console.error(error);
}
});
}
const editFileForm = document.getElementById('editFileForm');
if (editFileForm) {
const urlParams = new URLSearchParams(window.location.search);
const fileId = urlParams.get('fileId');
const fileName = urlParams.get('fileName');
const fileDescription = urlParams.get('fileDescription');
const fileCategory = urlParams.get('fileCategory');
const fileType = urlParams.get('fileType');
const fileSize = urlParams.get('fileSize');
const fileFormat = urlParams.get('fileFormat');
const fileTags = urlParams.get('fileTags');
if (fileId) {
document.getElementById('editFileId').value = fileId;
document.getElementById('editFileName').value = decodeURIComponent(fileName || '');
document.getElementById('editFileDescription').value = decodeURIComponent(fileDescription || '');
document.getElementById('editFileCategory').value = decodeURIComponent(fileCategory || '1');
document.getElementById('editFileType').value = decodeURIComponent(fileType || '1');
document.getElementById('editFileSize').value = decodeURIComponent(fileSize || '');
document.getElementById('editFileFormat').value = decodeURIComponent(fileFormat || '');
document.getElementById('editFileTags').value = decodeURIComponent(fileTags || '');
document.querySelector('#edit-file-tab').click();
}
editFileForm.addEventListener('submit', async (e) => {
e.preventDefault();
const id = document.getElementById('editFileId').value;
const name = document.getElementById('editFileName').value;
const description = document.getElementById('editFileDescription').value;
const category = document.getElementById('editFileCategory').value;
const fileType = document.getElementById('editFileType').value;
const size = document.getElementById('editFileSize').value;
const format = document.getElementById('editFileFormat').value;
const tags = document.getElementById('editFileTags').value;
if (!id || !name || !tags) {
this.view.showAlert('Название и теги обязательны!', 'danger');
return;
}
try {
await this.model.updateFile(id, name, description || '', category || '1', fileType || '1', size, format, new Date().toISOString(), tags.split(',').map(tag => tag.trim()));
this.view.showAlert('Файл обновлён!', 'success');
this.view.clearForm('#editFileForm');
setTimeout(() => window.location.href = '/File.html', 1000);
} catch (error) {
this.view.showAlert('Ошибка при обновлении файла!', 'danger');
console.error(error);
}
});
}
}
async handleDeleteItem(item, type) {
try {
console.log(`Deleting ${type}:`, item);
await this.model[`delete${type.charAt(0).toUpperCase() + type.slice(1)}`](item.id);
this.view.showAlert(`${type.charAt(0).toUpperCase() + type.slice(1)} удалён!`, 'success');
await this[`load${type.charAt(0).toUpperCase() + type.slice(1)}s`]();
} catch (error) {
this.view.showAlert('Ошибка при удалении!', 'danger');
console.error('Delete error:', error);
}
}
async handleRestoreFromBasket(item) {
try {
await this.model.restoreFromBasket(item.id, item.type);
this.view.showAlert(`${item.type.charAt(0).toUpperCase() + item.type.slice(1)} восстановлен!`, 'success');
await this.loadBasket();
} catch (error) {
this.view.showAlert('Ошибка при восстановлении!', 'danger');
console.error('Restore error:', error);
}
}
async handleDeleteFromBasket(item) {
try {
await this.model.deleteFromBasket(item.id);
this.view.showAlert(`${item.type.charAt(0).toUpperCase() + item.type.slice(1)} удалён из корзины!`, 'success');
await this.loadBasket();
} catch (error) {
this.view.showAlert('Ошибка при удалении из корзины!', 'danger');
console.error('Delete from basket error:', error);
}
}
handleEditAlbum(album) {
window.location.href = `/Upload.html?albumId=${album.id}&albumName=${encodeURIComponent(album.name)}&albumDescription=${encodeURIComponent(album.description || '')}&albumCategory=${encodeURIComponent(album.categoryId || '1')}&albumVisibility=${encodeURIComponent(album.visibility || 'public')}&albumOwner=${encodeURIComponent(album.owner || '')}&albumTags=${encodeURIComponent(album.tags.join(',') || '')}`;
}
handleEditPhoto(photo) {
window.location.href = `/Upload.html?photoId=${photo.id}&photoDescription=${encodeURIComponent(photo.description || '')}&photoCategory=${encodeURIComponent(photo.categoryId || '1')}&photoType=${encodeURIComponent(photo.photoTypeId || '1')}&photoResolution=${encodeURIComponent(photo.resolution || '')}&photoSize=${encodeURIComponent(photo.size || '')}&photoTags=${encodeURIComponent(photo.tags.join(',') || '')}`;
}
handleEditFile(file) {
window.location.href = `/Upload.html?fileId=${file.id}&fileName=${encodeURIComponent(file.name || '')}&fileDescription=${encodeURIComponent(file.description || '')}&fileCategory=${encodeURIComponent(file.categoryId || '1')}&fileType=${encodeURIComponent(file.fileTypeId || '1')}&fileSize=${encodeURIComponent(file.size || '')}&fileFormat=${encodeURIComponent(file.format || '')}&fileTags=${encodeURIComponent(file.tags.join(',') || '')}`;
}
}
export default Controller;

View File

@@ -1,172 +0,0 @@
/*Основной стиль */
body {
margin: 0;
font-family: Arial, sans-serif;
background-color: #808080;
}
/* Стиль шапки*/
.cover {
display: block;
width: 100%;
max-height: 30vh;
object-fit: cover;
}
/* Стиль для таблицы с кнопками перехода на следующую страницу*/
.table-container {
position: absolute;
top: 350px;
right: 20px;
background-color: #fff;
padding: 10px;
border-radius: 4px;
box-shadow: 0 2px 6px rgba(223, 49, 167, 0.699);
}
/* Стиль таблицы */
table {
border-collapse: collapse;
width: 200px;
}
/*Стиль для кнопок в таблице*/
.button {
display: block;
padding: 10px 20px;
text-align: center;
background-color: #ff0088;
color: white;
text-decoration: none;
border-radius: 4px;
margin: 5px 0;
transition: background-color 0.3s ease;
}
/*закрашивание кнопок*/
.button:hover {
background-color: #ee80ee;
}
/* Стили для нового текстового блока */
.text-block {
text-align: center;
margin-top: 40px;
padding: 20px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 6px rgba(223, 49, 167, 0.699);
}
/*Стиль текста Заголовка основного текста*/
.text-block h2 {
color: #ee80ee;
font-size: 48px;
margin-bottom: 12px;
}
/*Cтиль для обычного текста в заголовке*/
.text-block p {
color: #ff0088;
font-size: 32px;
}
/* Стили для таблицы с подпиской */
.new-table-container {
margin-top: 40px;
max-width: 1300px;
margin-left: auto;
margin-right: auto;
}
.new-table-container table {
width: 100%;
border-collapse: collapse;
}
/* Стиль для колонок с расценками*/
.new-table-container th, .new-table-container td {
padding: 12px;
border: 1px solid #dddddd;
text-align: center;
color: #000;
background-color: #ff00ff;
}
.new-table-container th {
background-color: #ff0088;
color: white;
}
/* Стили для желтой кнопки "Загрузить" */
.upload-button {
padding: 10px 20px;
background-color: #ffcc00;
color: #000;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s ease;
margin-bottom: 10px;
}
.upload-button:hover {
background-color: #e6b800;
}
/* Стили для кнопки "Вход" */
.login-button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s ease;
}
.login-button:hover {
background-color: #45a049; /* Темно-зеленый при наведении */
}
/*Стиль для блока где будут хранятся наши файлы*/
.file-container {
position: absolute;
top: 32%;
left: 5%;
width: 1500px;
max-height: 2500px;
background-color: #333;
border: 4px solid #ff0088;
border-radius: 8px;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: flex-start;
color: #ff0088;
font-size: 32px;
font-weight: bold;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
overflow-y: auto;
overflow-x: hidden;
}
.file-container img {
max-width: 300px;
max-height: 300px;
object-fit: cover;
margin: 10px;
}
.image-wrapper {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px;
}
.image-wrapper img {
max-width: 100%;
max-height: 300px;
object-fit: cover;
}
.image-wrapper p {
margin-top: 10px;
text-align: center;
font-size: 24px;
color: #ff0088;
}

View File

@@ -1,62 +0,0 @@
/* Общие стили */
body {
margin: 0;
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}
/* Окно входа */
.login-container {
background-color: rgba(255, 255, 255, 0.9);
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
width: 300px;
text-align: center;
}
h2 {
margin-bottom: 20px;
color: #333;
}
/* Форма */
.login-form {
display: flex;
flex-direction: column;
gap: 15px;
}
input {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
outline: none;
}
input:focus {
border-color: #ff0088;
}
/* Кнопка */
.login-button {
padding: 10px;
background-color: #ff0088;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
text-align: center;
text-decoration: none;
transition: background-color 0.3s ease;
}
.login-button:hover {
background-color: #e60073;
}

119
db.json Normal file

File diff suppressed because one or more lines are too long

75
dist/Album.html vendored Normal file
View File

@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкийАльбом</title>
<script type="module" crossorigin src="./assets/album-BsEZQu2l.js"></script>
<link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="stylesheet" crossorigin href="./assets/bootstrap-icons-8sx8Fhtg.css">
<link rel="stylesheet" crossorigin href="./assets/styles-CtPCArmk.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none" accept="image/*">
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Ваши Альбомы</h2>
<div class="album-container row row-cols-1 row-cols-md-3 g-4" id="albumContainer"></div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="./main.js"></script>
<script type="text/javascript" src="./bootstrap/js/bootstrap.bundle.min.js"></script>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-CBvV26yc.js"></script>

71
dist/Basket.html vendored Normal file
View File

@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Корзина</title>
<script type="module" crossorigin src="./assets/basket-BsEZQu2l.js"></script>
<link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="stylesheet" crossorigin href="./assets/bootstrap-icons-8sx8Fhtg.css">
<link rel="stylesheet" crossorigin href="./assets/styles-CtPCArmk.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 d-flex flex-column flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<a href="./index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="./File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="./Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="./Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
<a href="./Basket.html" class="btn btn-pink"><i class="bi bi-trash"></i> Корзина</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Корзина</h2>
<div class="mb-4 text-center">
<button class="btn btn-danger" id="clear-basket">Очистить корзину</button>
</div>
<div class="basket-container row row-cols-1 row-cols-md-3 g-4" id="basketContainer">
<!-- Элементы корзины будут добавлены через JavaScript -->
</div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="./main.js"></script>
<script type="text/javascript" src="./bootstrap/js/bootstrap.bundle.min.js"></script>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-CBvV26yc.js"></script>

75
dist/File.html vendored Normal file
View File

@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сладкие Файлы</title>
<script type="module" crossorigin src="./assets/file-BsEZQu2l.js"></script>
<link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="stylesheet" crossorigin href="./assets/bootstrap-icons-8sx8Fhtg.css">
<link rel="stylesheet" crossorigin href="./assets/styles-CtPCArmk.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none">
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Ваши Файлы</h2>
<div class="file-container row row-cols-1 row-cols-md-3 g-4" id="fileContainer"></div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="./main.js"></script>
<script type="text/javascript" src="./bootstrap/js/bootstrap.bundle.min.js"></script>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-CBvV26yc.js"></script>

87
dist/Password.html vendored Normal file
View File

@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкаяРегистрация</title>
<script async type="module" crossorigin src="./assets/password-ufRREwff.js"></script>
<link rel="stylesheet" crossorigin href="./assets/bootstrap-icons-8sx8Fhtg.css">
<link rel="stylesheet" crossorigin href="./assets/styles-CtPCArmk.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 d-flex flex-column flex-grow-1">
<!-- Шапка -->
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
<a href="Basket.html" class="btn btn-pink"><i class="bi bi-trash"></i> Корзина</a>
</div>
</nav>
</div>
</header>
<!-- Основное содержимое -->
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4">Вход на СладкийДиск</h2>
<div class="row justify-content-center">
<div class="col-md-6 col-lg-4">
<div class="card shadow">
<div class="card-body">
<form class="d-flex flex-column gap-3">
<div class="form-group">
<input type="text" class="form-control" placeholder="Логин" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Пароль" required>
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-box-arrow-in-right"></i> Войти</a>
</form>
</div>
</div>
</div>
</div>
</main>
<!-- Подвал -->
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 d-flex justify-content-md-end">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="text/javascript" src="./bootstrap/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript" src="./main.js"></script>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-CBvV26yc.js"></script>

75
dist/Photo.html vendored Normal file
View File

@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>СладкоеФото</title>
<script type="module" crossorigin src="./assets/photo-BsEZQu2l.js"></script>
<link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="stylesheet" crossorigin href="./assets/bootstrap-icons-8sx8Fhtg.css">
<link rel="stylesheet" crossorigin href="./assets/styles-CtPCArmk.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none" accept="image/*">
</div>
<a href="index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Ваши Фото</h2>
<div class="photo-container row row-cols-1 row-cols-md-3 g-4" id="photoContainer"></div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="./main.js"></script>
<script type="text/javascript" src="./bootstrap/js/bootstrap.bundle.min.js"></script>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-CBvV26yc.js"></script>

322
dist/Upload.html vendored Normal file
View File

@@ -0,0 +1,322 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Загрузка | SweetyDisk</title>
<script type="module" crossorigin src="./assets/upload-BsEZQu2l.js"></script>
<link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="stylesheet" crossorigin href="./assets/bootstrap-icons-8sx8Fhtg.css">
<link rel="stylesheet" crossorigin href="./assets/styles-CtPCArmk.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 d-flex flex-column flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
</div>
<a href="/index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="/File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="/Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="/Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<h2 class="display-5 text-pink mb-4 text-center">Загрузка и редактирование</h2>
<ul class="nav nav-tabs mb-4" id="uploadTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="upload-tab" data-bs-toggle="tab" data-bs-target="#upload" type="button" role="tab" aria-controls="upload" aria-selected="true">Загрузить</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="edit-album-tab" data-bs-toggle="tab" data-bs-target="#edit-album" type="button" role="tab" aria-controls="edit-album" aria-selected="false">Редактировать альбом</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="edit-photo-tab" data-bs-toggle="tab" data-bs-target="#edit-photo" type="button" role="tab" aria-controls="edit-photo" aria-selected="false">Редактировать фото</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="edit-file-tab" data-bs-toggle="tab" data-bs-target="#edit-file" type="button" role="tab" aria-controls="edit-file" aria-selected="false">Редактировать файл</button>
</li>
</ul>
<div class="tab-content" id="uploadTabContent">
<div class="tab-pane fade show active" id="upload" role="tabpanel" aria-labelledby="upload-tab">
<div class="card shadow mb-4">
<div class="card-body">
<h3 class="h5">Загрузить</h3>
<form id="uploadForm" class="row g-3">
<div class="col-12">
<label for="uploadType" class="form-label">Тип загрузки</label>
<select class="form-control" id="uploadType">
<option value="" disabled selected>Выберите тип</option>
<option value="album">Альбом</option>
<option value="photo">Фото</option>
<option value="file">Файл</option>
</select>
</div>
<div class="col-12 d-none" id="albumNameGroup">
<label for="albumName" class="form-label">Название альбома</label>
<input type="text" class="form-control" id="albumName">
</div>
<div class="col-12 d-none" id="albumDescriptionGroup">
<label for="albumDescription" class="form-label">Описание альбома</label>
<textarea class="form-control" id="albumDescription"></textarea>
</div>
<div class="col-12 d-none" id="albumCategoryGroup">
<label for="albumCategory" class="form-label">Категория</label>
<select class="form-control" id="albumCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12 d-none" id="albumVisibilityGroup">
<label for="albumVisibility" class="form-label">Видимость</label>
<select class="form-control" id="albumVisibility">
<option value="public">Публичный</option>
<option value="private">Приватный</option>
</select>
</div>
<div class="col-12 d-none" id="albumOwnerGroup">
<label for="albumOwner" class="form-label">Владелец</label>
<input type="text" class="form-control" id="albumOwner" placeholder="Имя пользователя">
</div>
<div class="col-12 d-none" id="albumTagsGroup">
<label for="albumTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="albumTags" placeholder="путешествия, семья">
</div>
<div class="col-12 d-none" id="photoDescriptionGroup">
<label for="photoDescription" class="form-label">Описание фото</label>
<textarea class="form-control" id="photoDescription"></textarea>
</div>
<div class="col-12 d-none" id="photoCategoryGroup">
<label for="photoCategory" class="form-label">Категория</label>
<select class="form-control" id="photoCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12 d-none" id="photoTypeGroup">
<label for="photoType" class="form-label">Тип фотографии</label>
<select class="form-control" id="photoType">
<option value="1">Черно-белая</option>
<option value="2">Цветная</option>
</select>
</div>
<div class="col-12 d-none" id="photoTagsGroup">
<label for="photoTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="photoTags" placeholder="природа, закат">
</div>
<div class="col-12 d-none" id="fileDescriptionGroup">
<label for="fileDescription" class="form-label">Описание файла</label>
<textarea class="form-control" id="fileDescription"></textarea>
</div>
<div class="col-12 d-none" id="fileCategoryGroup">
<label for="fileCategory" class="form-label">Категория</label>
<select class="form-control" id="fileCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12 d-none" id="fileTypeGroup">
<label for="fileType" class="form-label">Тип файла</label>
<select class="form-control" id="fileType">
<option value="1">Документ</option>
<option value="2">Архив</option>
</select>
</div>
<div class="col-12 d-none" id="fileNameGroup">
<label for="fileName" class="form-label">Название файла</label>
<input type="text" class="form-control" id="fileName">
</div>
<div class="col-12 d-none" id="fileFormatGroup">
<label for="fileFormat" class="form-label">Формат</label>
<input type="text" class="form-control" id="fileFormat" placeholder="pdf">
</div>
<div class="col-12 d-none" id="fileTagsGroup">
<label for="fileTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="fileTags" placeholder="работа, проект">
</div>
<div class="col-12">
<label for="fileInput" class="form-label">Выберите файл</label>
<input type="file" class="form-control" id="fileInput" accept="image/*">
</div>
<div class="col-12 text-center">
<div id="dropZone" class="border p-4 rounded bg-light">
Перетащите файл сюда или кликните для выбора
</div>
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink" id="uploadBtn">Загрузить</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="edit-album" role="tabpanel" aria-labelledby="edit-album-tab">
<div class="card shadow">
<div class="card-body">
<h3 class="h5">Р Редактировать альбом</h3>
<form id="editAlbumForm" class="row g-3">
<input type="hidden" id="editAlbumId">
<div class="col-12">
<label for="editAlbumName" class="form-label">Название альбома</label>
<input type="text" class="form-control" id="editAlbumName">
</div>
<div class="col-12">
<label for="editAlbumDescription" class="form-label">Описание альбома</label>
<textarea class="form-control" id="editAlbumDescription"></textarea>
</div>
<div class="col-12">
<label for="editAlbumCategory" class="form-label">Категория</label>
<select class="form-control" id="editAlbumCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12">
<label for="editAlbumVisibility" class="form-label">Видимость</label>
<select class="form-control" id="editAlbumVisibility">
<option value="public">Публичный</option>
<option value="private">Приватный</option>
</select>
</div>
<div class="col-12">
<label for="editAlbumOwner" class="form-label">Владелец</label>
<input type="text" class="form-control" id="editAlbumOwner">
</div>
<div class="col-12">
<label for="editAlbumTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="editAlbumTags">
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink">Сохранить</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="edit-photo" role="tabpanel" aria-labelledby="edit-photo-tab">
<div class="card shadow">
<div class="card-body">
<h3 class="h5">Редактировать фото</h3>
<form id="editPhotoForm" class="row g-3">
<input type="hidden" id="editPhotoId">
<div class="col-12">
<label for="editPhotoDescription" class="form-label">Описание фото</label>
<textarea class="form-control" id="editPhotoDescription"></textarea>
</div>
<div class="col-12">
<label for="editPhotoCategory" class="form-label">Категория</label>
<select class="form-control" id="editPhotoCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12">
<label for="editPhotoType" class="form-label">Тип фотографии</label>
<select class="form-control" id="editPhotoType">
<option value="1">Черно-белая</option>
<option value="2">Цветная</option>
</select>
</div>
<div class="col-12">
<label for="editPhotoTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="editPhotoTags" placeholder="природа, закат">
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink">Сохранить</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="edit-file" role="tabpanel" aria-labelledby="edit-file-tab">
<div class="card shadow">
<div class="card-body">
<h3 class="h5">Редактировать файл</h3>
<form id="editFileForm" class="row g-3">
<input type="hidden" id="editFileId">
<div class="col-12">
<label for="editFileName" class="form-label">Название файла</label>
<input type="text" class="form-control" id="editFileName">
</div>
<div class="col-12">
<label for="editFileDescription" class="form-label">Описание файла</label>
<textarea class="form-control" id="editFileDescription"></textarea>
</div>
<div class="col-12">
<label for="editFileCategory" class="form-label">Категория</label>
<select class="form-control" id="editFileCategory">
<option value="1">Личные</option>
<option value="2">Рабочие</option>
</select>
</div>
<div class="col-12">
<label for="editFileType" class="form-label">Тип файла</label>
<select class="form-control" id="editFileType">
<option value="1">Документ</option>
<option value="2">Архив</option>
</select>
</div>
<div class="col-12">
<label for="editFileFormat" class="form-label">Формат</label>
<input type="text" class="form-control" id="editFileFormat" placeholder="pdf">
</div>
<div class="col-12">
<label for="editFileTags" class="form-label">Теги (через запятую)</label>
<input type="text" class="form-control" id="editFileTags" placeholder="работа, проект">
</div>
<div class="col-12 text-center">
<button type="submit" class="btn btn-pink">Сохранить</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="./main.js"></script>
<script type="text/javascript" src="./bootstrap/js/bootstrap.bundle.min.js"></script>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-CBvV26yc.js"></script>

1
dist/assets/album-BsEZQu2l.js vendored Normal file
View File

@@ -0,0 +1 @@
import"./modulepreload-polyfill-B5Qt9EMX.js";/* empty css *//* empty css */function t(){import.meta.url,import("_").catch(()=>1),async function*(){}().next()}export{t as __vite_legacy_guard};

1
dist/assets/album-legacy-CRC7rfsn.js vendored Normal file
View File

@@ -0,0 +1 @@
System.register(["./modulepreload-polyfill-legacy-thrsW4a0.js","./bootstrap-icons-legacy-DouCT31f.js","./styles-legacy-CoGB2_BN.js"],(function(e,l){"use strict";return{setters:[null,null,null],execute:function(){}}}));

1
dist/assets/basket-BsEZQu2l.js vendored Normal file
View File

@@ -0,0 +1 @@
import"./modulepreload-polyfill-B5Qt9EMX.js";/* empty css *//* empty css */function t(){import.meta.url,import("_").catch(()=>1),async function*(){}().next()}export{t as __vite_legacy_guard};

1
dist/assets/basket-legacy-CRC7rfsn.js vendored Normal file
View File

@@ -0,0 +1 @@
System.register(["./modulepreload-polyfill-legacy-thrsW4a0.js","./bootstrap-icons-legacy-DouCT31f.js","./styles-legacy-CoGB2_BN.js"],(function(e,l){"use strict";return{setters:[null,null,null],execute:function(){}}}));

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

1
dist/assets/file-BsEZQu2l.js vendored Normal file
View File

@@ -0,0 +1 @@
import"./modulepreload-polyfill-B5Qt9EMX.js";/* empty css *//* empty css */function t(){import.meta.url,import("_").catch(()=>1),async function*(){}().next()}export{t as __vite_legacy_guard};

1
dist/assets/file-legacy-CRC7rfsn.js vendored Normal file
View File

@@ -0,0 +1 @@
System.register(["./modulepreload-polyfill-legacy-thrsW4a0.js","./bootstrap-icons-legacy-DouCT31f.js","./styles-legacy-CoGB2_BN.js"],(function(e,l){"use strict";return{setters:[null,null,null],execute:function(){}}}));

1
dist/assets/main-ByqzIKWg.js vendored Normal file
View File

@@ -0,0 +1 @@
import"./modulepreload-polyfill-B5Qt9EMX.js";/* empty css */function t(){import.meta.url,import("_").catch(()=>1),async function*(){}().next()}export{t as __vite_legacy_guard};

1
dist/assets/main-legacy-DogpbE9l.js vendored Normal file
View File

@@ -0,0 +1 @@
System.register(["./modulepreload-polyfill-legacy-thrsW4a0.js","./styles-legacy-CoGB2_BN.js"],(function(e,l){"use strict";return{setters:[null,null],execute:function(){}}}));

View File

@@ -0,0 +1 @@
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function s(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?r.credentials="include":e.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=s(e);fetch(e.href,r)}})();

View File

@@ -0,0 +1 @@
System.register([],(function(e,t){"use strict";return{execute:function(){}}}));

View File

@@ -0,0 +1 @@
System.register(["./bootstrap-icons-legacy-DouCT31f.js","./styles-legacy-CoGB2_BN.js"],(function(e,t){"use strict";return{setters:[null,null],execute:function(){}}}));

1
dist/assets/password-ufRREwff.js vendored Normal file
View File

@@ -0,0 +1 @@
/* empty css *//* empty css */function t(){import.meta.url,import("_").catch(()=>1),async function*(){}().next()}export{t as __vite_legacy_guard};

1
dist/assets/photo-BsEZQu2l.js vendored Normal file
View File

@@ -0,0 +1 @@
import"./modulepreload-polyfill-B5Qt9EMX.js";/* empty css *//* empty css */function t(){import.meta.url,import("_").catch(()=>1),async function*(){}().next()}export{t as __vite_legacy_guard};

1
dist/assets/photo-legacy-CRC7rfsn.js vendored Normal file
View File

@@ -0,0 +1 @@
System.register(["./modulepreload-polyfill-legacy-thrsW4a0.js","./bootstrap-icons-legacy-DouCT31f.js","./styles-legacy-CoGB2_BN.js"],(function(e,l){"use strict";return{setters:[null,null,null],execute:function(){}}}));

File diff suppressed because one or more lines are too long

1
dist/assets/styles-CtPCArmk.css vendored Normal file
View File

@@ -0,0 +1 @@
body{min-height:100vh;display:flex;flex-direction:column}.container-fluid{flex-grow:1;display:flex;flex-direction:column}main{flex-grow:1}.logo{width:60px;height:60px;border:2px solid #ff0088}.btn-pink{background-color:#f08;color:#fff}.btn-pink:hover{background-color:#ee80ee;color:#fff}.text-pink{color:#f08}.album-container,.basket-container,.file-container,.photo-container,.subscriptions-container{display:flex;flex-wrap:wrap;justify-content:center;gap:1rem;padding:0 1rem}.album-container .col,.basket-container .col,.file-container .col,.photo-container .col,.subscriptions-container .col{flex:0 0 auto;width:100%;max-width:300px}@media (min-width: 768px){.album-container .col,.basket-container .col,.file-container .col,.photo-container .col,.subscriptions-container .col{width:33.333333%}}@media (max-width: 767px){.album-container .col,.basket-container .col,.file-container .col,.photo-container .col,.subscriptions-container .col{width:100%;max-width:400px}}footer{flex-shrink:0}.social-links{display:flex;justify-content:flex-end;align-items:center}@media (max-width: 991px){.social-links{justify-content:center}}@media (max-width: 600px){.logo{width:50px;height:50px}}#dropZone:hover{background-color:#f8d7da;cursor:pointer}

1
dist/assets/styles-legacy-CoGB2_BN.js vendored Normal file
View File

@@ -0,0 +1 @@
System.register([],(function(o,e){"use strict";return{execute:function(){var o=document.createElement("style");o.textContent="body{min-height:100vh;display:flex;flex-direction:column}.container-fluid{flex-grow:1;display:flex;flex-direction:column}main{flex-grow:1}.logo{width:60px;height:60px;border:2px solid #ff0088}.btn-pink{background-color:#f08;color:#fff}.btn-pink:hover{background-color:#ee80ee;color:#fff}.text-pink{color:#f08}.album-container,.basket-container,.file-container,.photo-container,.subscriptions-container{display:flex;flex-wrap:wrap;justify-content:center;gap:1rem;padding:0 1rem}.album-container .col,.basket-container .col,.file-container .col,.photo-container .col,.subscriptions-container .col{flex:0 0 auto;width:100%;max-width:300px}@media (min-width: 768px){.album-container .col,.basket-container .col,.file-container .col,.photo-container .col,.subscriptions-container .col{width:33.333333%}}@media (max-width: 767px){.album-container .col,.basket-container .col,.file-container .col,.photo-container .col,.subscriptions-container .col{width:100%;max-width:400px}}footer{flex-shrink:0}.social-links{display:flex;justify-content:flex-end;align-items:center}@media (max-width: 991px){.social-links{justify-content:center}}@media (max-width: 600px){.logo{width:50px;height:50px}}#dropZone:hover{background-color:#f8d7da;cursor:pointer}\n/*$vite$:1*/",document.head.appendChild(o)}}}));

1
dist/assets/upload-BsEZQu2l.js vendored Normal file
View File

@@ -0,0 +1 @@
import"./modulepreload-polyfill-B5Qt9EMX.js";/* empty css *//* empty css */function t(){import.meta.url,import("_").catch(()=>1),async function*(){}().next()}export{t as __vite_legacy_guard};

1
dist/assets/upload-legacy-CRC7rfsn.js vendored Normal file
View File

@@ -0,0 +1 @@
System.register(["./modulepreload-polyfill-legacy-thrsW4a0.js","./bootstrap-icons-legacy-DouCT31f.js","./styles-legacy-CoGB2_BN.js"],(function(e,l){"use strict";return{setters:[null,null,null],execute:function(){}}}));

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

6
dist/bootstrap/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

136
dist/index.html vendored Normal file
View File

@@ -0,0 +1,136 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SweetyDisk</title>
<link href="./bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="./bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<script type="module" crossorigin src="./assets/main-ByqzIKWg.js"></script>
<link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="stylesheet" crossorigin href="./assets/styles-CtPCArmk.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="./src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="/Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none" accept="image/*">
</div>
<a href="/index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="/File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="/Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="/Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<div class="card text-center shadow mb-4">
<div class="card-body">
<h2 class="display-5 text-pink">Добро пожаловать на SweetyDisk!</h2>
<p class="lead">Здесь вы сможете загружать и хранить важные для вас данные.</p>
<p class="lead">А самое главное по очень сладкой цене.</p>
</div>
</div>
<div class="card mb-4">
<div class="card-body">
<h3 class="h5">Выбрать подписку</h3>
<form id="subscriptionForm" class="row g-3">
<div class="col-md-8">
<select class="form-control" id="subscriptionSelect">
<option value="" disabled selected>Выберите подписку</option>
<option value="Сладкая (1 год, 1 Тб, 1000 руб)">Сладкая (1 год, 1 Тб, 1000 руб)</option>
<option value="Сладкая Плюс (10 лет, 10 Тб, 10000 руб)">Сладкая Плюс (10 лет, 10 Тб, 10000 руб)</option>
<option value="Супер Сладкая (30 лет, 30 Тб, 30000 руб)">Супер Сладкая (30 лет, 30 Тб, 30000 руб)</option>
</select>
</div>
<div class="col-md-4">
<button type="submit" class="btn btn-pink w-100"><i class="bi bi-plus-circle"></i> Выбрать</button>
</div>
</form>
</div>
</div>
<div id="currentSubscription" class="card mb-4 d-none">
<div class="card-body d-flex justify-content-between align-items-center">
<div>
Текущая подписка: <strong id="subscriptionName"></strong>. Стоимость: <strong id="subscriptionPrice"></strong>.
</div>
<button id="deleteCurrentSubscription" class="btn btn-danger btn-sm">Удалить подписку</button>
</div>
</div>
<div class="subscriptions-container" id="subscriptionsContainer">
<div class="col">
<div class="card h-100 shadow">
<img src="./src/photo1.jpg" class="card-img-top" alt="Фото для Супер Сладкая">
<div class="card-body">
<h5 class="card-title">Супер Сладкая</h5>
<p class="card-text">30 лет, 30 Тб, 30000 руб</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100 shadow">
<img src="./src/photo2.jpg" class="card-img-top" alt="Фото для Сладкая Плюс">
<div class="card-body">
<h5 class="card-title">Сладкая Плюс</h5>
<p class="card-text">10 лет, 10 Тб, 10000 руб</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100 shadow">
<img src="./src/photo3.jpg" class="card-img-top" alt="Фото для Сладкая">
<div class="card-body">
<h5 class="card-title">Сладкая</h5>
<p class="card-text">1 год, 1 Тб, 1000 руб</p>
</div>
</div>
</div>
</div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="./main.js"></script>
<script type="text/javascript" src="./bootstrap/js/bootstrap.bundle.min.js"></script>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-CBvV26yc.js"></script>
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/main-legacy-DogpbE9l.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
</body>

6
dist/main.js vendored Normal file
View File

@@ -0,0 +1,6 @@
import Controller from '../controller.js';
console.log('main.js is loaded');
document.addEventListener('DOMContentLoaded', () => {
const controller = new Controller();
controller.init();
});

View File

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Before

Width:  |  Height:  |  Size: 408 KiB

After

Width:  |  Height:  |  Size: 408 KiB

BIN
dist/src/photo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

Before

Width:  |  Height:  |  Size: 586 KiB

After

Width:  |  Height:  |  Size: 586 KiB

View File

Before

Width:  |  Height:  |  Size: 313 KiB

After

Width:  |  Height:  |  Size: 313 KiB

View File

Before

Width:  |  Height:  |  Size: 402 KiB

After

Width:  |  Height:  |  Size: 402 KiB

BIN
dist/src/telegram.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
dist/src/vkontakte.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,57 +1,129 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SweetyDisk</title>
<link rel="stylesheet" href="css/Style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SweetyDisk</title>
<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<img class="cover" src="src/cover.png" alt="Логотип SweetyDisk"/>
<div class="table-container">
<table>
<tr>
<td><a href="File.html" class="button">Файлы</a></td>
</tr>
<tr>
<td><a href="Photo.html" class="button">Фото</a></td>
</tr>
<tr>
<td><a href="Album.html" class="button">Альбом</a></td>
</tr>
<tr>
<td><a href="Basket.html" class="button">Корзина</a></td>
</tr>
</table>
<button class="upload-button" onclick="document.getElementById('file-input').click()">Загрузить</button>
<input type="file" id="file-input" style="display: none;">
<a href="Password.html" class="login-button">Вход</a>
</div>
<div class="text-block">
<h2>Добро пожаловать на SweetyDisk!</h2>
<p>Здесь вы сможете загружать и хранить важные для вас данные.</p>
<p>А самое главное по очень сладкой цене.</p>
</div>
<div class="new-table-container">
<table>
<tr>
<th colspan="3">Варианты Подписки</th>
</tr>
<tr>
<td>30 лет - 30.000 рублей - 30Тбайт</td>
<td>10 лет - 10.000 рублей - 10Тбайт</td>
<td>1 год - 1.000 рублей - 1Тбайт</td>
</tr>
</table>
</div>
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid p-0 flex-grow-1">
<header class="bg-primary shadow p-3">
<div class="row align-items-center">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<div class="d-flex align-items-center">
<img src="/src/cover.png" alt="Логотип SweetyDisk" class="logo me-3 rounded">
<h1 class="h3 text-white mb-0">SweetyDisk</h1>
</div>
</div>
<nav class="col-md-6 col-12">
<div class="d-flex justify-content-end flex-wrap gap-2">
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list"></i> Меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="/Password.html"><i class="bi bi-box-arrow-in-right"></i> Войти</a></li>
<li><a class="dropdown-item" href="/Upload.html"><i class="bi bi-upload"></i> Загрузить</a></li>
</ul>
<input type="file" id="file-input" class="d-none" accept="image/*">
</div>
<a href="/index.html" class="btn btn-pink"><i class="bi bi-house"></i> Главная</a>
<a href="/File.html" class="btn btn-pink"><i class="bi bi-file-earmark"></i> Файлы</a>
<a href="/Photo.html" class="btn btn-pink"><i class="bi bi-camera"></i> Фото</a>
<a href="/Album.html" class="btn btn-pink"><i class="bi bi-images"></i> Альбом</a>
</div>
</nav>
</div>
</header>
<main class="container my-4 flex-grow-1">
<div class="card text-center shadow mb-4">
<div class="card-body">
<h2 class="display-5 text-pink">Добро пожаловать на SweetyDisk!</h2>
<p class="lead">Здесь вы сможете загружать и хранить важные для вас данные.</p>
<p class="lead">А самое главное по очень сладкой цене.</p>
</div>
</div>
<div class="card mb-4">
<div class="card-body">
<h3 class="h5">Выбрать подписку</h3>
<form id="subscriptionForm" class="row g-3">
<div class="col-md-8">
<select class="form-control" id="subscriptionSelect">
<option value="" disabled selected>Выберите подписку</option>
<option value="Сладкая (1 год, 1 Тб, 1000 руб)">Сладкая (1 год, 1 Тб, 1000 руб)</option>
<option value="Сладкая Плюс (10 лет, 10 Тб, 10000 руб)">Сладкая Плюс (10 лет, 10 Тб, 10000 руб)</option>
<option value="Супер Сладкая (30 лет, 30 Тб, 30000 руб)">Супер Сладкая (30 лет, 30 Тб, 30000 руб)</option>
</select>
</div>
<div class="col-md-4">
<button type="submit" class="btn btn-pink w-100"><i class="bi bi-plus-circle"></i> Выбрать</button>
</div>
</form>
</div>
</div>
<div id="currentSubscription" class="card mb-4 d-none">
<div class="card-body d-flex justify-content-between align-items-center">
<div>
Текущая подписка: <strong id="subscriptionName"></strong>. Стоимость: <strong id="subscriptionPrice"></strong>.
</div>
<button id="deleteCurrentSubscription" class="btn btn-danger btn-sm">Удалить подписку</button>
</div>
</div>
<div class="subscriptions-container" id="subscriptionsContainer">
<div class="col">
<div class="card h-100 shadow">
<img src="/src/photo1.jpg" class="card-img-top" alt="Фото для Супер Сладкая">
<div class="card-body">
<h5 class="card-title">Супер Сладкая</h5>
<p class="card-text">30 лет, 30 Тб, 30000 руб</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100 shadow">
<img src="/src/photo2.jpg" class="card-img-top" alt="Фото для Сладкая Плюс">
<div class="card-body">
<h5 class="card-title">Сладкая Плюс</h5>
<p class="card-text">10 лет, 10 Тб, 10000 руб</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100 shadow">
<img src="/src/photo3.jpg" class="card-img-top" alt="Фото для Сладкая">
<div class="card-body">
<h5 class="card-title">Сладкая</h5>
<p class="card-text">1 год, 1 Тб, 1000 руб</p>
</div>
</div>
</div>
</div>
</main>
<footer class="bg-dark text-white p-4 mt-auto">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<h4 class="text-pink">Контакты</h4>
<address>
Адрес: г. Ульяновск<br>
Телефон: +7 (495) 123-45-67<br>
Email: info@sweetydisk.ru<br>
Время работы: Пн-Пт, 9:0018:00
</address>
</div>
<div class="col-md-6 social-links">
<div class="d-flex gap-3">
<a href="#" class="text-white"><i class="bi bi-vimeo"></i> VK</a>
<a href="#" class="text-white"><i class="bi bi-telegram"></i> Telegram</a>
</div>
</div>
</div>
<small class="d-block text-center mt-3">© 2023 SweetyDisk. Все права защищены.</small>
</footer>
</div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>

174
model.js Normal file
View File

@@ -0,0 +1,174 @@
const API_URL = 'http://localhost:3000';
class Model {
constructor() {
this.API_URL = API_URL;
}
async fetchAlbums() {
const response = await fetch(`${this.API_URL}/albums`);
if (!response.ok) throw new Error('Failed to fetch albums');
return response.json();
}
async fetchPhotos() {
const response = await fetch(`${this.API_URL}/photos`);
if (!response.ok) throw new Error('Failed to fetch photos');
return response.json();
}
async fetchFiles() {
const response = await fetch(`${this.API_URL}/files`);
if (!response.ok) throw new Error('Failed to fetch files');
return response.json();
}
async fetchBasket() {
const response = await fetch(`${this.API_URL}/basket`);
if (!response.ok) throw new Error('Failed to fetch basket');
return response.json();
}
async createAlbum(name, src, description, categoryId, visibility, owner, createdAt, tags) {
const response = await fetch(`${this.API_URL}/albums`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, src, description, categoryId, visibility, owner, createdAt, tags }),
});
if (!response.ok) throw new Error('Failed to create album');
return response.json();
}
async createPhoto(src, description, categoryId, photoTypeId, resolution, size, createdAt, tags) {
const response = await fetch(`${this.API_URL}/photos`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ src, description, categoryId, photoTypeId, resolution, size, createdAt, tags }),
});
if (!response.ok) throw new Error('Failed to create photo');
return response.json();
}
async createFile(src, name, description, categoryId, fileTypeId, size, format, createdAt, tags) {
const response = await fetch(`${this.API_URL}/files`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ src, name, description, categoryId, fileTypeId, size, format, createdAt, tags }),
});
if (!response.ok) throw new Error('Failed to create file');
return response.json();
}
async updateAlbum(id, name, description, categoryId, visibility, owner, createdAt, tags) {
const response = await fetch(`${this.API_URL}/albums/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, description, categoryId, visibility, owner, createdAt, tags }),
});
if (!response.ok) throw new Error('Failed to update album');
return response.json();
}
async updatePhoto(id, description, categoryId, photoTypeId, resolution, size, createdAt, tags) {
const response = await fetch(`${this.API_URL}/photos/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ description, categoryId, photoTypeId, resolution, size, createdAt, tags }),
});
if (!response.ok) throw new Error('Failed to update photo');
return response.json();
}
async updateFile(id, name, description, categoryId, fileTypeId, size, format, createdAt, tags) {
const response = await fetch(`${this.API_URL}/files/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, description, categoryId, fileTypeId, size, format, createdAt, tags }),
});
if (!response.ok) throw new Error('Failed to update file');
return response.json();
}
async moveToBasket(item, type) {
const basketItem = { ...item, type };
delete basketItem.id;
console.log(`Saving to basket:`, basketItem);
const response = await fetch(`${this.API_URL}/basket`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(basketItem),
});
if (!response.ok) throw new Error(`Failed to move to basket: ${response.statusText}`);
return response.json();
}
async restoreFromBasket(id, type) {
const basketItem = await this.getBasketItem(id);
console.log(`Restoring from basket:`, basketItem);
const response = await fetch(`${this.API_URL}/${type}s`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: basketItem.name,
src: basketItem.src,
description: basketItem.description,
categoryId: basketItem.categoryId,
visibility: basketItem.visibility,
owner: basketItem.owner,
createdAt: basketItem.createdAt,
tags: basketItem.tags,
photoTypeId: basketItem.photoTypeId,
fileTypeId: basketItem.fileTypeId,
resolution: basketItem.resolution,
size: basketItem.size,
format: basketItem.format
}),
});
if (!response.ok) throw new Error('Failed to restore item');
await this.deleteFromBasket(id);
return response.json();
}
async deleteFromBasket(id) {
const response = await fetch(`${this.API_URL}/basket/${id}`, {
method: 'DELETE',
});
if (!response.ok) throw new Error('Failed to delete from basket');
}
async clearBasket() {
const basket = await this.fetchBasket();
await Promise.all(
basket.map(item => fetch(`${this.API_URL}/basket/${item.id}`, { method: 'DELETE' }))
);
}
async getBasketItem(id) {
const response = await fetch(`${this.API_URL}/basket/${id}`);
if (!response.ok) throw new Error('Failed to fetch basket item');
return response.json();
}
async deleteAlbum(id) {
const response = await fetch(`${this.API_URL}/albums/${id}`, {
method: 'DELETE',
});
if (!response.ok) throw new Error('Failed to delete album');
}
async deletePhoto(id) {
const response = await fetch(`${this.API_URL}/photos/${id}`, {
method: 'DELETE',
});
if (!response.ok) throw new Error('Failed to delete photo');
}
async deleteFile(id) {
const response = await fetch(`${this.API_URL}/files/${id}`, {
method: 'DELETE',
});
if (!response.ok) throw new Error('Failed to delete file');
}
}
export default Model;

5939
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

25
package.json Normal file
View File

@@ -0,0 +1,25 @@
{
"name": "sweety-disk",
"version": "1.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .js,.jsx",
"format": "prettier --write .",
"server": "json-server --watch db.json --port 3000"
},
"devDependencies": {
"@vitejs/plugin-legacy": "^5.0.0",
"eslint": "^8.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"prettier": "^3.0.0",
"vite": "^5.0.0",
"json-server": "^0.17.0"
},
"dependencies": {
"bootstrap": "^5.3.0",
"bootstrap-icons": "^1.11.0"
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6
public/main.js Normal file
View File

@@ -0,0 +1,6 @@
import Controller from '../controller.js';
console.log('main.js is loaded');
document.addEventListener('DOMContentLoaded', () => {
const controller = new Controller();
controller.init();
});

BIN
public/src/Album.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
public/src/Album1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
public/src/Album2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/src/Cart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
public/src/Cart1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
public/src/Cart2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
public/src/File.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
public/src/File2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
public/src/File3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/src/cover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
public/src/cover1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

BIN
public/src/photo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
public/src/photo1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 KiB

BIN
public/src/photo2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

BIN
public/src/photo3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

BIN
public/src/telegram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
public/src/vkontakte.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

110
styles.css Normal file
View File

@@ -0,0 +1,110 @@
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container-fluid {
flex-grow: 1;
display: flex;
flex-direction: column;
}
main {
flex-grow: 1;
}
.logo {
width: 60px;
height: 60px;
border: 2px solid #ff0088;
}
.btn-pink {
background-color: #ff0088;
color: white;
}
.btn-pink:hover {
background-color: #ee80ee;
color: white;
}
.text-pink {
color: #ff0088;
}
.album-container,
.basket-container,
.file-container,
.photo-container,
.subscriptions-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1rem;
padding: 0 1rem;
}
.album-container .col,
.basket-container .col,
.file-container .col,
.photo-container .col,
.subscriptions-container .col {
flex: 0 0 auto;
width: 100%;
max-width: 300px;
}
@media (min-width: 768px) {
.album-container .col,
.basket-container .col,
.file-container .col,
.photo-container .col,
.subscriptions-container .col {
width: 33.333333%;
}
}
@media (max-width: 767px) {
.album-container .col,
.basket-container .col,
.file-container .col,
.photo-container .col,
.subscriptions-container .col {
width: 100%;
max-width: 400px;
}
}
footer {
flex-shrink: 0;
}
.social-links {
display: flex;
justify-content: flex-end;
align-items: center;
}
@media (max-width: 991px) {
.social-links {
justify-content: center;
}
}
@media (max-width: 600px) {
.logo {
width: 50px;
height: 50px;
}
}
#dropZone:hover {
background-color: #f8d7da;
cursor: pointer;
}

131
view.js Normal file
View File

@@ -0,0 +1,131 @@
class View {
showAlert(message, type) {
const alertContainer = document.createElement('div');
alertContainer.className = `alert alert-${type} alert-dismissible fade show`;
alertContainer.role = 'alert';
alertContainer.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
`;
const header = document.querySelector('header');
if (header && header.nextElementSibling) {
header.parentNode.insertBefore(alertContainer, header.nextElementSibling);
} else {
document.body.prepend(alertContainer);
}
setTimeout(() => alertContainer.remove(), 3000);
}
clearForm(formSelector) {
const form = document.querySelector(formSelector);
if (form) form.reset();
}
renderItems(containerSelector, items, type, editCallback, deleteCallback) {
const container = document.querySelector(containerSelector);
if (!container) return;
container.innerHTML = '';
items.forEach(item => {
const card = document.createElement('div');
card.className = 'col-md-4 mb-4';
let content = '';
let details = '';
if (type === 'album') {
content = `
<div class="card shadow-sm">
<img src="${item.src}" class="card-img-top" alt="${item.name}">
<div class="card-body">
<h5 class="card-title">${item.name}</h5>
<p class="card-text">${item.description}</p>
`;
details = `
<p class="card-text"><small>Категория: ${item.categoryId === 1 ? 'Личные' : 'Рабочие'}</small></p>
<p class="card-text"><small>Видимость: ${item.visibility === 'public' ? 'Публичный' : 'Приватный'}</small></p>
<p class="card-text"><small>Владелец: ${item.owner}</small></p>
<p class="card-text"><small>Теги: ${item.tags.join(', ')}</small></p>
<p class="card-text"><small>Создано: ${new Date(item.createdAt).toLocaleDateString()}</small></p>
`;
} else if (type === 'photo') {
content = `
<div class="card shadow-sm">
<img src="${item.src}" class="card-img-top" alt="Фото">
<div class="card-body">
<p class="card-text">${item.description}</p>
`;
details = `
<p class="card-text"><small>Категория: ${item.categoryId === 1 ? 'Личные' : 'Рабочие'}</small></p>
<p class="card-text"><small>Тип: ${item.photoTypeId === 1 ? 'Черно-белая' : 'Цветная'}</small></p>
<p class="card-text"><small>Разрешение: ${item.resolution}</small></p>
<p class="card-text"><small>Размер: ${item.size} КБ</small></p>
<p class="card-text"><small>Теги: ${item.tags.join(', ')}</small></p>
<p class="card-text"><small>Последнее изменение: ${new Date(item.createdAt).toLocaleDateString()}</small></p>
`;
} else if (type === 'file') {
content = `
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">${item.name}</h5>
<p class="card-text">${item.description}</p>
`;
details = `
<p class="card-text"><small>Категория: ${item.categoryId === 1 ? 'Личные' : 'Рабочие'}</small></p>
<p class="card-text"><small>Тип: ${item.fileTypeId === 1 ? 'Документ' : 'Архив'}</small></p>
<p class="card-text"><small>Размер: ${item.size} КБ</small></p>
<p class="card-text"><small>Формат: ${item.format}</small></p>
<p class="card-text"><small>Теги: ${item.tags.join(', ')}</small></p>
<p class="card-text"><small>Последнее изменение: ${new Date(item.createdAt).toLocaleDateString()}</small></p>
`;
}
content += `
${details}
<div class="d-flex justify-content-between">
${editCallback ? `<button class="btn btn-primary btn-sm edit-btn" data-id="${item.id}">Редактировать</button>` : ''}
<button class="btn btn-danger btn-sm delete-btn" data-id="${item.id}">Удалить</button>
</div>
</div>
</div>
`;
card.innerHTML = content;
container.appendChild(card);
if (editCallback) {
card.querySelector('.edit-btn')?.addEventListener('click', () => editCallback(item));
}
card.querySelector('.delete-btn')?.addEventListener('click', () => deleteCallback(item));
});
}
renderBasketItems(containerSelector, items, restoreCallback, deleteCallback) {
const container = document.querySelector(containerSelector);
if (!container) return;
container.innerHTML = '';
items.forEach(item => {
const card = document.createElement('div');
card.className = 'col-md-4 mb-4';
let content = `
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">${item.name || 'Без названия'}</h5>
<p class="card-text">Тип: ${item.type}</p>
<div class="d-flex justify-content-between">
<button class="btn btn-success btn-sm restore-btn" data-id="${item.id}">Восстановить</button>
<button class="btn btn-danger btn-sm delete-btn" data-id="${item.id}">Удалить</button>
</div>
</div>
</div>
`;
card.innerHTML = content;
container.appendChild(card);
card.querySelector('.restore-btn')?.addEventListener('click', () => restoreCallback(item));
card.querySelector('.delete-btn')?.addEventListener('click', () => deleteCallback(item));
});
}
}
export default View;

21
vite.config.js Normal file
View File

@@ -0,0 +1,21 @@
import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';
import { resolve } from 'path';
export default defineConfig({
plugins: [legacy()],
base: './',
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
album: resolve(__dirname, 'Album.html'),
file: resolve(__dirname, 'File.html'),
password: resolve(__dirname, 'Password.html'),
photo: resolve(__dirname, 'Photo.html'),
upload: resolve(__dirname, 'Upload.html'),
basket: resolve(__dirname, 'Basket.html'),
},
},
},
});

BIN
Отчет 4 лабы.docx Normal file

Binary file not shown.

Binary file not shown.