283 lines
11 KiB
JavaScript
283 lines
11 KiB
JavaScript
// Import Bootstrap modal functionality
|
|
import { Modal } from 'bootstrap';
|
|
|
|
export class MovieView {
|
|
constructor() {
|
|
this.movieContainer = document.getElementById('movieContainer');
|
|
|
|
// Create add movie button if we're on the catalog page
|
|
if (window.location.pathname.includes('catalog.html')) {
|
|
this.createAddMovieButton();
|
|
}
|
|
|
|
// Initialize featured movies section if we're on the homepage
|
|
if (window.location.pathname.endsWith('index.html') || window.location.pathname.endsWith('/')) {
|
|
this.initializeHomepage();
|
|
}
|
|
}
|
|
|
|
// Initialize homepage elements
|
|
initializeHomepage() {
|
|
// We'll use the same movieContainer for homepage
|
|
if (!this.movieContainer) {
|
|
console.error('Movie container element not found on homepage');
|
|
return;
|
|
}
|
|
|
|
// Add a heading for the featured movies section if not already present
|
|
const parentSection = this.movieContainer.closest('section');
|
|
if (parentSection) {
|
|
const heading = parentSection.querySelector('h2');
|
|
if (heading) {
|
|
heading.textContent = 'Популярные фильмы';
|
|
heading.className = 'text-orange mb-4';
|
|
}
|
|
}
|
|
|
|
// Add a button to add movies on the homepage too
|
|
this.createAddMovieButton();
|
|
}
|
|
|
|
// Create "Add Movie" button and append it to the page
|
|
createAddMovieButton() {
|
|
// Find the appropriate container - either .mb-5 or the section containing movieContainer
|
|
let container = document.querySelector('.mb-5');
|
|
if (!container && this.movieContainer) {
|
|
container = this.movieContainer.closest('section');
|
|
}
|
|
if (!container) return;
|
|
|
|
// Check if button already exists
|
|
if (container.querySelector('.add-movie-btn')) return;
|
|
|
|
const buttonContainer = document.createElement('div');
|
|
buttonContainer.className = 'mb-4 d-flex justify-content-end';
|
|
|
|
const addButton = document.createElement('a');
|
|
addButton.className = 'btn btn-success add-movie-btn';
|
|
addButton.href = 'add-movie.html';
|
|
addButton.innerHTML = '<i class="bi bi-plus-circle me-2"></i>Добавить фильм';
|
|
|
|
buttonContainer.appendChild(addButton);
|
|
container.insertBefore(buttonContainer, this.movieContainer);
|
|
}
|
|
|
|
// Bind the save new movie form submit event
|
|
bindSaveNewMovie(handler) {
|
|
const addMovieForm = document.getElementById('addMovieForm');
|
|
if (!addMovieForm) return;
|
|
|
|
addMovieForm.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
|
|
const newMovie = {
|
|
title: document.getElementById('movieTitle').value,
|
|
director: document.getElementById('movieDirector').value,
|
|
genres: Array.from(document.getElementById('movieGenre').selectedOptions).map(option => option.text),
|
|
year: document.getElementById('movieYear').value,
|
|
description: document.getElementById('movieDescription').value,
|
|
poster: document.getElementById('posterPreview')?.src || 'resources/movies/placeholder.jpg'
|
|
};
|
|
|
|
handler(newMovie);
|
|
|
|
// Redirect back to catalog after adding
|
|
window.location.href = 'catalog.html';
|
|
});
|
|
}
|
|
|
|
createMovieElement(movie) {
|
|
const movieCard = document.createElement('div');
|
|
movieCard.className = 'card movie-card h-100 bg-dark';
|
|
movieCard.dataset.movieId = movie.id;
|
|
|
|
movieCard.innerHTML = `
|
|
<img src="${movie.poster}" class="card-img-top" alt="${movie.title} Poster">
|
|
<div class="card-body">
|
|
<h5 class="card-title text-white">
|
|
<i class="bi bi-film text-orange me-2"></i>${movie.title}
|
|
</h5>
|
|
<p class="card-text text-white">
|
|
<i class="bi bi-person-video3 me-2"></i>Режиссер: ${movie.director}
|
|
</p>
|
|
<p class="card-text text-light">
|
|
<i class="bi bi-tags me-2"></i>Жанр: ${Array.isArray(movie.genres) ? movie.genres.join(', ') : movie.genres}
|
|
</p>
|
|
<p class="card-text text-light">
|
|
<i class="bi bi-calendar3 me-2"></i>Год выпуска: ${movie.year}
|
|
</p>
|
|
</div>
|
|
<div class="card-footer bg-transparent border-0 d-flex justify-content-between">
|
|
<a href="edit-movie.html?id=${movie.id}" class="btn btn-warning edit-movie btn-sm">
|
|
<i class="bi bi-pencil"></i> Редактировать
|
|
</a>
|
|
<button class="btn btn-danger delete-movie btn-sm">
|
|
<i class="bi bi-trash"></i> Удалить
|
|
</button>
|
|
</div>
|
|
`;
|
|
|
|
return movieCard;
|
|
}
|
|
|
|
renderMovies(movies) {
|
|
// Make sure movies is an array before using forEach
|
|
if (!Array.isArray(movies)) {
|
|
console.error('Expected movies to be an array but got:', movies);
|
|
movies = [];
|
|
}
|
|
|
|
// Use movieContainer property instead of looking for 'movies-container'
|
|
if (!this.movieContainer) {
|
|
console.error('Movie container element not found. Make sure an element with id "movieContainer" exists in your HTML.');
|
|
return;
|
|
}
|
|
|
|
this.movieContainer.innerHTML = '';
|
|
|
|
// If we're on the homepage, only show up to 6 featured movies
|
|
const isHomepage = window.location.pathname.endsWith('index.html') || window.location.pathname.endsWith('/');
|
|
const moviesToShow = isHomepage ? movies.slice(0, 6) : movies;
|
|
|
|
moviesToShow.forEach(movie => {
|
|
const movieCard = this.createMovieElement(movie);
|
|
this.movieContainer.appendChild(movieCard);
|
|
});
|
|
|
|
// If we're on the homepage and there are more movies, add a "See All" button
|
|
if (isHomepage && movies.length > 6) {
|
|
const seeAllContainer = document.createElement('div');
|
|
seeAllContainer.className = 'col-12 text-center mt-4';
|
|
|
|
const seeAllButton = document.createElement('a');
|
|
seeAllButton.href = 'catalog.html';
|
|
seeAllButton.className = 'btn btn-primary';
|
|
seeAllButton.textContent = 'Смотреть все фильмы';
|
|
|
|
seeAllContainer.appendChild(seeAllButton);
|
|
this.movieContainer.parentNode.appendChild(seeAllContainer);
|
|
}
|
|
}
|
|
|
|
fillEditModal(movie) {
|
|
if (!this.editModal) return;
|
|
|
|
const titleInput = this.editModal.querySelector('#editMovieTitle');
|
|
const directorInput = this.editModal.querySelector('#editMovieDirector');
|
|
const genreSelect = this.editModal.querySelector('#editMovieGenre');
|
|
const yearInput = this.editModal.querySelector('#editMovieYear');
|
|
const descriptionInput = this.editModal.querySelector('#editMovieDescription');
|
|
const posterPreview = this.editModal.querySelector('#editPosterPreview');
|
|
|
|
titleInput.value = movie.title;
|
|
directorInput.value = movie.director;
|
|
|
|
// Handle genres (multi-select)
|
|
if (Array.isArray(movie.genres)) {
|
|
Array.from(genreSelect.options).forEach(option => {
|
|
option.selected = movie.genres.includes(option.text);
|
|
});
|
|
}
|
|
|
|
yearInput.value = movie.year;
|
|
descriptionInput.value = movie.description || '';
|
|
|
|
if (movie.poster) {
|
|
posterPreview.src = movie.poster;
|
|
this.editModal.querySelector('.preview-container').classList.remove('d-none');
|
|
}
|
|
|
|
this.editModal.dataset.movieId = movie.id;
|
|
}
|
|
|
|
bindDeleteMovie(handler) {
|
|
if (!this.movieContainer) return;
|
|
|
|
// Use event delegation to handle delete button clicks
|
|
// This works on any page that has the movieContainer
|
|
this.movieContainer.addEventListener('click', (e) => {
|
|
if (e.target.closest('.delete-movie')) {
|
|
const movieCard = e.target.closest('.movie-card');
|
|
const movieId = movieCard.dataset.movieId;
|
|
if (confirm('Вы уверены, что хотите удалить этот фильм?')) {
|
|
handler(movieId);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
bindEditMovie(handler) {
|
|
if (!this.movieContainer) return;
|
|
|
|
this.movieContainer.addEventListener('click', (e) => {
|
|
if (e.target.closest('.edit-movie')) {
|
|
const movieCard = e.target.closest('.movie-card');
|
|
const movieId = movieCard.dataset.movieId;
|
|
handler(movieId);
|
|
}
|
|
});
|
|
}
|
|
|
|
bindSaveEditedMovie(handler) {
|
|
if (!this.editModal) return;
|
|
|
|
const form = this.editModal.querySelector('form');
|
|
form.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
|
|
const movieId = this.editModal.dataset.movieId;
|
|
const updatedMovie = {
|
|
title: form.querySelector('#editMovieTitle').value,
|
|
director: form.querySelector('#editMovieDirector').value,
|
|
genres: Array.from(form.querySelector('#editMovieGenre').selectedOptions).map(option => option.text),
|
|
year: form.querySelector('#editMovieYear').value,
|
|
description: form.querySelector('#editMovieDescription').value,
|
|
poster: form.querySelector('#editPosterPreview').src
|
|
};
|
|
|
|
handler(movieId, updatedMovie);
|
|
|
|
// Close modal using Bootstrap
|
|
bootstrap.Modal.getInstance(this.editModal).hide();
|
|
});
|
|
}
|
|
|
|
bindFilterMovies(handler) {
|
|
const genreSelect = document.getElementById('genre-select');
|
|
const yearSelect = document.getElementById('year-select');
|
|
const searchInput = document.getElementById('search-input');
|
|
|
|
if (genreSelect) {
|
|
genreSelect.addEventListener('change', () => {
|
|
const filters = {
|
|
genre: genreSelect.value,
|
|
year: yearSelect ? yearSelect.value : 'all',
|
|
search: searchInput ? searchInput.value : ''
|
|
};
|
|
handler(filters);
|
|
});
|
|
}
|
|
|
|
if (yearSelect) {
|
|
yearSelect.addEventListener('change', () => {
|
|
const filters = {
|
|
genre: genreSelect ? genreSelect.value : 'all',
|
|
year: yearSelect.value,
|
|
search: searchInput ? searchInput.value : ''
|
|
};
|
|
handler(filters);
|
|
});
|
|
}
|
|
|
|
if (searchInput) {
|
|
searchInput.addEventListener('input', () => {
|
|
const filters = {
|
|
genre: genreSelect ? genreSelect.value : 'all',
|
|
year: yearSelect ? yearSelect.value : 'all',
|
|
search: searchInput.value
|
|
};
|
|
handler(filters);
|
|
});
|
|
}
|
|
}
|
|
} |