Repository: htmlacademy-ecmascript/1048521-big-trip-2
Pull request #5: Разделяй и властвуй
Author: login: ElviraKiamova
Created: 2025-03-10T13:34:27Z | Merged: 2025-03-11T11:23:37Z



---
:mortar_board: [Разделяй и властвуй](https://up.htmlacademy.ru/ecmascript-individual/2/user/1048521/tasks/8)


Diff:
diff --git a/src/main.js b/src/main.js
index a63dd41..2fbe8f9 100644
--- a/src/main.js
+++ b/src/main.js
@@ -3,7 +3,7 @@ import TripFormFiltersView from './view/trip-form-filters-view.js.js';
 import TripFormSortView from './view/trip-form-sort-view.js';
 import HeaderPresenter from './presenter/header-presenter.js';
 import ListPresenter from './presenter/list-presenter.js';
-import {render, RenderPosition} from './render.js';
+import {render, RenderPosition} from './framework/render.js';
 import PointModel from './model/model.js';
 
 
diff --git a/src/model/model.js b/src/model/model.js
index 2364c5f..b4084db 100644
--- a/src/model/model.js
+++ b/src/model/model.js
@@ -32,12 +32,12 @@ const MOCK_POINTS = Array.from({length: mockPoints.length}, getRandomPoints);
 const mergedData = mergeDataArrays(MOCK_POINTS, mockOffers, mockDestinations);
 
 export default class PointModel {
-  tasks = null;
+  #tasks = null;
   constructor() {
-    this.tasks = mergedData;
+    this.#tasks = mergedData;
   }
 
   getTasks() {
-    return this.tasks;
+    return this.#tasks;
   }
 }
diff --git a/src/presenter/header-presenter.js b/src/presenter/header-presenter.js
index 2120bd1..d65b4fe 100644
--- a/src/presenter/header-presenter.js
+++ b/src/presenter/header-presenter.js
@@ -1,14 +1,15 @@
 import TripInfoView from '../view/trip-info-view.js';
-import {render, RenderPosition} from '../render.js';
+import {render, RenderPosition} from '../framework/render.js';
 
 export default class ListPresenter {
-  tripInfoComponent = new TripInfoView;
+  #boardContainer = null;
+  #tripInfoComponent = new TripInfoView;
 
   constructor({boardContainer}) {
-    this.boardContainer = boardContainer;
+    this.#boardContainer = boardContainer;
   }
 
   init() {
-    render(this.tripInfoComponent, this.boardContainer, RenderPosition.AFTERBEGIN);
+    render(this.#tripInfoComponent, this.#boardContainer, RenderPosition.AFTERBEGIN);
   }
 }
diff --git a/src/presenter/list-presenter.js b/src/presenter/list-presenter.js
index 4d5273d..29e6d89 100644
--- a/src/presenter/list-presenter.js
+++ b/src/presenter/list-presenter.js
@@ -1,22 +1,68 @@
 import TripEventsListView from '../view/trip-events-list-view.js';
 import RoutPointView from '../view/route-point-view.js';
-import {render} from '../render.js';
+import {render, replace} from '../framework/render.js';
+import RoutPointEditView from '../view/route-point-edit-view.js';
+import RoutPointBoxView from '../view/route-point-box-view.js';
 
 export default class ListPresenter {
-  listComponent = new TripEventsListView;
+  #tasksModel = null;
+  #boardContainer = null;
+  #listComponent = new TripEventsListView;
+  #boardTasks = [];
 
   constructor({boardContainer, tasksModel}) {
-    this.boardContainer = boardContainer;
-    this.tasksModel = tasksModel;
+    this.#boardContainer = boardContainer;
+    this.#tasksModel = tasksModel;
   }
 
   init() {
-    this.boardTasks = [...this.tasksModel.getTasks()];
+    this.#boardTasks = [...this.#tasksModel.getTasks()];
+    render(this.#listComponent, this.#boardContainer);
+    for (let i = 0; i < this.#boardTasks.length; i++) {
+      this.#renderTask(this.#boardTasks[i]);
+    }
+  }
+
+  #renderTask(task) {
+    const escKeyDownHandler = (evt) => {
+      if (evt.key === 'Escape') {
+        evt.preventDefault();
+        replaceFormToCard();
+        document.removeEventListener('keydown', escKeyDownHandler);
+      }
+    };
+
+    const taskEditComponent = new RoutPointEditView({
+      task,
+      onFormSubmit: () => {
+        replaceFormToCard();
+        document.addEventListener('keydown', escKeyDownHandler);
+      }
+    });
 
-    render(this.listComponent, this.boardContainer);
+    const taskBoxComponent = new RoutPointBoxView({
+      task,
+      onEditClick: () => {
+        replaceCardToForm();
+        document.addEventListener('keydown', escKeyDownHandler);
+      }
+    });
+
+    const taskComponent = new RoutPointView({
+      task,
+      taskEditComponent,
+      taskBoxComponent,
+    });
+
+    render(taskComponent, this.#listComponent.element);
+    render(taskBoxComponent, taskComponent.element);
+
+    function replaceCardToForm() {
+      replace(taskEditComponent, taskBoxComponent);
+    }
 
-    for (let i = 0; i < this.boardTasks.length; i++) {
-      render(new RoutPointView({task: this.boardTasks[i]}), this.listComponent.getElement());
+    function replaceFormToCard() {
+      replace(taskBoxComponent, taskEditComponent);
     }
   }
 }
diff --git a/src/render.js b/src/render.js
deleted file mode 100644
index 8c22c92..0000000
--- a/src/render.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const RenderPosition = {
-  BEFOREBEGIN: 'beforebegin',
-  AFTERBEGIN: 'afterbegin',
-  BEFOREEND: 'beforeend',
-  AFTEREND: 'afterend',
-};
-
-function createElement(template) {
-  const newElement = document.createElement('div');
-  newElement.innerHTML = template;
-
-  return newElement.firstElementChild;
-}
-
-function render(component, container, place = RenderPosition.BEFOREEND) {
-  container.insertAdjacentElement(place, component.getElement());
-}
-
-export {RenderPosition, createElement, render};
diff --git a/src/view/new-event-button-view.js b/src/view/new-event-button-view.js
index bdf6317..541326f 100644
--- a/src/view/new-event-button-view.js
+++ b/src/view/new-event-button-view.js
@@ -1,23 +1,11 @@
-import {createElement} from '../render.js';
+import AbstractView from '../framework/view/abstract-view.js';
 
 function createNewEventButtonTemplate() {
   return '<button class="trip-main__event-add-btn  btn  btn--big  btn--yellow" type="button">New event</button>';
 }
 
-export default class NewEventButtonView {
-  getTemplate() {
+export default class NewEventButtonView extends AbstractView {
+  get template() {
     return createNewEventButtonTemplate();
   }
-
-  getElement() {
-    if (!this.element) {
-      this.element = createElement(this.getTemplate());
-    }
-
-    return this.element;
-  }
-
-  removeElement() {
-    this.element = null;
-  }
 }
diff --git a/src/view/route-point-box-view.js b/src/view/route-point-box-view.js
new file mode 100644
index 0000000..f539b69
--- /dev/null
+++ b/src/view/route-point-box-view.js
@@ -0,0 +1,77 @@
+import AbstractView from '../framework/view/abstract-view.js';
+import {humanizeTaskDueDate, showTripDuration, calculateTripDuration, showFullDate, showFullDateTime} from '../utils.js';
+
+function createAddServices(offers) {
+  return offers.map((offer) =>
+    `<li class="event__offer">
+      <span class="event__offer-title">${offer.title}</span>
+      &plus;&euro;&nbsp;
+      <span class="event__offer-price">${offer.price}</span>
+    </li>`
+  ).join('');
+}
+
+function createRoutPointBoxTemplate(task) {
+  const {destinationDetails, type, offers, startDate, endDate, basePrice} = task;
+  return `<div class="event">
+            <time class="event__date" datetime="${showFullDate(startDate)}">${humanizeTaskDueDate(startDate)}</time>
+            <div class="event__type">
+              <img class="event__type-icon" width="42" height="42" src="img/icons/${type}.png" alt="Event type icon">
+            </div>
+            <h3 class="event__title">${type} ${destinationDetails.name}</h3>
+            <div class="event__schedule">
+              <p class="event__time">
+                <time class="event__start-time" datetime="${showFullDateTime(startDate)}">${showTripDuration(startDate)}</time>
+                &mdash;
+                <time class="event__end-time" datetime="${showFullDateTime(endDate)}">${showTripDuration(endDate)}</time>
+              </p>
+              <p class="event__duration">${calculateTripDuration(startDate, endDate)}</p>
+            </div>
+            <p class="event__price">
+              &euro;&nbsp;<span class="event__price-value">${basePrice}</span>
+            </p>
+            <h4 class="visually-hidden">Offers:</h4>
+            <ul class="event__selected-offers">
+              ${createAddServices(offers)}
+            </ul>
+            <button class="event__favorite-btn  event__favorite-btn--active" type="button">
+              <span class="visually-hidden">Add to favorite</span>
+              <svg class="event__favorite-icon" width="28" height="28" viewBox="0 0 28 28">
+                <path d="M14 21l-8.22899 4.3262 1.57159-9.1631L.685209 9.67376 9.8855 8.33688 14 0l4.1145 8.33688 9.2003 1.33688-6.6574 6.48934 1.5716 9.1631L14 21z"/>
+              </svg>
+            </button>
+            <button class="event__rollup-btn" type="button">
+              <span class="visually-hidden">Open event</span>
+            </button>
+          </div>`;
+}
+
+export default class RoutPointBoxView extends AbstractView {
+  #task = null;
+  #handleEditClick = null;
+  #element = null;
+
+  constructor({task, onEditClick}) {
+    super();
+    this.#task = task;
+    this.#handleEditClick = onEditClick;
+  }
+
+  get template() {
+    return createRoutPointBoxTemplate(this.#task);
+  }
+
+  get element() {
+    if (!this.#element) {
+      this.#element = super.element;
+      const eventRollupButtonElement = this.#element.querySelector('.event__rollup-btn');
+      eventRollupButtonElement.addEventListener('click', this.#editClickHandler);
+    }
+    return this.#element;
+  }
+
+  #editClickHandler = (evt) => {
+    evt.preventDefault();
+    this.#handleEditClick();
+  };
+}
diff --git a/src/view/route-point-edit-view.js b/src/view/route-point-edit-view.js
new file mode 100644
index 0000000..ebd47b3
--- /dev/null
+++ b/src/view/route-point-edit-view.js
@@ -0,0 +1,154 @@
+import AbstractView from '../framework/view/abstract-view.js';
+import {showNewPointDate} from '../utils.js';
+
+function createAddNewPointWithout(type, offers, startDate, endDate, basePrice) {
+  return `<form class="event event--edit" action="#" method="post">
+            <header class="event__header">
+              <div class="event__type-wrapper">
+                <label class="event__type  event__type-btn" for="event-type-toggle-1">
+                  <span class="visually-hidden">Choose event type</span>
+                  <img class="event__type-icon" width="17" height="17" src="img/icons/${type}.png" alt="Event type icon">
+                </label>
+                <input class="event__type-toggle  visually-hidden" id="event-type-toggle-1" type="checkbox">
+
+                <div class="event__type-list">
+                  <fieldset class="event__type-group">
+                    <legend class="visually-hidden">Event type</legend>
+
+                    <div class="event__type-item">
+                      <input id="event-type-taxi-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="taxi">
+                      <label class="event__type-label  event__type-label--taxi" for="event-type-taxi-1">Taxi</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-bus-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="bus">
+                      <label class="event__type-label  event__type-label--bus" for="event-type-bus-1">Bus</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-train-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="train">
+                      <label class="event__type-label  event__type-label--train" for="event-type-train-1">Train</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-ship-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="ship">
+                      <label class="event__type-label  event__type-label--ship" for="event-type-ship-1">Ship</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-drive-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="drive">
+                      <label class="event__type-label  event__type-label--drive" for="event-type-drive-1">Drive</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-flight-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="flight" checked>
+                      <label class="event__type-label  event__type-label--flight" for="event-type-flight-1">Flight</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-check-in-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="check-in">
+                      <label class="event__type-label  event__type-label--check-in" for="event-type-check-in-1">Check-in</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-sightseeing-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="sightseeing">
+                      <label class="event__type-label  event__type-label--sightseeing" for="event-type-sightseeing-1">Sightseeing</label>
+                    </div>
+
+                    <div class="event__type-item">
+                      <input id="event-type-restaurant-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="restaurant">
+                      <label class="event__type-label  event__type-label--restaurant" for="event-type-restaurant-1">Restaurant</label>
+                    </div>
+                  </fieldset>
+                </div>
+              </div>
+
+              <div class="event__field-group  event__field-group--destination">
+                <label class="event__label  event__type-output" for="event-destination-1">
+                  ${type}
+                </label>
+                <input class="event__input  event__input--destination" id="event-destination-1" type="text" name="event-destination" value="" list="destination-list-1">
+                <datalist id="destination-list-1">
+                  <option value="Amsterdam"></option>
+                  <option value="Geneva"></option>
+                  <option value="Chamonix"></option>
+                </datalist>
+              </div>
+
+              <div class="event__field-group  event__field-group--time">
+                <label class="visually-hidden" for="event-start-time-1">From</label>
+                <input class="event__input  event__input--time" id="event-start-time-1" type="text" name="event-start-time" value="${showNewPointDate(startDate)}">
+                &mdash;
+                <label class="visually-hidden" for="event-end-time-1">To</label>
+                <input class="event__input  event__input--time" id="event-end-time-1" type="text" name="event-end-time" value="${showNewPointDate(endDate)}">
+              </div>
+
+              <div class="event__field-group  event__field-group--price">
+                <label class="event__label" for="event-price-1">
+                  <span class="visually-hidden">Price</span>
+                  &euro; ${basePrice}
+                </label>
+                <input class="event__input  event__input--price" id="event-price-1" type="text" name="event-price" value="">
+              </div>
+
+              <button class="event__save-btn  btn  btn--blue" type="submit">Save</button>
+              <button class="event__reset-btn" type="reset">Cancel</button>
+            </header>
+            <section class="event__details">
+
+
+              <section class="event__section  event__section--offers">
+                <h3 class="event__section-title  event__section-title--offers">Offers</h3>
+                <div class="event__available-offers">
+                  ${createButtonAddServices(offers)}
+                  </div>
+                </div>
+              </section>
+            </section>
+          </form>`;
+}
+
+function createButtonAddServices(offers) {
+  return offers.map((offer) =>
+    `<div class="event__offer-selector">
+      <input class="event__offer-checkbox  visually-hidden" id="event-offer-comfort-${offer.id}" type="checkbox" name="event-offer-comfort" checked>
+      <label class="event__offer-label" for="event-offer-comfort-${offer.id}">
+        <span class="event__offer-title">${offer.title}</span>
+        &plus;&euro;&nbsp;
+        <span class="event__offer-price">${offer.price}</span>
+      </label>
+    </div>`
+  ).join('');
+}
+
+export default class RoutPointEditView extends AbstractView {
+  #task = null;
+  #handleFormSubmit = null;
+  #element = null;
+
+  constructor({task, onFormSubmit}) {
+    super();
+    this.#task = task;
+    this.#handleFormSubmit = onFormSubmit;
+  }
+
+  get template() {
+    const { type, offers, startDate, endDate, basePrice } = this.#task;
+    return createAddNewPointWithout(type, offers, startDate, endDate, basePrice);
+  }
+
+  get element() {
+    if (!this.#element) {
+      this.#element = super.element;
+      this.#element.addEventListener('submit', this.#formSubmitHandler);
+      const closeElement = this.#element.querySelector('.event__reset-btn');
+      closeElement.addEventListener('click', this.#formSubmitHandler);
+    }
+    return this.#element;
+  }
+
+  #formSubmitHandler = (evt) => {
+    evt.preventDefault();
+    this.#handleFormSubmit();
+  };
+}
diff --git a/src/view/route-point-view.js b/src/view/route-point-view.js
index f58f98f..0825d6b 100644
--- a/src/view/route-point-view.js
+++ b/src/view/route-point-view.js
@@ -1,205 +1,30 @@
-import {createElement} from '../render.js';
-import {humanizeTaskDueDate, showTripDuration, calculateTripDuration, showFullDate, showFullDateTime, showNewPointDate, getRandomArrayElement} from '../utils.js';
+import AbstractView from '../framework/view/abstract-view.js';
 
-function createAddNewPointWithout(type, offers, startDate, endDate, basePrice) {
-  return `<form class="event event--edit hidden" action="#" method="post">
-            <header class="event__header">
-              <div class="event__type-wrapper">
-                <label class="event__type  event__type-btn" for="event-type-toggle-1">
-                  <span class="visually-hidden">Choose event type</span>
-                  <img class="event__type-icon" width="17" height="17" src="img/icons/${type}.png" alt="Event type icon">
-                </label>
-                <input class="event__type-toggle  visually-hidden" id="event-type-toggle-1" type="checkbox">
 
-                <div class="event__type-list">
-                  <fieldset class="event__type-group">
-                    <legend class="visually-hidden">Event type</legend>
-
-                    <div class="event__type-item">
-                      <input id="event-type-taxi-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="taxi">
-                      <label class="event__type-label  event__type-label--taxi" for="event-type-taxi-1">Taxi</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-bus-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="bus">
-                      <label class="event__type-label  event__type-label--bus" for="event-type-bus-1">Bus</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-train-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="train">
-                      <label class="event__type-label  event__type-label--train" for="event-type-train-1">Train</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-ship-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="ship">
-                      <label class="event__type-label  event__type-label--ship" for="event-type-ship-1">Ship</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-drive-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="drive">
-                      <label class="event__type-label  event__type-label--drive" for="event-type-drive-1">Drive</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-flight-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="flight" checked>
-                      <label class="event__type-label  event__type-label--flight" for="event-type-flight-1">Flight</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-check-in-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="check-in">
-                      <label class="event__type-label  event__type-label--check-in" for="event-type-check-in-1">Check-in</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-sightseeing-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="sightseeing">
-                      <label class="event__type-label  event__type-label--sightseeing" for="event-type-sightseeing-1">Sightseeing</label>
-                    </div>
-
-                    <div class="event__type-item">
-                      <input id="event-type-restaurant-1" class="event__type-input  visually-hidden" type="radio" name="event-type" value="restaurant">
-                      <label class="event__type-label  event__type-label--restaurant" for="event-type-restaurant-1">Restaurant</label>
-                    </div>
-                  </fieldset>
-                </div>
-              </div>
-
-              <div class="event__field-group  event__field-group--destination">
-                <label class="event__label  event__type-output" for="event-destination-1">
-                  ${type}
-                </label>
-                <input class="event__input  event__input--destination" id="event-destination-1" type="text" name="event-destination" value="" list="destination-list-1">
-                <datalist id="destination-list-1">
-                  <option value="Amsterdam"></option>
-                  <option value="Geneva"></option>
-                  <option value="Chamonix"></option>
-                </datalist>
-              </div>
-
-              <div class="event__field-group  event__field-group--time">
-                <label class="visually-hidden" for="event-start-time-1">From</label>
-                <input class="event__input  event__input--time" id="event-start-time-1" type="text" name="event-start-time" value="${showNewPointDate(startDate)}">
-                &mdash;
-                <label class="visually-hidden" for="event-end-time-1">To</label>
-                <input class="event__input  event__input--time" id="event-end-time-1" type="text" name="event-end-time" value="${showNewPointDate(endDate)}">
-              </div>
-
-              <div class="event__field-group  event__field-group--price">
-                <label class="event__label" for="event-price-1">
-                  <span class="visually-hidden">Price</span>
-                  &euro; ${basePrice}
-                </label>
-                <input class="event__input  event__input--price" id="event-price-1" type="text" name="event-price" value="">
-              </div>
-
-              <button class="event__save-btn  btn  btn--blue" type="submit">Save</button>
-              <button class="event__reset-btn" type="reset">Cancel</button>
-            </header>
-            <section class="event__details">
-
-
-              <section class="event__section  event__section--offers">
-                <h3 class="event__section-title  event__section-title--offers">Offers</h3>
-                <div class="event__available-offers">
-                  ${createButtonAddServices(offers)}
-                  </div>
-                </div>
-              </section>
-
-
-            </section>
-          </form>`;
-}
-
-function createButtonAddServices(offers) {
-  return offers.map((offer) =>
-    `<div class="event__offer-selector">
-      <input class="event__offer-checkbox  visually-hidden" id="event-offer-comfort-${offer.id}" type="checkbox" name="event-offer-comfort" checked>
-      <label class="event__offer-label" for="event-offer-comfort-${offer.id}">
-        <span class="event__offer-title">${offer.title}</span>
-        &plus;&euro;&nbsp;
-        <span class="event__offer-price">${offer.price}</span>
-      </label>
-    </div>`
-  ).join('');
-}
-
-function createAddServices(offers) {
-  return offers.map((offer) =>
-    `<li class="event__offer">
-      <span class="event__offer-title">${offer.title}</span>
-      &plus;&euro;&nbsp;
-      <span class="event__offer-price">${offer.price}</span>
-    </li>`
-  ).join('');
-}
-
-function createRoutPointTemplate(task) {
-  console.log(task);
-  const {destinationDetails, type, offers, startDate, endDate, basePrice} = task;
+function createRoutPointTemplate(task, cbForm, cbBox) {
+  const {type, offers, startDate, endDate, basePrice} = task;
+  const additionalContentForm = typeof cbForm === 'function' ? cbForm(type, offers, startDate, endDate, basePrice) : '';
+  const additionalContentBox = typeof cbBox === 'function' ? cbBox(task) : '';
 
   return `<li class="trip-events__item">
-            <div class="event">
-              <time class="event__date" datetime="${showFullDate(startDate)}">${humanizeTaskDueDate(startDate)}</time>
-              <div class="event__type">
-                <img class="event__type-icon" width="42" height="42" src="img/icons/${type}.png" alt="Event type icon">
-              </div>
-              <h3 class="event__title">${type} ${destinationDetails.name}</h3>
-              <div class="event__schedule">
-                <p class="event__time">
-                  <time class="event__start-time" datetime="${showFullDateTime(startDate)}">${showTripDuration(startDate)}</time>
-                  &mdash;
-                  <time class="event__end-time" datetime="${showFullDateTime(endDate)}">${showTripDuration(endDate)}</time>
-                </p>
-                <p class="event__duration">${calculateTripDuration(startDate, endDate)}</p>
-              </div>
-              <p class="event__price">
-                &euro;&nbsp;<span class="event__price-value">${basePrice}</span>
-              </p>
-              <h4 class="visually-hidden">Offers:</h4>
-              <ul class="event__selected-offers">
-                ${createAddServices(offers)}
-              </ul>
-              <button class="event__favorite-btn  event__favorite-btn--active" type="button">
-                <span class="visually-hidden">Add to favorite</span>
-                <svg class="event__favorite-icon" width="28" height="28" viewBox="0 0 28 28">
-                  <path d="M14 21l-8.22899 4.3262 1.57159-9.1631L.685209 9.67376 9.8855 8.33688 14 0l4.1145 8.33688 9.2003 1.33688-6.6574 6.48934 1.5716 9.1631L14 21z"/>
-                </svg>
-              </button>
-              <button class="event__rollup-btn" type="button">
-                <span class="visually-hidden">Open event</span>
-              </button>
-            </div>
-            ${createAddNewPointWithout(type, offers, startDate, endDate, basePrice)}
+            ${additionalContentBox}
+            ${additionalContentForm}
           </li>`;
 }
 
-export default class RoutPointView {
-  constructor({task}) {
-    this.task = task;
-    this.element = null;
-  }
-
-  getTemplate() {
-    return createRoutPointTemplate(this.task);
-  }
+export default class RoutPointView extends AbstractView {
+  #task = null;
+  #cbForm = null;
+  #cbBox = null;
 
-  getElement() {
-    if (!this.element) {
-      this.element = createElement(this.getTemplate());
-      const eventRollupButtonElement = this.element.querySelector('.event__rollup-btn');
-      eventRollupButtonElement.addEventListener('click', this.handleRollupButtonClick);
-    }
-    return this.element;
+  constructor({task, cbForm, cbBox}) {
+    super();
+    this.#task = task;
+    this.#cbForm = cbForm;
+    this.#cbBox = cbBox;
   }
 
-  handleRollupButtonClick = () => {
-    const formElement = this.element.querySelector('.event--edit');
-    const pointElement = this.element.querySelector('.event');
-    formElement.classList.toggle('hidden');
-    pointElement.classList.toggle('hidden');
-  };
-
-  removeElement() {
-    this.element = null;
+  get template() {
+    return createRoutPointTemplate(this.#task, this.#cbForm, this.#cbBox);
   }
 }
diff --git a/src/view/trip-events-list-view.js b/src/view/trip-events-list-view.js
index 59e2c4e..644684b 100644
--- a/src/view/trip-events-list-view.js
+++ b/src/view/trip-events-list-view.js
@@ -1,23 +1,11 @@
-import {createElement} from '../render.js';
+import AbstractView from '../framework/view/abstract-view.js';
 
 function createTripEventsListTemplate() {
   return '<ul class="trip-events__list"></ul>';
 }
 
-export default class TripEventsListView {
-  getTemplate() {
+export default class TripEventsListView extends AbstractView {
+  get template() {
     return createTripEventsListTemplate();
   }
-
-  getElement() {
-    if (!this.element) {
-      this.element = createElement(this.getTemplate());
-    }
-
-    return this.element;
-  }
-
-  removeElement() {
-    this.element = null;
-  }
 }
diff --git a/src/view/trip-form-filters-view.js.js b/src/view/trip-form-filters-view.js.js
index 134e0ef..5f4f4b0 100644
--- a/src/view/trip-form-filters-view.js.js
+++ b/src/view/trip-form-filters-view.js.js
@@ -1,4 +1,4 @@
-import {createElement} from '../render.js';
+import AbstractView from '../framework/view/abstract-view.js';
 
 function createTripFormFiltersTemplate() {
   return `<form class="trip-filters" action="#" method="get">
@@ -23,20 +23,8 @@ function createTripFormFiltersTemplate() {
           </form>`;
 }
 
-export default class TripFormFiltersView {
-  getTemplate() {
+export default class TripFormFiltersView extends AbstractView {
+  get template() {
     return createTripFormFiltersTemplate();
   }
-
-  getElement() {
-    if (!this.element) {
-      this.element = createElement(this.getTemplate());
-    }
-
-    return this.element;
-  }
-
-  removeElement() {
-    this.element = null;
-  }
 }
diff --git a/src/view/trip-form-sort-view.js b/src/view/trip-form-sort-view.js
index 40e6b5e..83d60bd 100644
--- a/src/view/trip-form-sort-view.js
+++ b/src/view/trip-form-sort-view.js
@@ -1,4 +1,4 @@
-import {createElement} from '../render.js';
+import AbstractView from '../framework/view/abstract-view.js';
 
 function createTripFormSortTemplate() {
   return `<form class="trip-events__trip-sort  trip-sort" action="#" method="get">
@@ -29,20 +29,8 @@ function createTripFormSortTemplate() {
           </form>`;
 }
 
-export default class TripFormSortView {
-  getTemplate() {
+export default class TripFormSortView extends AbstractView {
+  get template() {
     return createTripFormSortTemplate();
   }
-
-  getElement() {
-    if (!this.element) {
-      this.element = createElement(this.getTemplate());
-    }
-
-    return this.element;
-  }
-
-  removeElement() {
-    this.element = null;
-  }
 }
diff --git a/src/view/trip-info-view.js b/src/view/trip-info-view.js
index cb0bab9..85deb22 100644
--- a/src/view/trip-info-view.js
+++ b/src/view/trip-info-view.js
@@ -1,4 +1,4 @@
-import {createElement} from '../render.js';
+import AbstractView from '../framework/view/abstract-view.js';
 
 function createTripInfoTemplate() {
   return `<section class="trip-main__trip-info  trip-info">
@@ -12,20 +12,8 @@ function createTripInfoTemplate() {
           </section>`;
 }
 
-export default class TripInfoView {
-  getTemplate() {
+export default class TripInfoView extends AbstractView {
+  get template() {
     return createTripInfoTemplate();
   }
-
-  getElement() {
-    if (!this.element) {
-      this.element = createElement(this.getTemplate());
-    }
-
-    return this.element;
-  }
-
-  removeElement() {
-    this.element = null;
-  }
 }


Reviews:
user: login: 0x41rtur
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-11T11:23:13Z

Review comments:
diff_hunk: @@ -1,22 +1,68 @@
 import TripEventsListView from '../view/trip-events-list-view.js';
 import RoutPointView from '../view/route-point-view.js';
-import {render} from '../render.js';
+import {render, replace} from '../framework/render.js';
+import RoutPointEditView from '../view/route-point-edit-view.js';
+import RoutPointBoxView from '../view/route-point-box-view.js';
 
 export default class ListPresenter {
-  listComponent = new TripEventsListView;
+  #tasksModel = null;
+  #boardContainer = null;
+  #listComponent = new TripEventsListView;
+  #boardTasks = [];
 
   constructor({boardContainer, tasksModel}) {
-    this.boardContainer = boardContainer;
-    this.tasksModel = tasksModel;
+    this.#boardContainer = boardContainer;
+    this.#tasksModel = tasksModel;
   }
 
   init() {
-    this.boardTasks = [...this.tasksModel.getTasks()];
+    this.#boardTasks = [...this.#tasksModel.getTasks()];
+    render(this.#listComponent, this.#boardContainer);
+    for (let i = 0; i < this.#boardTasks.length; i++) {
+      this.#renderTask(this.#boardTasks[i]);
+    }
+  }
+
+  #renderTask(task) {
+    const escKeyDownHandler = (evt) => {
+      if (evt.key === 'Escape') {
+        evt.preventDefault();
+        replaceFormToCard();
+        document.removeEventListener('keydown', escKeyDownHandler);
+      }
+    };
path: src/presenter/list-presenter.js
user: login: 0x41rtur
body: подумай, тут можно ведь повесить только 1 обработчик на все карточки а не на каждую
created_at: 2025-03-11T11:21:15Z
author_association: NONE
diff_hunk: @@ -0,0 +1,154 @@
+import AbstractView from '../framework/view/abstract-view.js';
+import {showNewPointDate} from '../utils.js';
+
+function createAddNewPointWithout(type, offers, startDate, endDate, basePrice) {
+  return `<form class="event event--edit" action="#" method="post">
+            <header class="event__header">
+              <div class="event__type-wrapper">
+                <label class="event__type  event__type-btn" for="event-type-toggle-1">
+                  <span class="visually-hidden">Choose event type</span>
+                  <img class="event__type-icon" width="17" height="17" src="img/icons/${type}.png" alt="Event type icon">
+                </label>
+                <input class="event__type-toggle  visually-hidden" id="event-type-toggle-1" type="checkbox">
+
+                <div class="event__type-list">
path: src/view/route-point-edit-view.js
user: login: 0x41rtur
body: можно вынести в отдельный шаблон списка
created_at: 2025-03-11T11:22:58Z
author_association: NONE

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-10T13:35:08Z
body: Ваш пулреквест опубликован. Посмотреть можно [здесь](https://htmlacademy-ecmascript.github.io/1048521-big-trip-2/5/)
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-10T20:15:44Z
body: Ваш пулреквест опубликован. Посмотреть можно [здесь](https://htmlacademy-ecmascript.github.io/1048521-big-trip-2/5/)
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-10T20:23:03Z
body: Ваш пулреквест опубликован. Посмотреть можно [здесь](https://htmlacademy-ecmascript.github.io/1048521-big-trip-2/5/)
author_association: NONE