This commit is contained in:
Your Name~ 2023-12-19 14:33:55 +04:00
parent c6f96fed5b
commit f1f2120b97
9 changed files with 17 additions and 663 deletions

View File

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

View File

@ -1,181 +0,0 @@
// film.js
import { getAllLines, getAllItemTypes } from './lines-rest-api.js';
async function loadMovies() {
try {
const moviesData = await getAllLines();
addMovieCards(moviesData);
} catch (error) {
console.error("Error loading movies:", error);
}
}
async function loadMoviesindex() {
try {
const moviesData = await getAllLines();
addMovieCardsindex(moviesData);
} catch (error) {
console.error("Error loading movies:", error);
}
}
async function loadMoviesBygenre() {
try {
const moviesData = await getAllLines();
const itemTypes = await getAllItemTypes();
addMoviesByGenre(moviesData, itemTypes);
} catch (error) {
console.error("Error loading movies:", error);
}
}
function addMoviesByGenre(moviesData, itemTypes) {
var containers = document.querySelectorAll(".movie-container");
containers.forEach(function (container) {
var genre = container.querySelector("h1").textContent;
// Находим все фильмы для данного жанра
var genreMovies = moviesData.filter(function (movie) {
var itemType = itemTypes[movie.itemsId-1];
if (itemType && itemType.genre === genre) {
return true;
} else {
console.error("Invalid itemTypes for movie:", movie);
console.log("itemType:", itemType);
console.log("genre:", genre);
return false;
}
});
genreMovies.forEach(function (movie) {
addMovieCardsByContainer(container, movie);
});
});
}
function addMovieCardsByContainer(container,movie) {
if (!container) {
console.error("Movie container not found");
return;
}
var movieCard = document.createElement("div");
movieCard.className = "movie-card";
var image = document.createElement("img");
// Проверяем, есть ли у фильма изображение, и вставляем соответствующее изображение
image.src = movie.image ? movie.image : "https://via.placeholder.com/300x400";
image.alt = "Movie Image";
var content = document.createElement("div");
content.className = "movie-card-content";
var title = document.createElement("h2");
title.textContent = movie.name;
var description = document.createElement("p");
description.textContent = "Рейтинг: " + movie.rating;
content.appendChild(title);
content.appendChild(description);
movieCard.appendChild(image);
movieCard.appendChild(content);
container.appendChild(movieCard);
}
function addMovieCards(moviesData) {
var container = document.getElementById("movie-container");
if (!container) {
console.error("Movie container not found");
return;
}
moviesData.forEach(function (movie) {
var movieCard = document.createElement("div");
movieCard.className = "movie-card";
var image = document.createElement("img");
// Проверяем, есть ли у фильма изображение, и вставляем соответствующее изображение
image.src = movie.image ? movie.image : "https://via.placeholder.com/300x400";
image.alt = "Movie Image";
var content = document.createElement("div");
content.className = "movie-card-content";
var title = document.createElement("h2");
title.textContent = movie.name;
var description = document.createElement("p");
description.textContent = "Рейтинг: " + movie.rating;
content.appendChild(title);
content.appendChild(description);
movieCard.appendChild(image);
movieCard.appendChild(content);
container.appendChild(movieCard);
});
}
function addMovieCardsindex(moviesData) {
var containers = document.querySelectorAll(".movie-container");
if (!containers || containers.length === 0) {
console.error("Movie containers not found");
return;
}
containers.forEach(function (container) {
moviesData.forEach(function (movie) {
var movieCard = document.createElement("div");
movieCard.className = "movie-card";
var image = document.createElement("img");
// Проверяем, есть ли у фильма изображение, и вставляем соответствующее изображение
image.src = movie.image ? movie.image : "https://via.placeholder.com/300x400";
image.alt = "Movie Image";
var content = document.createElement("div");
content.className = "movie-card-content";
var title = document.createElement("h2");
title.textContent = movie.name;
var description = document.createElement("p");
description.textContent = "Рейтинг: " + movie.rating;
content.appendChild(title);
content.appendChild(description);
movieCard.appendChild(image);
movieCard.appendChild(content);
container.appendChild(movieCard);
});
});
}
document.addEventListener('DOMContentLoaded', function () {
if (window.location.pathname.includes("page2.html")) {
// Запуск функции для page2.html
loadMovies();
}else if (window.location.pathname.includes("page5.html")) {
// Запуск функции для page5.html
loadMovies();
}else if (window.location.pathname.includes("page3.html")) {
// Запуск функции для page3.html
loadMoviesBygenre();
}else if (window.location.pathname.includes("index.html")) {
// Запуск функции для index.html
loadMoviesindex();
}
});

View File

@ -1,87 +0,0 @@
const serverUrl = "http://localhost:8081";
export function createLineObject(item,name, rating, release_date, director,image) {
return {
itemsId: parseInt(item),
name,
rating,
release_date,
director,
image,
};
}
export async function getAllItemTypes() {
const response = await fetch(`${serverUrl}/items`);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
export async function getAllLines() {
const response = await fetch(`${serverUrl}/lines?_expand=items`);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
export async function getLine(id) {
const response = await fetch(`${serverUrl}/lines/${id}?_expand=items`);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
export async function createLine(item,name, rating, release_date, director,image) {
const itemObject = createLineObject(item,name, rating, release_date, director,image);
const options = {
method: "POST",
body: JSON.stringify(itemObject),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
};
const response = await fetch(`${serverUrl}/lines`, options);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
export async function updateLine(id,item,name, rating, release_date, director,image) {
const itemObject = createLineObject(item,name, rating, release_date, director,image);
const options = {
method: "PUT",
body: JSON.stringify(itemObject),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
};
const response = await fetch(`${serverUrl}/lines/${id}`, options);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
export async function deleteLine(id) {
const options = {
method: "DELETE",
};
const response = await fetch(`${serverUrl}/lines/${id}`, options);
if (!response.ok) {
throw response.statusText;
}
window.location.reload(true);
return response.json();
}

View File

@ -1,82 +0,0 @@
export const cntrls = {
button: document.getElementById("items-add"),
table: document.querySelector("#items-table tbody"),
form: document.getElementById("items-form"),
lineId: document.getElementById("items-line-id"),
filmname: document.getElementById("name"),
itemsType: document.getElementById("item"),
rating: document.getElementById("rating"),
releaseDate: document.getElementById("releaseDate"),
director: document.getElementById("director"),
image: document.getElementById("image"),
imagePreview: document.getElementById("image-preview"),
};
export const imagePlaceholder = "https://via.placeholder.com/300x400";
export function createItemsOption(name, value = "", isSelected = false) {
const option = document.createElement("option");
option.value = value || "";
option.selected = isSelected;
option.text = name;
return option;
}
function createTableAnchor(icon, callback) {
const i = document.createElement("i");
i.classList.add("fa-solid", icon);
const a = document.createElement("a");
a.href = "#";
a.appendChild(i);
a.onclick = (event) => {
event.preventDefault();
event.stopPropagation();
callback();
};
const td = document.createElement("td");
td.appendChild(a);
return td;
}
function createTableColumn(value) {
const td = document.createElement("td");
td.textContent = value;
return td;
}
export function createTableRow(line, index, editCallback, deleteCallback, items) {
const rowNumber = document.createElement("th");
rowNumber.scope = "row";
rowNumber.textContent = index + 1;
const row = document.createElement("tr");
row.id = `line-${line.id}`;
row.appendChild(rowNumber);
// Добавляем свойства из массива "lines"
row.appendChild(createTableColumn(line.name)); // Название фильма
// Добавляем жанр на основе "genre_id" из массива "items"
const genreItem = items.find(item => item.id === line.itemsId);
const genre = genreItem ? genreItem.genre : '';
row.appendChild(createTableColumn(genre)); // Жанр
row.appendChild(createTableColumn(line.rating)); // Рейтинг
row.appendChild(createTableColumn(formatDate(line.release_date))); // Дата
row.appendChild(createTableColumn(line.director)); // Режиссер
// Добавляем ячейки для редактирования и удаления
row.appendChild(createTableAnchor("fa-pencil", editCallback));
row.appendChild(createTableAnchor("fa-trash", deleteCallback));
return row;
}
// Функция для форматирования даты
function formatDate(dateString) {
const options = { year: 'numeric', month: 'long', day: 'numeric' };
return new Date(dateString).toLocaleDateString(undefined, options);
}

View File

@ -1,213 +0,0 @@
import {
createLine,
deleteLine,
getAllItemTypes,
getAllLines,
getLine,
updateLine,
} from "./lines-rest-api";
import {
cntrls,
createItemsOption,
createTableRow,
imagePlaceholder,
} from "./lines-ui";
async function drawItemsSelect() {
const genres = await getAllItemTypes();
cntrls.itemsType.innerHTML = "";
cntrls.itemsType.appendChild(createItemsOption("Выберите значение", "", true));
genres.forEach((genre) => {
cntrls.itemsType.appendChild(createItemsOption(genre.genre, genre.id));
});
}
async function drawLinesTable() {
console.info("Try to load data");
if (!cntrls.table) {
return;
}
const data = await getAllLines();
const genres = await getAllItemTypes();
cntrls.table.innerHTML = "";
data.forEach((item, index) => {
cntrls.table.appendChild(
createTableRow(
item,
index,
() => location.assign(`editpage.html?id=${item.id}`),
() => deleteLine(item.id),
genres
),
);
});
}
async function addLine(item,name, rating, release_date, director,image) {
console.info("Try to add item");
const data = await createLine(item,name, rating, release_date, director,image);
console.info("Added");
console.info(data);
drawLinesTable();
}
async function editLine(id,item,name, rating, release_date, director,image) {
console.info("Try to update item");
const data = await updateLine(id,item,name, rating, release_date, director,image);
console.info("Updated");
console.info(data);
drawLinesTable();
}
async function readFile(file) {
const reader = new FileReader();
// создание Promise-объекта для использования функции
// с помощью await (асинхронно) без коллбэков (callback)
// https://learn.javascript.ru/promise
return new Promise((resolve, reject) => {
// 2. "Возвращаем" содержимое когда файл прочитан
// через вызов resolve
// Если не использовать Promise, то всю работу по взаимодействию
// с REST API пришлось бы делать в обработчике (callback) функции
// onloadend
reader.onloadend = () => {
const fileContent = reader.result;
// Здесь могла бы быть работа с REST API
// Чтение заканчивает выполняться здесь
resolve(fileContent);
};
// 3. Возвращаем ошибку
reader.onerror = () => {
// Или здесь в случае ошибки
reject(new Error("oops, something went wrong with the file reader."));
};
// Шаг 1. Сначала читаем файл
// Чтение начинает выполняться здесь
reader.readAsDataURL(file);
});
}
// функция для обновления блока с превью выбранного изображения
async function updateImagePreview() {
// получение выбранного файла
// возможен выбор нескольких файлов, поэтому необходимо получить только первый
const file = cntrls.image.files[0];
// чтение содержимого файла в виде base64 строки
const fileContent = await readFile(file);
console.info("base64 ", fileContent);
// обновление атрибута src для тега img с id image-preview
cntrls.imagePreview.src = fileContent;
}
export function linesForm() {
console.info("linesForm");
drawItemsSelect();
drawLinesTable();
// Вызов функции обновления превью изображения при возникновении
// события oncahnge в тэге input с id image
cntrls.image.addEventListener("change", () => updateImagePreview());
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
event.preventDefault();
event.stopPropagation();
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
if (cntrls.imagePreview.src !== imagePlaceholder) {
const result = await fetch(cntrls.imagePreview.src);
const blob = await result.blob();
imageBase64 = await readFile(blob);
}
const currentId = cntrls.lineId.value;
if (!currentId) {
await addLine(
cntrls.itemsType.value,
cntrls.filmname.value,
cntrls.rating.value,
cntrls.releaseDate.value,
cntrls.director.value,
imageBase64,
);
} else {
await editLine(
currentId,
cntrls.itemsType.value,
cntrls.title.value,
cntrls.rating.value,
cntrls.releaseDate.value,
cntrls.director.value,
imageBase64,
);
}
});
}
export async function linesPageForm() {
console.info("linesPageForm");
drawItemsSelect();
const goBack = () => location.assign("/admin.html");
cntrls.image.addEventListener("change", () => updateImagePreview());
const urlParams = new URLSearchParams(location.search);
const currentId = urlParams.get("id");
if (currentId) {
try {
const line = await getLine(currentId);
cntrls.itemsType.value = line.itemsId;
cntrls.filmname.value = line.name;
cntrls.rating.value = line.rating;
cntrls.releaseDate.value = line.release_date;
cntrls.director.value = line.director;
cntrls.imagePreview.src = line.image ? line.image : imagePlaceholder;
} catch {
goBack();
}
}
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
event.preventDefault();
event.stopPropagation();
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
if (cntrls.imagePreview.src !== imagePlaceholder) {
// Загрузка содержимого атрибута src тэга img с id image-preview
// Здесь выполняется HTTP запрос с типом GET
const result = await fetch(cntrls.imagePreview.src);
// Получение из HTTP-ответа бинарного содержимого
const blob = await result.blob();
// Получение base64 строки для файла
// Здесь выполняется Promise из функции readFile
// Promise позволяет писать линейный код для работы с асинхронными методами
// без использования обработчиков (callback) с помощью await
imageBase64 = await readFile(blob);
}
if (!currentId) {
await addLine(
cntrls.itemsType.value,
cntrls.filmname.value,
cntrls.rating.value,
cntrls.releaseDate.value,
cntrls.director.value,
imageBase64,
);
} else {
await editLine(
currentId,
cntrls.itemsType.value,
cntrls.filmname.value,
cntrls.rating.value,
cntrls.releaseDate.value,
cntrls.director.value,
imageBase64,
);
}
goBack();
});
}

View File

@ -1,23 +0,0 @@
const movieCards = document.querySelectorAll('.movie-card');
// Добавляем обработчик события нажатия для каждой карточки фильма
movieCards.forEach(card => {
const link = card.querySelector('.movie-link');
const kinopoiskId = card.dataset.kinopoiskId;
card.addEventListener('click', () => {
// Формируем новый URL с использованием ID Кинопоиска
const redirectUrl = `https://kinopoisk-watch-dsze5.ondigitalocean.app/player/?id=${kinopoiskId}`;
// Перенаправляем пользователя на полученный URL
window.location.href = redirectUrl;
});
});
$(document).ready(function () {
var url = window.location.href;
$('.navbar-nav a').filter(function () {
return this.href == url;
}).addClass('active');
});

View File

@ -1,16 +0,0 @@
function validation() {
const forms = document.querySelectorAll("form.needs-validation");
for (let i = 0; i < forms.length; i += 1) {
const form = forms[i];
form.addEventListener("submit", (event) => {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
});
}
}
export default validation;

View File

@ -14,6 +14,7 @@ const AdminPage = () => {
<Table className="mt-2" striped> <Table className="mt-2" striped>
<thead> <thead>
<tr>
<th scope="col"></th> <th scope="col"></th>
<th scope="col" className="w-25">Фильм</th> <th scope="col" className="w-25">Фильм</th>
<th scope="col" className="w-25">Жанр</th> <th scope="col" className="w-25">Жанр</th>
@ -22,6 +23,7 @@ const AdminPage = () => {
<th scope="col" className="w-25">Режиссер</th> <th scope="col" className="w-25">Режиссер</th>
<th scope="col"></th> <th scope="col"></th>
<th scope="col"></th> <th scope="col"></th>
</tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>
</Table> </Table>

View File

@ -22,28 +22,28 @@ const PageEdit = () => {
alt="placeholder" /> alt="placeholder" />
</div> </div>
<Form id="items-form" noValidate validated={validated} onSubmit={handleSubmit}> <Form id="items-form" noValidate validated={validated} onSubmit={handleSubmit}>
<Form.Group className="mb-3" controlId="item"> <Form.Group className="mb-3" htmlFor="item">
<Form.Label htmlFor="item" className="form-label">Жанр</Form.Label> <Form.Label htmlFor="item" className="form-label">Жанр</Form.Label>
<Form.Select name='selected' required> <Form.Select name='selected' required>
</Form.Select> </Form.Select>
</Form.Group> </Form.Group>
<Form.Group className="mb-3" controlId="name"> <Form.Group className="mb-3" htmlFor="name">
<Form.Label>Название фильма</Form.Label> <Form.Label>Название фильма</Form.Label>
<Form.Control type="text" name="name" required /> <Form.Control type="text" name="name" required />
</Form.Group> </Form.Group>
<Form.Group className="mb-3" controlId="rating"> <Form.Group className="mb-3" htmlFor="rating">
<Form.Label>Рейтинг</Form.Label> <Form.Label>Рейтинг</Form.Label>
<Form.Control type="number" name="rating" min="1" max="10" required /> <Form.Control type="number" name="rating" min="1" max="10" required />
</Form.Group> </Form.Group>
<Form.Group className="mb-3" controlId="releaseDate"> <Form.Group className="mb-3" htmlFor="releaseDate">
<Form.Label>Дата создания</Form.Label> <Form.Label>Дата создания</Form.Label>
<Form.Control type="date" name="releaseDate" required /> <Form.Control type="date" name="releaseDate" required />
</Form.Group> </Form.Group>
<Form.Group className="mb-3" controlId="director"> <Form.Group className="mb-3" htmlFor="director">
<Form.Label>Режиссер</Form.Label> <Form.Label>Режиссер</Form.Label>
<Form.Control type="text" name="director" required /> <Form.Control type="text" name="director" required />
</Form.Group> </Form.Group>
<Form.Group className="mb-3" controlId="image"> <Form.Group className="mb-3" htmlFor="image">
<Form.Label>Обложка</Form.Label> <Form.Label>Обложка</Form.Label>
<Form.Control type="file" name="image" accept="image/*" /> <Form.Control type="file" name="image" accept="image/*" />
</Form.Group> </Form.Group>