Skip to content

Commit

Permalink
Merge pull request #5 from vvvyat/module4-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Jun 10, 2024
2 parents 865cce7 + d73ac35 commit 7e4f41e
Show file tree
Hide file tree
Showing 15 changed files with 506 additions and 206 deletions.
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

0 comments on commit 7e4f41e

Please sign in to comment.