Skip to content

Commit

Permalink
Merge pull request #7 from reking06/module5-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Sep 26, 2024
2 parents 554f252 + 232ebaa commit 587b92f
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 112 deletions.
5 changes: 5 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,8 @@ export const FilterMessage = {
[FilterType.PRESENT]: 'There are no present events now',
[FilterType.PAST]: 'There are no past events now'
};

export const Mode = {
DEFAULT: 'DEFAULT',
EDITING: 'EDITING',
};
4 changes: 2 additions & 2 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Presenter from './presenter/presenter.js';
import MainPresenter from './presenter/main-presenter.js';
import PointModel from './model/point-model.js';

const tripMainElement = document.querySelector('.trip-main');
Expand All @@ -8,7 +8,7 @@ const filtersElement = document.querySelector('.trip-controls__filters');
const pointModel = new PointModel();
pointModel.init();

const presenter = new Presenter({
const presenter = new MainPresenter({
infoContainer: tripMainElement,
contentContainer: tripEventsElement,
filtersContainer: filtersElement,
Expand Down
80 changes: 80 additions & 0 deletions src/presenter/main-presenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import TripInfoView from '../view/trip-info-view.js';
import EventsListView from '../view/events-list-view.js';
import FiltersView from '../view/filters-view.js';
import SortView from '../view/sort-view.js';
import EventAddButtonView from '../view/event-add-button-view.js';
import EventsMessageView from '../view/events-message-view.js';
import PointPresenter from './point-presenter.js';
import { render, RenderPosition } from '../framework/render.js';
import { EVENTS_MESSAGE } from '../constants.js';
import { generateFilter } from '../mocks/filters.js';
import { updateItem } from '../util/utils.js';

export default class MainPresenter {
#tripInfoComponent = new TripInfoView();
#addButtonComponent = new EventAddButtonView();
#sortComponent = new SortView();
#listComponent = new EventsListView();
#pointModel = null;
#pointPresenters = new Map();

#points = [];
#offers = [];
#destinations = [];

constructor({infoContainer, contentContainer, filtersContainer, pointModel}) {
this.infoContainer = infoContainer;
this.contentContainer = contentContainer;
this.filtersContainer = filtersContainer;
this.#pointModel = pointModel;
}

init() {
this.#points = this.#pointModel.points;
this.#destinations = this.#pointModel.destinations;
this.#offers = this.#pointModel.offers;
const filters = generateFilter(this.#points);

render(this.#tripInfoComponent, this.infoContainer, RenderPosition.AFTERBEGIN);
render(new FiltersView({filters}), this.filtersContainer);
render(this.#addButtonComponent, this.infoContainer);

this.#renderWithoutContent(this.#points);
this.#renderContent(this.#points, this.#offers, this.#destinations);
}

#renderWithoutContent = (points) => {
if (points.length === 0) {
render(new EventsMessageView(EVENTS_MESSAGE.EMPTY), this.contentContainer);
}
};

#renderContent = (points, offers, destinations) => {
render(this.#sortComponent, this.contentContainer);
render(this.#listComponent, this.contentContainer);
this.#renderPoints(points, offers, destinations);
};

#renderPoints = (points, offers, destinations) => {
points.forEach((point) => this.#renderPoint(point, offers, destinations));
};

#renderPoint = (point, offers, destinations) => {
const listComponent = this.#listComponent.element;
const onDataChange = this.#handlePointChange;
const onModeChange = this.#handleModeChange;
const pointPresenter = new PointPresenter({ listComponent, onDataChange, onModeChange });

pointPresenter.init(point, offers, destinations);
this.#pointPresenters.set(point.id, pointPresenter);
};

#handlePointChange = (updatedPoint) => {
this.#points = updateItem(this.#points, updatedPoint);
this.#pointPresenters.get(updatedPoint.id).init(updatedPoint, this.#offers, this.#destinations);
};

#handleModeChange = () => {
this.#pointPresenters.forEach((presenter) => presenter.resetView());
};
}
115 changes: 115 additions & 0 deletions src/presenter/point-presenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { render, replace, remove } from '../framework/render.js';
import { Mode } from '../constants.js';

import EventEditorView from '../view/event-editor-view.js';
import EventsItemView from '../view/events-item-view.js';

export default class PointPresenter {
#listComponent = null;
#eventComponent = null;
#eventEditorComponent = null;

#point = [];
#offers = [];
#destinations = [];

#handleDataChange = null;
#handleModeChange = null;

#mode = Mode.DEFAULT;

constructor({listComponent, onDataChange, onModeChange}) {
this.#listComponent = listComponent;
this.#handleDataChange = onDataChange;
this.#handleModeChange = onModeChange;
}

init(point, offers, destinations) {
this.#point = point;
this.#offers = offers;
this.#destinations = destinations;

const prevEventComponent = this.#eventComponent;
const prevEventEditorComponent = this.#eventEditorComponent;

this.#eventComponent = new EventsItemView({
point: this.#point,
offers: this.#offers,
destinations: this.#destinations,
onEditClick: this.#handleOpenClick,
onFavoriteClick: this.#handleFavoriteClick
});

this.#eventEditorComponent = new EventEditorView({
point: this.#point,
offers: this.#offers,
destinations: this.#destinations,
onEditClick: this.#handleCloseClick,
onFormSubmit: this.#handleFormSubmit
});

if (prevEventComponent === null || prevEventEditorComponent === null) {
render(this.#eventComponent, this.#listComponent);
return;
}

if (this.#mode === Mode.DEFAULT) {
replace(this.#eventComponent, prevEventComponent);
}

if (this.#mode === Mode.EDITING) {
replace(this.#eventEditorComponent, prevEventEditorComponent);
}

remove(prevEventComponent);
remove(prevEventEditorComponent);
}

destroy() {
remove(this.#eventComponent);
remove(this.#eventEditorComponent);
}

resetView() {
if (this.#mode !== Mode.DEFAULT) {
this.#replaceFormToPoint();
}
}

#replacePointToForm = () => {
replace(this.#eventEditorComponent, this.#eventComponent);
document.addEventListener('keydown', this.#escKeyDownHandler);
this.#handleModeChange();
this.#mode = Mode.EDITING;
};

#replaceFormToPoint = () => {
replace(this.#eventComponent, this.#eventEditorComponent);
document.removeEventListener('keydown', this.#escKeyDownHandler);
this.#mode = Mode.DEFAULT;
};

#escKeyDownHandler = (event) => {
if (event.key === 'Escape') {
event.preventDefault();
this.#replaceFormToPoint();
}
};

#handleOpenClick = () => {
this.#replacePointToForm();
};

#handleCloseClick = () => {
this.#replaceFormToPoint();
};

#handleFormSubmit = (point) => {
this.#handleDataChange(point);
this.#replaceFormToPoint();
};

#handleFavoriteClick = () => {
this.#handleDataChange({...this.#point, isFavorite: !this.#point.isFavorite});
};
}
89 changes: 0 additions & 89 deletions src/presenter/presenter.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ export const isDatePast = (end) => dayjs().isAfter(end);

export const getCapitalized = (word) => `${word[0].toUpperCase()}${word.slice(1)}`;


export const updateItem = (items, update) => items.map((item) => item.id === update.id ? update : item);
7 changes: 2 additions & 5 deletions src/view/event-add-button-view.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import AbstractView from '../framework/view/abstract-view.js';

function createEventAddButtonTemplate() {
return `
<button class="trip-main__event-add-btn btn btn--big btn--yellow" type="button">New event</button>
`;
}
const createEventAddButtonTemplate = () => `
<button class="trip-main__event-add-btn btn btn--big btn--yellow" type="button">New event</button>`;

export default class EventAddButtonView extends AbstractView {
get template() {
Expand Down
19 changes: 10 additions & 9 deletions src/view/event-editor-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const createEventDetailsTemplate = (defaultOffers, selectedOffers, description,
</section>`;
};

const createEventEditorTemplate = (point, destinations, offers)=> {
const createEventEditorTemplate = (point, offers, destinations)=> {
const eventDestination = destinations.find((item) => item.id === point.destination);
const defaultOffers = offers.find((offer) => offer.type === point.type).offers;
const selectedOffers = defaultOffers.filter((defaultOffer) => point.offers.includes(defaultOffer.id));
Expand Down Expand Up @@ -137,31 +137,32 @@ const createEventEditorTemplate = (point, destinations, offers)=> {
};

export default class EventEditorView extends AbstractView {
#point = null;
#destinations = null;
#offers = null;
#point = [];
#destinations = [];
#offers = [];

#handleFormSubmit = null;
#handleEditClick = null;

constructor({point, destinations, offers, onFormSubmit, onEditClick}) {
constructor({ point, offers, destinations, onEditClick, onFormSubmit }) {
super();
this.#point = point;
this.#destinations = destinations;
this.#offers = offers;
this.#handleFormSubmit = onFormSubmit;
this.#destinations = destinations;
this.#handleEditClick = onEditClick;
this.#handleFormSubmit = onFormSubmit;

this.element.querySelector('form').addEventListener('submit', this.#formSubmitHandler);
this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#editClickHandler);
}

get template() {
return createEventEditorTemplate(this.#point, this.#destinations, this.#offers);
return createEventEditorTemplate(this.#point, this.#offers, this.#destinations);
}

#formSubmitHandler = (event) => {
event.preventDefault();
this.#handleFormSubmit();
this.#handleFormSubmit(this.#point);
};

#editClickHandler = (event) => {
Expand Down
Loading

0 comments on commit 587b92f

Please sign in to comment.