diff --git a/src/destinations-api-service.js b/src/destinations-api-service.js new file mode 100644 index 0000000..6af354b --- /dev/null +++ b/src/destinations-api-service.js @@ -0,0 +1,18 @@ +/* eslint-disable no-console */ +import ApiService from './framework/api-service.js'; + +export default class DestinationsApiService extends ApiService { + get destinations() { + return this._fetchData({url: 'destinations'}); + } + + async _fetchData(config) { + try { + const response = await this._load(config); + return await ApiService.parseResponse(response); + } catch (error) { + console.error('Failed to fetch data:', error); + throw error; + } + } +} diff --git a/src/main.js b/src/main.js index 0b0b7d6..42827a6 100644 --- a/src/main.js +++ b/src/main.js @@ -6,6 +6,12 @@ import NewPointBtnView from './view/new-point-button-view'; import FilterModel from './model/filters-model'; import FilterPresenter from './presenter/filter-presenter'; import { render } from './framework/render'; +import PointsApiService from './points-api-service'; +import DestinationsApiService from './destinations-api-service'; +import OffersApiService from './offers-api-service'; + +const AUTHORIZATION = 'Basic hsdl3232JDSkfkd'; +const END_POINT = 'https://21.objects.htmlacademy.pro/big-trip'; const bodyElement = document.querySelector('body'); const headerElement = bodyElement.querySelector('.page-header'); @@ -13,11 +19,20 @@ const headerElement = bodyElement.querySelector('.page-header'); const siteListFilter = headerElement.querySelector('.trip-controls__filters'); const tripMain = headerElement.querySelector('.trip-main'); const eventsList = bodyElement.querySelector('.trip-events'); -const pointsModel = new PointsModel(); -const destinationsModel = new DestinationsModel(); -const offersModel = new OffersModel(); const filterModel = new FilterModel(); +const pointsModel = new PointsModel({ + pointsApiService: new PointsApiService(END_POINT, AUTHORIZATION), +}); + +const destinationsModel = new DestinationsModel({ + destinationsApiService: new DestinationsApiService(END_POINT, AUTHORIZATION), +}); + +const offersModel = new OffersModel({ + offersApiService: new OffersApiService(END_POINT, AUTHORIZATION), +}); + const boardPresenter = new BoardPresenter({ container: eventsList, headerContainer: tripMain, @@ -49,6 +64,14 @@ function handleNewPointButtonClick() { render(newPointButtonComponent, tripMain); -filterPresenter.init(); -boardPresenter.init(); +const awaiter = async () => { + await Promise.all([ + offersModel.init(), + destinationsModel.init(), + ]); + pointsModel.init(); + filterPresenter.init(); + boardPresenter.init(); +}; +awaiter(); diff --git a/src/mock/const.js b/src/mock/const.js index a72daf5..251af46 100644 --- a/src/mock/const.js +++ b/src/mock/const.js @@ -10,54 +10,6 @@ const TRANSPORT_IMAGES = [ 'restaurant', ]; -const TRANSPORT_OFFERS = [ - {'taxi': [{title: 'taxi-offer-1', price: 10}, {title: 'taxi-offer-2', price: 20}, {title: 'taxi-offer-3', price: 30}]}, - {'bus': [{title: 'bus-offer-1', price: 10}, {title: 'bus-offer-2', price: 20}, {title: 'bus-offer-3', price: 30}]}, - {'train': [{title: 'train-offer-1', price: 10}, {title: 'train-offer-2', price: 20}, {title: 'train-offer-3', price: 30}]}, - {'ship': [{title: 'ship-offer-1', price: 10}, {title: 'ship-offer-2', price: 20}, {title: 'ship-offer-3', price: 30}]}, - {'drive': [{title: 'drive-offer-1', price: 10}, {title: 'drive-offer-2', price: 20}, {title: 'drive-offer-3', price: 30}]}, - {'flight': [{title: 'flight-offer-1', price: 10}, {title: 'flight-offer-2', price: 20}, {title: 'flight-offer-3', price: 30}]}, - {'check-in': [{title: 'check-in-offer-1', price: 10}, {title: 'check-in-offer-2', price: 20}, {title: 'check-in-offer-3', price: 30}]}, - {'sightseeing': [{title: 'sightseeing-offer-1', price: 10}, {title: 'sightseeing-offer-2', price: 20}, {title: 'sightseeing-offer-3', price: 30}]}, - {'restaurant': [{title: 'restaurant-offer-1', price: 10}, {title: 'restaurant-offer-2', price: 20}, {title: 'restaurant-offer-3', price: 30}]}, -]; - -const CITIES = [ - 'Amsterdam', - 'Geneva', - 'Chamonix', - 'Tokyo', - 'Moscow', - 'Abu Dhabi', - 'Brussels', - 'Budapest', - 'Cairo', - 'Cape Town', - 'Chicago', - 'Dubai', - 'Helsinki', -]; - -/* const citiesData = CITIES.map((city, index) => ({ - id: crypto.randomUUID(), - description: `${city}, is a beautiful city, a true Asian pearl, with crowded streets.`, - name: city, - pictures: [ - { - src: `https://loremflickr.com/300/200?random=${index}`, - description: `${city} parliament building`, - } - ] -})); */ - -const OFFERS = [ - {ofName: 'Add luggage', price: 30}, - {ofName: 'Switch to comfort class', price: 100}, - {ofName: 'Add meal', price: 15}, - {ofName: 'Choose seats', price: 5}, - {ofName: 'Travel by train', price: 40}, -]; - const FilterType = { EVERYTHING: 'everything', FUTURE: 'future', @@ -90,6 +42,7 @@ const UpdateType = { PATCH: 'PATCH', MINOR: 'MINOR', MAJOR: 'MAJOR', + INIT: 'INIT', }; -export {TRANSPORT_IMAGES, CITIES, OFFERS, FilterType, SortType, EmptyFilter, TRANSPORT_OFFERS, UserAction, UpdateType}; +export {TRANSPORT_IMAGES, FilterType, SortType, EmptyFilter, UserAction, UpdateType}; diff --git a/src/mock/point.js b/src/mock/point.js deleted file mode 100644 index cad39b3..0000000 --- a/src/mock/point.js +++ /dev/null @@ -1,111 +0,0 @@ -import { getRandomArrayElement, getRandomInt } from '../utils/common'; -import { TRANSPORT_IMAGES, TRANSPORT_OFFERS, CITIES } from './const'; -import { NOW } from '../utils/task'; -import dayjs from 'dayjs'; - -const mockOffers = []; -const mockDests = []; -//`cfe${d}16cq-10xa-ye10-8077-2fs9a01edcab` - -const citiesData = CITIES.map((city, index) => ({ - id: crypto.randomUUID(), - description: `${city}, is a beautiful city, a true Asian pearl, with crowded streets.`, - name: city, - pictures: [ - { - src: `https://loremflickr.com/300/200?random=${index}`, - description: `${city} parliament building`, - } - ] -})); - -function getRandomPoint() { - - const id = crypto.randomUUID(); - const price = getRandomInt(20, 2000); - const isFavorite = getRandomInt(0, 2) === 1; - const type = getRandomArrayElement(TRANSPORT_IMAGES); - const dates = []; - dates.push(NOW.subtract(getRandomInt(0, 20), 'day').subtract(getRandomInt(0, 24), 'hour').subtract(getRandomInt(1, 50), 'minute').toISOString()); - dates.push(NOW.add(getRandomInt(0, 20), 'day').add(getRandomInt(0, 24), 'hour').add(getRandomInt(1, 50), 'minute').toISOString()); - dates.push(NOW.toISOString()); - const dateFrom = getRandomArrayElement(dates); - const dateTo = dayjs(dateFrom).add(getRandomInt(0, 20), 'day').add(getRandomInt(0, 24), 'hour').add(getRandomInt(1, 50), 'minute').toISOString(); - //const d = getRandomInt(4,8); - const offersIds = []; - const destId = getRandomArrayElement(citiesData).id; - - for(let i = 0; i < getRandomInt(0,4); i++) { - offersIds.push(crypto.randomUUID()); - } - - const point = { - id: id, - basePrice: price, - dateFrom: dateFrom, - dateTo: dateTo, - destination: destId, - isFavorite: isFavorite, - offers: [ - ...offersIds, - ], - type: type - }; - - getOffers(point); - getDests(point); - - return point; -} - -function getOffers(point) { - if(point === undefined) { - return; - } - const allOffers = []; - const offersArr = Object.values(TRANSPORT_OFFERS.find((x) => Object.keys(x)[0] === point.type)); - if(point.offers.length > 0) { - for(let i = 0; i < point.offers.length; i++) { - - const ofEl = offersArr[0][i]; - - const of = { - id: point.offers[i], - title: ofEl.title, - price: ofEl.price - }; - - allOffers.push(of); - } - } - - const offer = { - type: point.type, - offers: [ - ...allOffers, - ] - }; - mockOffers.push(offer); - //console.log(offer) - return offer; -} - -function getDests(point) { - const id = point.destination; - const city = getRandomArrayElement(CITIES); - const dest = { - id: id, - description: `${city}, is a beautiful city, a true asian pearl, with crowded streets.`, - name: `${city}`, - pictures: [ - { - src: `https://loremflickr.com/300/200?random=${point.destination}`, - description: `${city} parliament building`, - } - ] - }; - mockDests.push(dest); - -} - -export {getRandomPoint, mockOffers, mockDests, getDests, getOffers, citiesData}; diff --git a/src/model/destinations-model.js b/src/model/destinations-model.js index bc58984..276f435 100644 --- a/src/model/destinations-model.js +++ b/src/model/destinations-model.js @@ -1,8 +1,22 @@ import Observable from '../framework/observable'; -import { mockDests } from '../mock/point'; export default class DestinationsModel extends Observable{ - #destinations = mockDests; + #destinations = []; + #destinationsApiService = null; + + constructor({destinationsApiService}) { + super(); + this.#destinationsApiService = destinationsApiService; + } + + async init() { + try { + const destinations = await this.#destinationsApiService.destinations; + this.#destinations = destinations.map((dest) => dest); + } catch(err) { + this.#destinations = []; + } + } get destinations(){ return this.#destinations; diff --git a/src/model/offers-model.js b/src/model/offers-model.js index 3332986..52da13e 100644 --- a/src/model/offers-model.js +++ b/src/model/offers-model.js @@ -1,10 +1,24 @@ import Observable from '../framework/observable'; -import { mockOffers } from '../mock/point'; export default class OffersModel extends Observable{ - #offers = mockOffers; + #offers = []; + #offersApiService = null; + + constructor({offersApiService}) { + super(); + this.#offersApiService = offersApiService; + } get offers(){ return this.#offers; } + + async init() { + try { + const offers = await this.#offersApiService.offers; + this.#offers = offers.map((offer) => offer); + } catch(err) { + this.#offers = []; + } + } } diff --git a/src/model/points-model.js b/src/model/points-model.js index 811d889..9adf002 100644 --- a/src/model/points-model.js +++ b/src/model/points-model.js @@ -1,31 +1,52 @@ -import { getRandomPoint } from '../mock/point.js'; -import { sortPointsArrByDay } from '../utils/task.js'; -import { getRandomInt } from '../utils/common.js'; import Observable from '../framework/observable.js'; - -const POINTS_COUNT = getRandomInt(0, 2); +import { UpdateType } from '../mock/const.js'; export default class PointsModel extends Observable{ - #points = Array.from({length: POINTS_COUNT}, getRandomPoint).sort(sortPointsArrByDay); + #pointsApiService = null; + #points = []; + + + constructor({pointsApiService}) { + super(); + this.#pointsApiService = pointsApiService; + } get points() { return this.#points; } - updatePoint(updateType, update) { + async init() { + try { + const points = await this.#pointsApiService.points; + this.#points = points.map(this.#adaptToClient); + } catch(err) { + this.#points = []; + } + + this._notify(UpdateType.INIT); + } + + async updatePoint(updateType, update) { const index = this.#points.findIndex((point) => point.id === update.id); if(index === -1) { throw new Error('Can\'t update unexisting point'); } - this.#points = [ - ...this.#points.slice(0, index), - update, - ...this.#points.slice(index + 1), - ]; + try { + const response = await this.#pointsApiService.updatePoint(update); + const updatedPoint = this.#adaptToClient(response); - this._notify(updateType, update); + this.#points = [ + ...this.#points.slice(0, index), + updatedPoint, + ...this.#points.slice(index + 1), + ]; + + this._notify(updateType, updatedPoint); + } catch(err) { + throw new Error('Can\'t update point'); + } } addPoint(updateType, update) { @@ -53,5 +74,15 @@ export default class PointsModel extends Observable{ this._notify(updateType); } + + #adaptToClient(point) { + const { 'base_price': basePrice, 'date_from': dateFrom, 'date_to': dateTo, 'is_favorite': isFavorite, ...rest } = point; + return { + ...rest, + basePrice, + dateFrom, + dateTo, + isFavorite, + }; + } } -export {POINTS_COUNT}; diff --git a/src/offers-api-service.js b/src/offers-api-service.js new file mode 100644 index 0000000..67e1826 --- /dev/null +++ b/src/offers-api-service.js @@ -0,0 +1,18 @@ +/* eslint-disable no-console */ +import ApiService from './framework/api-service.js'; + +export default class OffersApiService extends ApiService { + get offers() { + return this._fetchData({url: 'offers'}); + } + + async _fetchData(config) { + try { + const response = await this._load(config); + return await ApiService.parseResponse(response); + } catch (error) { + console.error('Failed to fetch data:', error); + throw error; + } + } +} diff --git a/src/points-api-service.js b/src/points-api-service.js new file mode 100644 index 0000000..85e3e05 --- /dev/null +++ b/src/points-api-service.js @@ -0,0 +1,63 @@ +/* eslint-disable no-console */ +import ApiService from './framework/api-service.js'; + +const Method = { + GET: 'GET', + PUT: 'PUT', + POST: 'POST', + DELETE: 'DELETE', +}; + +export default class PointsApiService extends ApiService { + get points() { + return this._fetchData({ url: 'points' }); + } + + async updatePoint(point) { + return this._fetchData({ + url: `points/${point.id}`, + method: Method.PUT, + body: JSON.stringify(this.#adaptToServer(point)), + headers: new Headers({ 'Content-Type': 'application/json' }), + }); + } + + async addPoint(point) { + return this._fetchData({ + url: 'points', + method: Method.POST, + body: JSON.stringify(this.#adaptToServer(point)), + headers: new Headers({ 'Content-Type': 'application/json' }), + }); + } + + async deletePoint(point) { + return this._fetchData({ + url: `points/${point.id}`, + method: Method.DELETE, + body: JSON.stringify(point), + headers: new Headers({ 'Content-Type': 'application/json' }), + }); + } + + async _fetchData(config) { + try { + const response = await this._load(config); + return await ApiService.parseResponse(response); + } catch (error) { + console.error('Failed to fetch data:', error); + throw error; + } + } + + #adaptToServer(point) { + const { basePrice, dateFrom, dateTo, isFavorite, ...rest } = point; + return { + ...rest, + 'base_price': basePrice, + 'date_from': dateFrom, + 'date_to': dateTo, + 'is_favorite': isFavorite, + }; + } +} diff --git a/src/presenter/board-presenter.js b/src/presenter/board-presenter.js index 9b4d0b0..102827c 100644 --- a/src/presenter/board-presenter.js +++ b/src/presenter/board-presenter.js @@ -5,13 +5,13 @@ import PointView from '../view/point-view'; import ListSortElement from '../view/sort-view'; import ListEmpty from '../view/list-empty-view'; import MainInfo from '../view/info-view'; +import LoadingView from '../view/loading-view'; import PointPresenter from './point-presenter'; import { filter } from '../utils/filter'; import { SortType, UpdateType, UserAction } from '../mock/const'; import { sortPointsArrByPrice, sortPointsArrByTime, sortPointsArrByDay } from '../utils/task'; import { FilterType } from '../mock/const'; import NewPointPresenter from './new-point-presenter'; -import { citiesData } from '../mock/point'; export default class BoardPresenter { #container = null; @@ -26,6 +26,7 @@ export default class BoardPresenter { #eventListComponent = null; #newPointComponent = null; #noPointsComponent = null; + #loadingComponent = new LoadingView(); #pointPresenter = new Map(); #newPointPresenter = null; @@ -35,6 +36,7 @@ export default class BoardPresenter { #allDests = null; #curDests = []; + #isLoading = true; constructor({container, headerContainer, eventListComponent, editPoint, infoView, pointView, pointsModel, offersModel, destinationsModel, noPointsComponent, filterModel, onNewPointDestroy}) { this.#container = container; @@ -62,7 +64,6 @@ export default class BoardPresenter { } init() { - this.#allDests = citiesData; this.#renderComponents(); } @@ -83,16 +84,12 @@ export default class BoardPresenter { switch(this.#currentSortType) { case SortType.PRICE: - //return [this.#pointsModel.points].sort(sortPointsArrByPrice); return filteredPoints.sort(sortPointsArrByPrice); case SortType.TIME: - //return [this.#pointsModel.points].sort(sortPointsArrByTime); return filteredPoints.sort(sortPointsArrByTime); case SortType.DAY: - //return [this.#pointsModel.points].sort(sortPointsArrByTime); return filteredPoints.sort(sortPointsArrByDay); } - //return this.#pointsModel.points; return filteredPoints; } @@ -116,6 +113,7 @@ export default class BoardPresenter { this.#pointPresenter.clear(); remove(this.#sortComponent); + remove(this.#loadingComponent); remove(this.#mainInfoComponent); if(this.#noPointsComponent) { remove(this.#noPointsComponent); @@ -150,6 +148,8 @@ export default class BoardPresenter { eventListComponent: this.#eventListComponent, onDataChange: this.#handleViewAction, onModeChange: this.#handleModeChange, + destinations: this.destinations, + offers: this.offers, }); pointPresenter.init(point, offer, destination); @@ -184,6 +184,11 @@ export default class BoardPresenter { this.#clearBoard({resetSortType: true}); this.#renderComponents(); break; + case UpdateType.INIT: + this.#isLoading = false; + remove(this.#loadingComponent); + this.#renderComponents(); + break; } }; @@ -194,11 +199,8 @@ export default class BoardPresenter { #renderMainInfo() { if (this.points.length > 0) { - /* for(let i = 0; i < this.points.length; i++) { - } */ - //console.log(this.points) - //console.log(this.#allDests) - this.#mainInfoComponent = new MainInfo({ points: this.points, offers: this.offers, dests: this.#allDests }); + const dests = [this.#findDest(this.points[0]), this.#findDest(this.points[Math.floor(this.points.length / 2)]), this.#findDest(this.points[this.points.length - 1])]; + this.#mainInfoComponent = new MainInfo({ points: this.points, offers: this.offers, dests: dests }); render(this.#mainInfoComponent, this.#headerContainer, RenderPosition.AFTERBEGIN); } } @@ -212,6 +214,10 @@ export default class BoardPresenter { } } + #renderLoading() { + render(this.#loadingComponent, this.#container, RenderPosition.AFTERBEGIN); + } + #findOffer(point) { const matchedOffers = this.offers.find((offer) => offer.type === point.type); if (!matchedOffers) { return { type: point.type, offers: [] }; } @@ -230,8 +236,11 @@ export default class BoardPresenter { #renderDynamicComponents() { render(this.#eventListComponent, this.#container); + if(this.#isLoading) { + this.#renderLoading(); + return; + } this.#renderSort(); - //this.#renderMainInfo(); if (this.points.length === 0) { this.#renderNoPoints(); remove(this.#sortComponent); diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js index 5731455..c512759 100644 --- a/src/presenter/point-presenter.js +++ b/src/presenter/point-presenter.js @@ -21,13 +21,16 @@ export default class PointPresenter { #point = null; #offer = null; #destination = null; + #destinations = null; + #offers = null; #mode = Mode.DEFAULT; - constructor({ eventListComponent, onDataChange, onModeChange }) { + constructor({ eventListComponent, onDataChange, onModeChange, destinations, offers }) { this.#eventListComponent = eventListComponent; this.#handleDataChange = onDataChange; this.#handleModeChange = onModeChange; - + this.#destinations = destinations; + this.#offers = offers; } init(point, offer, destination) { @@ -51,6 +54,8 @@ export default class PointPresenter { onFormSubmit: this.#handleFormSubmit, onFormClose: this.#resetClickHandler, onDeleteClick: this.#handleDeleteClick, + allDestinations: this.#destinations, + allOffers: this.#offers }); if(prevPointComponent === null || prevPointEditComponent === null) { diff --git a/src/templates/edit-point-template.js b/src/templates/edit-point-template.js index f81b4a6..ee96d00 100644 --- a/src/templates/edit-point-template.js +++ b/src/templates/edit-point-template.js @@ -1,12 +1,10 @@ import { normalizeLongDayDate } from '../utils/task'; -import { TRANSPORT_IMAGES, TRANSPORT_OFFERS } from '../mock/const'; -import { citiesData } from '../mock/point'; +import { TRANSPORT_IMAGES } from '../mock/const'; import he from '../../node_modules/he'; -export const editPointTemplate = (data) => { +export const editPointTemplate = (data, allOffers, allDests) => { const point = data.state.point || {}; const dest = data.dest || {}; - const { dateFrom = '', dateTo = '', type = '', basePrice = '' } = point; const { description = '', name = '', pictures = [] } = dest; const dateF = dateFrom ? normalizeLongDayDate(dateFrom) : ''; @@ -26,17 +24,16 @@ export const editPointTemplate = (data) => { return transportTypes.join(''); } - function cities() { - return citiesData.map((city) => ``).join(''); + function getCities() { + const cities = []; + allDests.forEach((el) => { if(!cities.includes(el.name)) { cities.push(``); } }); + return cities.join(''); } function offersElements() { - const typeOffers = TRANSPORT_OFFERS.reduce((acc, offerGroup) => { - const trType = Object.keys(offerGroup)[0]; - const offersArr = offerGroup[trType]; - - if (trType === type) { - offersArr.forEach((offer) => { + const typeOffers = allOffers.reduce((acc, offerGroup) => { + if (offerGroup.type === type) { + offerGroup.offers.forEach((offer) => { const title = offer.title; const price = offer.price; const typeOf = title.split(' ')[0]; @@ -56,9 +53,9 @@ export const editPointTemplate = (data) => { return acc; }, []); - return typeOffers.join(''); } + const offersHtml = `
Loading...
' + ); +} +export {loadingTemplate}; diff --git a/src/utils/common.js b/src/utils/common.js deleted file mode 100644 index 2be3b27..0000000 --- a/src/utils/common.js +++ /dev/null @@ -1,15 +0,0 @@ -function getRandomArrayElement (points) { - return points[Math.floor(Math.random() * points.length)]; -} - -export const getRandomInt = (min, max) => { - const minCeiled = Math.ceil(min); - const maxFloored = Math.floor(max); - return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); -}; - -/* function updateItem(items, update) { - return items.map((item) => item.id === update.id ? update : item); -} */ - -export { getRandomArrayElement }; diff --git a/src/utils/task.js b/src/utils/task.js index 5f2d102..d9a36a8 100644 --- a/src/utils/task.js +++ b/src/utils/task.js @@ -76,7 +76,16 @@ function presentFilterPoints (point) { } function sortPointsArrByDay (a, b) { - return Number(dayjs(a.dateFrom).format(DAY_FORMAT)) - Number(dayjs(b.dateFrom).format(DAY_FORMAT)); + const dateA = dayjs(a.dateFrom); + const dateB = dayjs(b.dateFrom); + + if (dateA.isBefore(dateB)) { + return -1; + } else if (dateA.isAfter(dateB)) { + return 1; + } else { + return 0; + } } function sortPointsArrByPrice (a, b) { diff --git a/src/view/edit-point-view.js b/src/view/edit-point-view.js index 8306b6b..16bae54 100644 --- a/src/view/edit-point-view.js +++ b/src/view/edit-point-view.js @@ -1,7 +1,6 @@ import { editPointTemplate } from '../templates/edit-point-template'; import AbstractStatefulView from '../framework/view/abstract-stateful-view'; import flatpickr from 'flatpickr'; -import { citiesData } from '../mock/point'; import 'flatpickr/dist/flatpickr.min.css'; @@ -14,12 +13,14 @@ export default class EditPointView extends AbstractStatefulView { #datepickerFrom = null; #datepickerTo = null; #allDests = null; + #allOffers = null; - constructor({ point, offer, destination, onFormSubmit, onFormClose, onDeleteClick }) { + constructor({ point, offer, destination, onFormSubmit, onFormClose, onDeleteClick, allDestinations, allOffers }) { super(); this.#offers = offer; this.#dest = destination; - this.#allDests = citiesData; + this.#allDests = allDestinations; + this.#allOffers = allOffers; this._setState(EditPointView.parsePointToState({point})); this.#handleFormSubmit = onFormSubmit; this.#handleFormClose = onFormClose; @@ -45,7 +46,7 @@ export default class EditPointView extends AbstractStatefulView { state: this._state, offers: this.#offers, dest: this.#dest, - }); + }, this.#allOffers, this.#allDests); } diff --git a/src/view/loading-view.js b/src/view/loading-view.js new file mode 100644 index 0000000..1da7535 --- /dev/null +++ b/src/view/loading-view.js @@ -0,0 +1,8 @@ +import AbstractView from '../framework/view/abstract-view'; +import { loadingTemplate } from '../templates/loading-template'; + +export default class LoadingView extends AbstractView { + get template() { + return loadingTemplate(); + } +}