Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Разделяй и властвуй #5

Merged
merged 2 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
332 changes: 332 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
"@babel/preset-env": "7.20.2",
"babel-loader": "9.1.0",
"copy-webpack-plugin": "11.0.0",
"css-loader": "6.7.2",
"eslint": "8.28.0",
"eslint-config-htmlacademy": "8.0.0",
"html-webpack-plugin": "5.6.0",
"style-loader": "3.3.1",
"webpack": "5.75.0",
"webpack-cli": "5.0.0",
"webpack-dev-server": "4.11.1"
Expand Down
16 changes: 5 additions & 11 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import FilterView from './view/filter-view.js';
import SortView from './view/sort-view.js';
import ListPresenter from './presenter/list-presenter.js';
import {render} from './render.js';
import PointsModel from './model/points-model.js';
import DestinationsModel from './model/destinations-model.js';
import OffersModel from './model/offers-model.js';
import {render} from './framework/render.js';

const filterContainer = document.querySelector('.trip-controls__filters');
const sortAndListContainer = document.querySelector('.trip-events');
const pointsContainer = document.querySelector('.trip-events');

const pointsModel = new PointsModel();
const destinationsModel = new DestinationsModel({pointsModel});
const offersModel = new OffersModel({pointsModel});
const listPresenter = new ListPresenter({
container: sortAndListContainer,
pointsModel: pointsModel,
destinationsModel: destinationsModel,
offersModel: offersModel
container: pointsContainer,
pointsModel
});

render(new FilterView(), filterContainer);
render(new SortView(), sortAndListContainer);
render(new SortView(), pointsContainer);
listPresenter.init();
11 changes: 8 additions & 3 deletions src/mock/point.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,13 @@ function getOffersByType(type) {
return offers.find((offersByType) => offersByType.type === type).offers;
}

function getOfferById(offersByType, id) {
return offersByType.find((offer) => offer.id === id);
function getSelectedOffers(offerIds, offersByType) {
const selectedOffers = [];
for (let i = 0; i < offerIds.length; i++ ) {
selectedOffers.push(offersByType.find((offer) => offer.id === offerIds[i]));
}

return selectedOffers;
}

export {getRandomPoint, getDestinationById, getOffersByType, getOfferById};
export {getRandomPoint, getDestinationById, getOffersByType, getSelectedOffers};
13 changes: 0 additions & 13 deletions src/model/destinations-model.js

This file was deleted.

26 changes: 0 additions & 26 deletions src/model/offers-model.js

This file was deleted.

6 changes: 3 additions & 3 deletions src/model/points-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import {getRandomPoint} from '../mock/point.js';
import {POINT_COUNT} from '../const.js';

export default class PointsModel {
points = Array.from({length: POINT_COUNT}, getRandomPoint);
#points = Array.from({length: POINT_COUNT}, getRandomPoint);

getPoints() {
return this.points;
get points() {
return this.#points;
}
}
81 changes: 62 additions & 19 deletions src/presenter/list-presenter.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,73 @@
import ListView from '../view/list-view.js';
import EditPointView from '../view/edit-point-view.js';
import ListPointView from '../view/list-point-view.js';
import {render} from '../render.js';
import ListPointView from '../view/point-view.js';
import {render, replace} from '../framework/render.js';
import {getDestinationById, getOffersByType, getSelectedOffers} from '../mock/point.js';

export default class ListPresenter {
listComponent = new ListView();
#listComponent = new ListView();
#container;
#pointsModel;
#points;

constructor({container, pointsModel, destinationsModel, offersModel}) {
this.container = container;
this.pointsModel = pointsModel;
this.destinationsModel = destinationsModel;
this.offersModel = offersModel;
constructor({container, pointsModel}) {
this.#container = container;
this.#pointsModel = pointsModel;
}

init() {
this.points = [...this.pointsModel.getPoints()];
this.destinations = [...this.destinationsModel.getDestinations(this.points)];
this.selectedOffers = [...this.offersModel.getSelectedOffers(this.points)];
this.typesOffers = [...this.offersModel.getTypesOffers(this.points)];
render(this.listComponent, this.container);
render(new EditPointView({pointData: this.points[0], destinationData: this.destinations[0], offersByType: this.typesOffers[0]}),
this.listComponent.getElement());

for (let i = 1; i < this.points.length; i++) {
render(new ListPointView({pointData: this.points[i], destinationData: this.destinations[i],
selectedOffersData: this.selectedOffers[i]}), this.listComponent.getElement());
this.#points = [...this.#pointsModel.points];
render(this.#listComponent, this.#container);

for (let i = 0; i < this.#points.length; i++) {
this.#renderPoint(this.#points[i]);
}
}

#renderPoint(point) {
const escKeyDownHandler = (evt) => {
if (evt.key === 'Escape') {
evt.preventDefault();
replaceEditFormToPoint();
document.removeEventListener('keydown', escKeyDownHandler);
}
};

const offersByType = getOffersByType(point.type);
const destination = getDestinationById(point.destination);

const pointComponent = new ListPointView({
point,
destination,
selectedOffers: getSelectedOffers(point.offers, offersByType),
handleClick: () => {
replacePointToEditForm();
document.addEventListener('keydown', escKeyDownHandler);
}
});

const pointEditComponent = new EditPointView({
point,
destination,
offersByType,
handleSubmit: () => {
replaceEditFormToPoint();
document.removeEventListener('keydown', escKeyDownHandler);
},
handleClick: () => {
replaceEditFormToPoint();
document.removeEventListener('keydown', escKeyDownHandler);
}
});

function replacePointToEditForm() {
replace(pointEditComponent, pointComponent);
}

function replaceEditFormToPoint() {
replace(pointComponent, pointEditComponent);
}

render(pointComponent, this.#listComponent.element);
}
}
19 changes: 0 additions & 19 deletions src/render.js

This file was deleted.

84 changes: 48 additions & 36 deletions src/view/edit-point-view.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {createElement} from '../render.js';
import {TYPES, DESTINATIONS} from '../const.js';
import {TYPES, DESTINATIONS, DEFAULT_POINT_DATA} from '../const.js';
import AbstractView from '../framework/view/abstract-view.js';

function editPointTemplate(point, destination, typesTemplate, offersTemplate, picturesTemplate, destinationsTemplate) {
return `
Expand Down Expand Up @@ -49,6 +49,9 @@ function editPointTemplate(point, destination, typesTemplate, offersTemplate, pi

<button class="event__save-btn btn btn--blue" type="submit">Save</button>
<button class="event__reset-btn" type="reset">Cancel</button>
<button class="event__rollup-btn" type="button">
<span class="visually-hidden">Open event</span>
</button>
</header>
<section class="event__details">
<section class="event__section event__section--offers">
Expand All @@ -75,27 +78,38 @@ function editPointTemplate(point, destination, typesTemplate, offersTemplate, pi
`;
}

export default class EditPointView {
constructor({pointData, destinationData, offersByType}) {
this.pointData = pointData;
this.destinationData = destinationData;
this.offersByType = offersByType;
export default class EditPointView extends AbstractView {
#point;
#destination;
#offersByType;
#handleSubmit;
#handleClick;

constructor({point = DEFAULT_POINT_DATA, destination, offersByType, handleSubmit, handleClick}) {
super();
this.#point = point;
this.#destination = destination;
this.#offersByType = offersByType;
this.#handleSubmit = handleSubmit;
this.element.querySelector('form').addEventListener('submit', this.#submitHandler);
this.#handleClick = handleClick;
this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#clickHandler);
}

getTypesTemplate() {
get #typesTemplate() {
let typesTemplate = '';
for (let i = 0; i < TYPES.length; i++) {
const isChecked = TYPES[i] === this.pointData.type ? 'checked' : '';
const isChecked = TYPES[i] === this.#point.type ? 'checked' : '';
typesTemplate += `
<div class="event__type-item">
<input id="event-type-${TYPES[i]}-${this.pointData.id}" class="event__type-input visually-hidden" type="radio" name="event-type" value="${TYPES[i]}" ${isChecked}>
<label class="event__type-label event__type-label--${TYPES[i]}" for="event-type-${TYPES[i]}-${this.pointData.id}">${TYPES[i]}</label>
<input id="event-type-${TYPES[i]}-${this.#point.id}" class="event__type-input visually-hidden" type="radio" name="event-type" value="${TYPES[i]}" ${isChecked}>
<label class="event__type-label event__type-label--${TYPES[i]}" for="event-type-${TYPES[i]}-${this.#point.id}">${TYPES[i]}</label>
</div>`;
}
return typesTemplate;
}

getDestinationsTemplate() {
get #destinationsTemplate() {
let destinationsTemplate = '';
for (let i = 0; i < DESTINATIONS.length; i++) {
destinationsTemplate += `
Expand All @@ -104,48 +118,46 @@ export default class EditPointView {
return destinationsTemplate;
}

getOffersTemplate() {
get #offersTemplate() {
let offersTemplate = '';
for (let i = 0; i < this.offersByType.length; i++) {
const isChecked = this.offersByType[i].id in this.pointData.offers ? 'checked' : '';
const offerShortName = this.offersByType[i].name.toLowerCase().split(' ').at(-1);
for (let i = 0; i < this.#offersByType.length; i++) {
const isChecked = this.#offersByType[i].id in this.#point.offers ? 'checked' : '';
const offerShortName = this.#offersByType[i].name.toLowerCase().split(' ').at(-1);
offersTemplate += `
<div class="event__offer-selector">
<input class="event__offer-checkbox visually-hidden" id="event-offer-${offerShortName}-${this.pointData.id}" type="checkbox" name="event-offer-${offerShortName}" ${isChecked}>
<label class="event__offer-label" for="event-offer-${offerShortName}-${this.pointData.id}">
<span class="event__offer-title">${this.offersByType[i].name}</span>
<input class="event__offer-checkbox visually-hidden" id="event-offer-${offerShortName}-${this.#point.id}" type="checkbox" name="event-offer-${offerShortName}" ${isChecked}>
<label class="event__offer-label" for="event-offer-${offerShortName}-${this.#point.id}">
<span class="event__offer-title">${this.#offersByType[i].name}</span>
&plus;&euro;&nbsp;
<span class="event__offer-price">${this.offersByType[i].price}</span>
<span class="event__offer-price">${this.#offersByType[i].price}</span>
</label>
</div>`;
}
return offersTemplate;
}

getPicturesTemplate() {
get #picturesTemplate() {
let picturesTemplate = '';
for (let i = 0; i < this.destinationData.pictures.length; i++) {
const picture = this.destinationData.pictures[i];
for (let i = 0; i < this.#destination.pictures.length; i++) {
const picture = this.#destination.pictures[i];
picturesTemplate += `
<img class="event__photo" src="${picture.src}" alt="${picture.description}">`;
}
return picturesTemplate;
}

getTemplate() {
return editPointTemplate(this.pointData, this.destinationData, this.getTypesTemplate(),
this.getOffersTemplate(), this.getPicturesTemplate(), this.getDestinationsTemplate());
get template() {
return editPointTemplate(this.#point, this.#destination, this.#typesTemplate,
this.#offersTemplate, this.#picturesTemplate, this.#destinationsTemplate);
}

getElement() {
if (!this.element) {
this.element = createElement(this.getTemplate());
}

return this.element;
}
#submitHandler = (evt) => {
evt.preventDefault();
this.#handleSubmit();
};

removeElement() {
this.element = null;
}
#clickHandler = (evt) => {
evt.preventDefault();
this.#handleClick();
};
}
18 changes: 3 additions & 15 deletions src/view/filter-view.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {createElement} from '../render.js';
import AbstractView from '../framework/view/abstract-view.js';

function createFilterTemplate() {
return `
Expand Down Expand Up @@ -28,20 +28,8 @@ function createFilterTemplate() {
`;
}

export default class FilterView {
getTemplate() {
export default class FilterView extends AbstractView {
get template() {
return createFilterTemplate();
}

getElement() {
if (!this.element) {
this.element = createElement(this.getTemplate());
}

return this.element;
}

removeElement() {
this.element = null;
}
}
Loading
Loading