From 5dc034192d7d567c6fe26831d3147789e4ec7a6c Mon Sep 17 00:00:00 2001 From: DashaKukartseva Date: Mon, 10 Jun 2024 22:00:01 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 26 +++++++++++++------------- src/const.js | 2 -- src/main.js | 12 ++++++------ src/presenters/filterpresenter.js | 4 ++-- src/presenters/newpointpresenter.js | 29 +++-------------------------- src/presenters/pointpresenter.js | 23 +++++++++++------------ src/presenters/trippresenter.js | 24 ++++++++++++++++++------ src/presenters/utils.js | 24 ++++++++++++------------ src/service/apiservice.js | 26 ++++++++++++++++++++++++-- src/view/filter.js | 11 ++++++----- src/view/list.js | 2 +- src/view/modpoint.js | 1 + src/view/point.js | 22 ++++++++++------------ src/view/tripinfo.js | 2 +- 14 files changed, 108 insertions(+), 100 deletions(-) diff --git a/package.json b/package.json index 2dbac80..63eb2f0 100644 --- a/package.json +++ b/package.json @@ -15,23 +15,23 @@ "url": "https://github.com/DashaKukartseva/2433045-big-trip-4" }, "dependencies": { - "dayjs": "^1.11.6", - "flatpickr": "^4.6.13", - "he": "^1.2.0" + "dayjs": "1.11.6", + "flatpickr": "4.6.13", + "he": "1.2.0" }, "devDependencies": { - "@babel/core": "^7.24.0", - "@babel/preset-env": "^7.24.0", - "babel-loader": "^9.1.3", - "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.11.0", + "@babel/core": "7.24.0", + "@babel/preset-env": "7.24.0", + "babel-loader": "9.1.3", + "copy-webpack-plugin": "11.0.0", + "css-loader": "6.11.0", "eslint": "8.28.0", "eslint-config-htmlacademy": "8.0.0", - "html-webpack-plugin": "^5.6.0", - "style-loader": "^3.3.4", - "webpack": "^5.75.0", - "webpack-cli": "^5.0.0", - "webpack-dev-server": "^4.11.1" + "html-webpack-plugin": "5.6.0", + "style-loader": "3.3.4", + "webpack": "5.75.0", + "webpack-cli": "5.0.0", + "webpack-dev-server": "4.11.1" }, "engines": { "node": "18" diff --git a/src/const.js b/src/const.js index 2af7902..5358943 100644 --- a/src/const.js +++ b/src/const.js @@ -1,4 +1,3 @@ -const TYPES = ['taxi','bus','train','ship','drive','flight','check-in','sightseeing','restaurant']; const DEFAULT_TYPE = 'flight'; const DESTINATION_ITEMS_LENGTH = 3; @@ -86,7 +85,6 @@ export { UpdateType, Mode, FilterType, - TYPES, POINT_EMPTY, MSEC_IN_HOUR, MSEC_IN_DAY, DESTINATION_ITEMS_LENGTH, SortType}; diff --git a/src/main.js b/src/main.js index 4a37f86..f539e38 100644 --- a/src/main.js +++ b/src/main.js @@ -8,7 +8,7 @@ import pointApiService from './service/apiservice.js'; import FilterModel from './model/filters.js'; import { render, RenderPosition } from './framework/render.js'; -const AUTHORIZATION = 'Basic dd89j3m2h5l'; +const AUTHORIZATION = 'Basic dd89j3m2h10l'; const END_POINT = 'https://21.objects.htmlacademy.pro/big-trip'; const apiService = new pointApiService(END_POINT, AUTHORIZATION); @@ -28,7 +28,8 @@ const routePresenter = new TripPointsPresenter({ offersModel, pointsModel, filterModel, - onNewPointDestroy: handleNewPointFormClose + onNewPointDestroy: handleNewPointFormClose, + onNewPointClick: handleNewPointClick, }); const filterPresenter = new FilterPresenter({ @@ -46,12 +47,11 @@ function handleNewPointFormClose() { } function handleNewPointButtonClick() { - routePresenter.createPoint(); - newPointButtonComponent.element.disabled = true; + routePresenter.createEvent(); + handleNewPointClick(); } render(newPointButtonComponent, tripMainContainer, RenderPosition.BEFOREEND); - -routePresenter.init(); filterPresenter.init(); +routePresenter.init(); pointsModel.init(); diff --git a/src/presenters/filterpresenter.js b/src/presenters/filterpresenter.js index 4f6ed2d..18fde04 100644 --- a/src/presenters/filterpresenter.js +++ b/src/presenters/filterpresenter.js @@ -1,7 +1,7 @@ import { render, replace, remove } from '../framework/render.js'; import FilterView from '../view/filter.js'; import { filter } from '../utils.js'; -import { UpdateType } from '../const'; +import { UpdateType, FilterType} from '../const'; export default class FilterPresenter { #filterContainer = null; @@ -25,7 +25,7 @@ export default class FilterPresenter { return Object.entries(filter).map( ([filterType, filterPoints]) => ({ type: filterType, - exists: filterPoints(points).length > 0 + exists: filterType === FilterType.EVERYTHING ? true : filterPoints(points).length > 0 }) ); } diff --git a/src/presenters/newpointpresenter.js b/src/presenters/newpointpresenter.js index 344f9e8..28382f8 100644 --- a/src/presenters/newpointpresenter.js +++ b/src/presenters/newpointpresenter.js @@ -1,8 +1,7 @@ import { remove, render, RenderPosition } from '../framework/render.js'; import EditablePointView from '../view/modpoint.js'; -import { UserAction, UpdateType, EditType, Method } from '../const.js'; +import {UserAction, UpdateType, EditType} from '../const.js'; import { isEscapeKey, } from '../utils.js'; -import pointApiService from '../service/apiservice.js'; export default class NewPointPresenter { #pointListContainer = null; @@ -10,7 +9,6 @@ export default class NewPointPresenter { #offersModel = null; #handleDataChange = null; #handleDestroy = null; - #pointEditComponent = null; constructor({pointListContainer, destinationsModel, offersModel, onDataChange, onDestroy}) { @@ -59,11 +57,11 @@ export default class NewPointPresenter { }); } - #handleEditSubmit = (event) => { + #handleEditSubmit = (point) => { this.#handleDataChange( UserAction.ADD_EVENT, UpdateType.MINOR, - {id: crypto.randomUUID(), ...event}, + point ); }; @@ -79,7 +77,6 @@ export default class NewPointPresenter { this.#pointEditComponent.shake(resetFormState); } - #handleResetClick = () => { this.destroy(); }; @@ -90,24 +87,4 @@ export default class NewPointPresenter { this.destroy(); } }; - - async addPoint(update) { - const response = await this._load({ - url: 'points', - method: Method.POST, - body: JSON.stringify(adaptToServer(update)), - headers: new Headers({'Content-Type': 'application/json'}), - }); - const parsedResponse = await pointApiService.parseResponse(response); - return parsedResponse; - } - - async deleteEvent(update) { - const response = await this._load({ - url: `points/${update.id}`, - method: Method.DELETE, - }); - - return response; - } } diff --git a/src/presenters/pointpresenter.js b/src/presenters/pointpresenter.js index 9e5808e..1acd6f9 100644 --- a/src/presenters/pointpresenter.js +++ b/src/presenters/pointpresenter.js @@ -1,29 +1,28 @@ import { render, replace, remove } from '../framework/render.js'; -import { Mode } from '../const.js'; -import { isEscapeKey } from '../utils.js'; +import { isEscapeKey, isBigDifference } from '../utils.js'; import PointView from '../view/point.js'; import EditablePointView from '../view/modpoint.js'; -import { UserAction, UpdateType } from '../const.js'; -import { isBigDifference } from '../utils.js'; +import { UserAction, UpdateType, Mode } from '../const.js'; export default class PointPresenter { #pointListContainer = null; #destinationsModel = null; #offersModel = null; - #onDataChange = null; + #handleDataChange = null; #point = null; #pointComponent = null; #pointEditComponent = null; - #onModeChange = null; + #handleDataChange = null; + #handleModeChange = null; #mode = Mode.DEFAULT; constructor({pointListContainer, destinationsModel, offersModel, onDataChange, onModeChange}) { this.#pointListContainer = pointListContainer; this.#destinationsModel = destinationsModel; this.#offersModel = offersModel; - this.#onDataChange = onDataChange; - this.#onModeChange = onModeChange; + this.#handleDataChange = onDataChange; + this.#handleModeChange = onModeChange; } init(point) { @@ -107,7 +106,7 @@ export default class PointPresenter { #replacePointToEditor() { replace(this.#pointEditComponent, this.#pointComponent); document.addEventListener('keydown', this.#escKeyDownHandler); - this.#onModeChange(); + this.#handleModeChange(); this.#mode = Mode.EDITING; } @@ -122,7 +121,7 @@ export default class PointPresenter { }; #favoriteClickHandler = () => { - this.#onDataChange( UserAction.UPDATE_EVENT, UpdateType.PATCH, {...this.#point, isFavorite: !this.#point.isFavorite}); + this.#handleDataChange( UserAction.UPDATE_EVENT, UpdateType.PATCH, {...this.#point, isFavorite: !this.#point.isFavorite}); }; #editorRollupClickHandler = () => { @@ -132,7 +131,7 @@ export default class PointPresenter { #editSubmitHandler = (update) => { const isMinorUpdate = isBigDifference(update, this.#point); - this.#onDataChange( + this.#handleDataChange( UserAction.UPDATE_EVENT, isMinorUpdate ? UpdateType.MINOR : UpdateType.PATCH, update, @@ -141,7 +140,7 @@ export default class PointPresenter { }; #editResetHandler = (event) => { - this.#onDataChange( + this.#handleDataChange( UserAction.DELETE_EVENT, UpdateType.MINOR, event, diff --git a/src/presenters/trippresenter.js b/src/presenters/trippresenter.js index 4840c1f..1d8fc34 100644 --- a/src/presenters/trippresenter.js +++ b/src/presenters/trippresenter.js @@ -13,6 +13,7 @@ export default class TripPointsPresenter { #listComponent = new ListView(); #sortComponent = null; #noPointComponent = null; + #tripContainer = null; #tripInfoContainer = null; @@ -20,26 +21,32 @@ export default class TripPointsPresenter { #offersModel = null; #pointsModel = null; #filterModel = null; + #handleNewPointClick = null; + #handleNewPointDestroy = null; + #tripInfoPresenter = null; #pointPresenters = new Map(); #newPointPresenter = null; + #currentSortType = SortType.DAY; #filterType = FilterType.EVERYTHING; #isLoading = true; #isLoadingError = false; + #isCreating = false; #uiBlocker = new UiBlocker({ lowerLimit: TimeLimit.LOWER_LIMIT, upperLimit: TimeLimit.UPPER_LIMIT }); - constructor({tripInfoContainer, tripContainer, destinationsModel, offersModel, pointsModel,filterModel, onNewPointDestroy}) { + constructor({tripInfoContainer, tripContainer, destinationsModel, offersModel, pointsModel,filterModel, onNewPointDestroy, onNewPointClick}) { this.#tripInfoContainer = tripInfoContainer; this.#tripContainer = tripContainer; this.#destinationsModel = destinationsModel; this.#offersModel = offersModel; this.#pointsModel = pointsModel; this.#filterModel = filterModel; - this.#tripContainer = tripContainer; + this.#handleNewPointClick = onNewPointClick; + this.#handleNewPointDestroy = onNewPointDestroy; this.#newPointPresenter = new NewPointPresenter({ pointListContainer: this.#listComponent, @@ -54,9 +61,10 @@ export default class TripPointsPresenter { } get points() { - this.#filterType = this.#filterModel.filter; + this.#filterType = FilterType.EVERYTHING; const points = this.#pointsModel.get(); const filteredPoints = filter[this.#filterType](points); + return sort[this.#currentSortType](filteredPoints); } @@ -65,14 +73,17 @@ export default class TripPointsPresenter { } createPoint() { + this.#isCreating = true; this.#currentSortType = SortType.DAY; this.#filterModel.setFilter(UpdateType.MAJOR, FilterType.EVERYTHING); this.#newPointPresenter.init(); + this.#isCreating = false; } #renderTrip() { if (this.#isLoading) { this.#renderMessage({isLoading: true}); + this.#handleNewPointClick(); return; } @@ -81,7 +92,7 @@ export default class TripPointsPresenter { return; } - if (this.points.length === 0) { + if (this.points.length === 0 && !this.#isCreating) { this.#renderMessage(); return; } @@ -180,8 +191,8 @@ export default class TripPointsPresenter { destinationsModel: this.#destinationsModel, offersModel: this.#offersModel }); - const sortedEvents = sort[SortType.DAY](this.events); - this.#tripInfoPresenter.init(sortedEvents); + const sortedPoints = sort[SortType.DAY](this.points); + this.#tripInfoPresenter.init(sortedPoints); }; #clearTripInfo = () => { @@ -209,6 +220,7 @@ export default class TripPointsPresenter { case UpdateType.INIT: this.#isLoadingError = data.isError; this.#isLoading = false; + this.#handleNewPointDestroy(); this.#clearTrip(); this.#renderTrip(); this.#renderTripInfo(); diff --git a/src/presenters/utils.js b/src/presenters/utils.js index f48161a..6a95955 100644 --- a/src/presenters/utils.js +++ b/src/presenters/utils.js @@ -33,7 +33,7 @@ function firstLetterToLowerCase(type) { function isBigDifference(event1, event2) { return event1.price !== event2.price - || getEventDuration(event1.dateFrom, event1.dateTo) !== getEventDuration(event2.dateFrom, event2.dateTo); + || getPointDuration(event1.dateFrom, event1.dateTo) !== getPointDuration(event2.dateFrom, event2.dateTo); } function sortByDay(event1, event2) { @@ -156,24 +156,24 @@ const sort = { }; export { - isEventPast, - isEventPresent, - isEventFuture, - formatStringToDateTime, - formatStringToShortDate, - formatStringToTime, - getPointDuration, + adaptToClient, + adaptToServer, firstLetterToUpperCase, firstLetterToLowerCase, updateItem, isEscapeKey, + formatStringToDateTime, + formatStringToShortDate, + formatStringToTime, + getPointDuration, + sortByDay, sortByTime, sortByPrice, isBigDifference, filter, NoEventsTextType, - adaptToClient, - adaptToServer, - sortByDay, sort, getTripTitle, + sort, + getTripTitle, getTripDuration, - getTripCost}; + getTripCost + }; diff --git a/src/service/apiservice.js b/src/service/apiservice.js index 44736f6..0fcbfba 100644 --- a/src/service/apiservice.js +++ b/src/service/apiservice.js @@ -1,8 +1,8 @@ import ApiService from '../framework/api-service.js'; import { Method } from '../const.js'; -import { adaptToServer } from '../utils.js'; +import { adaptToServer } from '../utils/adapt.js'; -export default class pointApiService extends ApiService { +export default class EventsApiService extends ApiService { get events() { return this._load({url: 'points'}) .then(ApiService.parseResponse); @@ -30,4 +30,26 @@ export default class pointApiService extends ApiService { return parsedResponse; } + + async addEvent(update) { + const response = await this._load({ + url: 'points', + method: Method.POST, + body: JSON.stringify(adaptToServer(update)), + headers: new Headers({'Content-Type': 'application/json'}), + }); + + const parsedResponse = await ApiService.parseResponse(response); + + return parsedResponse; + } + + async deleteEvent(update) { + const response = await this._load({ + url: `points/${update.id}`, + method: Method.DELETE, + }); + + return response; + } } diff --git a/src/view/filter.js b/src/view/filter.js index 4576ed1..b7eee5f 100644 --- a/src/view/filter.js +++ b/src/view/filter.js @@ -4,11 +4,12 @@ import { firstLetterToUpperCase } from '../utils.js'; function createFilterItemElement(filter, currentFilter) { const {type, exists} = filter; return` -
- - -
`; +
+ + +
`; } + function createFilterElement(filterItems, currentFilter) { const filterItemsTemplate = filterItems.map((filter) => createFilterItemElement(filter, currentFilter)).join(''); return ` @@ -31,7 +32,7 @@ export default class FilterView extends AbstractView { this.element.addEventListener('change', this.#filterTypeChangeHandler); } - getTemplate() { + get template() { return createFilterElement(this.#filters, this.#currentFilter); } diff --git a/src/view/list.js b/src/view/list.js index ca4463f..a07bcf1 100644 --- a/src/view/list.js +++ b/src/view/list.js @@ -7,7 +7,7 @@ function createEventListViewTemplate() { } export default class PointListView extends AbstractView { - getTemplate() { + get template() { return createEventListViewTemplate(); } } diff --git a/src/view/modpoint.js b/src/view/modpoint.js index af79589..69154cf 100644 --- a/src/view/modpoint.js +++ b/src/view/modpoint.js @@ -98,6 +98,7 @@ function createModPointElement({point, pointDestination, pointOffers, pointType} + ${createResetButtonTemplate(eventType, isDeleting, isDisabled)} ${(pointType === EditType.EDITING) ? ' - - `; + `; } function createOffersTemplate({ offers, pointOffers }) { - const selectedOffers = pointOffers.filter((offer) => offers.includes(offer.id)); - return selectedOffers.reduce((result, current) => - `${result} -
  • - ${current.title} - +€  - ${current.price} -
  • - `, ''); + const offerItem = offers.map((offers) => pointOffers.includes(offers.id) ? ` +
  • + ${offers.title} + +€  + ${offers.price} +
  • ` : '').join(''); + return ``; } export default class PointView extends AbstractView { @@ -61,6 +58,7 @@ export default class PointView extends AbstractView { #offers = null; #onRollupClick = null; #onFavoriteClick = null; + constructor({ point, pointDestination, pointOffers, onRollupClick,onFavoriteClick }) { super(); this.#point = point; @@ -75,7 +73,7 @@ export default class PointView extends AbstractView { .addEventListener('click', this.#favoriteClickHandler); } - getTemplate() { + get Template() { return createPointViewTemplate({ point: this.#point, pointDestination: this.#destination, diff --git a/src/view/tripinfo.js b/src/view/tripinfo.js index f6c1641..8b8becd 100644 --- a/src/view/tripinfo.js +++ b/src/view/tripinfo.js @@ -3,7 +3,7 @@ import { getTripTitle, getTripDuration, getTripCost } from '../utils/trip-info.j function createTripInfoElement({ isEmpty, title, duration, cost}) { return `${isEmpty - ? '' + ? '
    ' : `