From 1d34d4739fff231585d1a21c8e4700a9b830f1d5 Mon Sep 17 00:00:00 2001 From: June Date: Sun, 9 Jun 2024 21:22:33 +0500 Subject: [PATCH] fix --- package-lock.json | 2 +- src/Readme.md | 1 - src/const.js | 36 ++---- src/main.js | 16 +-- src/mock/filter.js | 8 -- src/mock/sort.js | 10 -- src/model/waypoint-model.js | 12 -- src/presenter/filter-presenter.js | 12 +- src/presenter/new-waypoint-presenter.js | 52 ++++---- src/presenter/waypoint-presenter.js | 88 ++++++------- src/presenter/waypoints-list-presenter.js | 69 +++++----- src/utils.js | 64 ++++----- src/view/editing-form-view.js | 150 +++++++++++----------- src/view/filter-view.js | 4 +- src/view/new-point-button-view.js | 4 +- src/view/sort-view.js | 4 +- src/view/waypoint-view.js | 12 +- 17 files changed, 252 insertions(+), 292 deletions(-) delete mode 100644 src/Readme.md delete mode 100644 src/mock/filter.js delete mode 100644 src/mock/sort.js diff --git a/package-lock.json b/package-lock.json index 3dce15b..55125ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "clean-webpack-plugin": "4.0.0", "dayjs": "1.11.6", - "flatpickr": "^4.6.13", + "flatpickr": "4.6.13", "he": "1.2.0", "html-webpack-plugin": "5.6.0" }, diff --git a/src/Readme.md b/src/Readme.md deleted file mode 100644 index 843d415..0000000 --- a/src/Readme.md +++ /dev/null @@ -1 +0,0 @@ -Папка для скриптов. diff --git a/src/const.js b/src/const.js index 1976c61..d3601d2 100644 --- a/src/const.js +++ b/src/const.js @@ -1,13 +1,13 @@ -const API_SRC = 'https://23.objects.htmlacademy.pro/big-trip'; -const AUTHORIZATION = 'Basic awdaf5g34123csdrh56w2r51'; +export const API_SRC = 'https://23.objects.htmlacademy.pro/big-trip'; +export const AUTHORIZATION = 'Basic awdaf5g34123csdrh56w2r51'; -const ACTIONS = { +export const ACTIONS = { UPDATE_POINT: 'update', ADD_POINT: 'add', DELETE_POINT: 'delete', }; -const UPDATE_TYPE = { +export const UPDATE_TYPE = { INIT: 'INIT', ERROR: 'ERROR', PATCH: 'PATCH', @@ -15,18 +15,18 @@ const UPDATE_TYPE = { MAJOR: 'MAJOR', }; -const DATE_FORMAT_EDIT = 'd/m/y H:i'; -const DATE_FORMAT_DAY = 'MMM DD'; -const DATE_FORMAT_HOURS = 'hh:mm'; +export const DATE_FORMAT_EDIT = 'd/m/y H:i'; +export const DATE_FORMAT_DAY = 'MMM DD'; +export const DATE_FORMAT_HOURS = 'hh:mm'; -const FILTER_TYPE = { +export const FILTER_TYPE = { EVERYTHING: 'everything', FUTURE: 'future', PRESENT: 'present', PAST: 'past', }; -const SORTING_TYPES = { +export const SORTING_TYPES = { DAY: 'day', EVENT: 'event', TIME: 'time', @@ -34,12 +34,12 @@ const SORTING_TYPES = { OFFERS: 'offers' }; -const TIME_LIMITS = { +export const TIME_LIMITS = { LOWER_LIMIT: 350, UPPER_LIMIT: 1000, }; -const EVENTS_MESSAGE = { +export const EVENTS_MESSAGE = { LOADING: 'Loading...', ERROR: 'Failed to load latest route information' }; @@ -50,17 +50,3 @@ export const FILTER_TYPE_MESSAGE = { PRESENT: 'There are no present events now', PAST: 'There are no past events now', }; - -export { - API_SRC, - AUTHORIZATION, - DATE_FORMAT_EDIT, - DATE_FORMAT_DAY, - DATE_FORMAT_HOURS, - FILTER_TYPE, - SORTING_TYPES, - ACTIONS, - UPDATE_TYPE, - TIME_LIMITS, - EVENTS_MESSAGE -}; diff --git a/src/main.js b/src/main.js index c1540c2..c50ef33 100644 --- a/src/main.js +++ b/src/main.js @@ -1,21 +1,20 @@ import {render, RenderPosition} from './framework/render.js'; import WaypointsListPresenter from './presenter/waypoints-list-presenter.js'; import WaypointsModel from './model/waypoint-model.js'; -import {getMockFilters} from './mock/filter.js'; -import {getMockSorts} from './mock/sort.js'; import FilterPresenter from './presenter/filter-presenter'; import FilterModel from './model/filter-model'; import NewPointButtonView from './view/new-point-button-view'; import WaypointsService from './service/waypoints-service'; import {API_SRC, AUTHORIZATION} from './const'; +import {getFilters, getSorts} from './utils'; + +const filters = getFilters(); +const sorts = getSorts(); const mainContainer = document.querySelector('.trip-main'); const filterContainer = document.querySelector('.trip-controls__filters'); const eventContainer = document.querySelector('.trip-events'); -const mockFilters = getMockFilters(); -const mockSorts = getMockSorts(); - const waypointsModel = new WaypointsModel({ waypointsService: new WaypointsService(API_SRC, AUTHORIZATION) }); @@ -26,7 +25,7 @@ const filterPresenter = new FilterPresenter({ filterContainer, filterModel, waypointsModel, - filters: mockFilters + filters }); const newPointButtonComponent = new NewPointButtonView({ @@ -42,12 +41,11 @@ const eventPresenter = new WaypointsListPresenter({ eventContainer, waypointsModel, filterModel, - sorts: mockSorts, - filters: mockFilters, + sorts, + filters, onNewPointDestroy: handleNewPointFormClose }); - function handleNewPointButtonClick() { eventPresenter.createWaypoint(); newPointButtonComponent.element.disabled = true; diff --git a/src/mock/filter.js b/src/mock/filter.js deleted file mode 100644 index 83a18c8..0000000 --- a/src/mock/filter.js +++ /dev/null @@ -1,8 +0,0 @@ -import {filters} from '../utils'; - -export function getMockFilters() { - return Object.entries(filters).map(([name, getPoints]) => ({ - name, - getPoints, - })); -} diff --git a/src/mock/sort.js b/src/mock/sort.js deleted file mode 100644 index f2efad7..0000000 --- a/src/mock/sort.js +++ /dev/null @@ -1,10 +0,0 @@ -import {sorts} from '../utils'; -import {SORTING_TYPES} from '../const'; - -export function getMockSorts() { - return Object.entries(sorts).map(([name, getPoints]) => ({ - name, - getPoints, - isDisabled: name === SORTING_TYPES.EVENT || name === SORTING_TYPES.OFFERS - })); -} diff --git a/src/model/waypoint-model.js b/src/model/waypoint-model.js index 82e2f34..d8d8899 100644 --- a/src/model/waypoint-model.js +++ b/src/model/waypoint-model.js @@ -24,18 +24,6 @@ export default class WaypointsModel extends Observable { return this.offers; } - getWaypoint(id) { - return this.waypoints.find((waypoint) => waypoint.id === id); - } - - setWaypoints(waypoints) { - this.waypoints = waypoints; - } - - setWaypoint(waypoint, id) { - this.waypoints = [...this.waypoints.filter((other) => other.id !== id), waypoint]; - } - async init() { try { const waypoints = await this.#waypointsService.events; diff --git a/src/presenter/filter-presenter.js b/src/presenter/filter-presenter.js index 2d60ebc..f12425c 100644 --- a/src/presenter/filter-presenter.js +++ b/src/presenter/filter-presenter.js @@ -3,12 +3,12 @@ import FilterView from '../view/filter-view'; import {FILTER_TYPE} from '../const'; export default class FilterPresenter { - #filterContainer; - #filters; #filterComponent = null; + #waypoints = null; #filterModel; #waypointsModel; - #waypoints = null; + #filterContainer; + #filters; constructor({filterContainer, filterModel, waypointsModel, filters}) { this.#filterContainer = filterContainer; @@ -32,9 +32,7 @@ export default class FilterPresenter { const prevFilterComponent = this.#filterComponent; this.#filterComponent = new FilterView({ - filters: this.filters, - type: this.#filterModel.filter, - onChange: this.#handleTypeChange + filters: this.filters, type: this.#filterModel.filter, onChange: this.#onChangeType }); if (prevFilterComponent === null) { @@ -48,7 +46,7 @@ export default class FilterPresenter { render(this.#filterComponent, this.#filterContainer); } - #handleTypeChange = (type) => { + #onChangeType = (type) => { if (this.#filterModel.filter === type) { return; } diff --git a/src/presenter/new-waypoint-presenter.js b/src/presenter/new-waypoint-presenter.js index 04d6eb5..24a70aa 100644 --- a/src/presenter/new-waypoint-presenter.js +++ b/src/presenter/new-waypoint-presenter.js @@ -4,10 +4,10 @@ import EditingFormView from '../view/editing-form-view'; import {isEscape} from '../utils'; export default class NewWaypointPresenter { + #newWaypointComponent = null; #offers; #destinations; #pointListContainer; - #newWaypointComponent = null; #handleDataChange; #handleDestroy; #closeAllEditForms; @@ -21,6 +21,23 @@ export default class NewWaypointPresenter { this.#closeAllEditForms = closeAllEditForms; } + setSavingStatus() { + this.#newWaypointComponent.updateElement({ + isSaving: true, + }); + } + + setAbortingStatus() { + const resetFormState = () => { + this.#newWaypointComponent.updateElement({ + isSaving: false, + isDeleting: false, + }); + }; + + this.#newWaypointComponent.shake(resetFormState); + } + init() { if (this.#newWaypointComponent !== null) { return; @@ -32,13 +49,13 @@ export default class NewWaypointPresenter { offers: this.#offers, destinations: this.#destinations, waypoint: {type: 'flight', destination: '', basePrice: 0, offers: [], isFavorite: false}, - onFormSubmit: (newWaypoint) => this.#handleSaveClick(newWaypoint), - onClose: () => this.#handleCancelClick(), - onDelete: this.#handleCancelClick + onFormSubmit: (newWaypoint) => this.#onSave(newWaypoint), + onClose: () => this.#onCancel(), + onDelete: this.#onCancel }); render(this.#newWaypointComponent, this.#pointListContainer, RenderPosition.AFTERBEGIN); - document.addEventListener('keydown', this.#escKeyDownHandler); + document.addEventListener('keydown', this.#onEscKeyDown); } destroy() { @@ -51,38 +68,21 @@ export default class NewWaypointPresenter { remove(this.#newWaypointComponent); this.#newWaypointComponent = null; - document.removeEventListener('keydown', this.#escKeyDownHandler); - } - - setSavingStatus() { - this.#newWaypointComponent.updateElement({ - isSaving: true, - }); - } - - setAbortingStatus() { - const resetFormState = () => { - this.#newWaypointComponent.updateElement({ - isSaving: false, - isDeleting: false, - }); - }; - - this.#newWaypointComponent.shake(resetFormState); + document.removeEventListener('keydown', this.#onEscKeyDown); } - #handleSaveClick = (waypoint) => { + #onSave = (waypoint) => { this.#handleDataChange(USER_ACTION.ADD_POINT, UPDATE_TYPE.MAJOR, { ...waypoint, isFavorite: false }); }; - #handleCancelClick = () => { + #onCancel = () => { this.destroy(); }; - #escKeyDownHandler = (evt) => { + #onEscKeyDown = (evt) => { if (isEscape(evt.key)) { evt.preventDefault(); this.destroy(); diff --git a/src/presenter/waypoint-presenter.js b/src/presenter/waypoint-presenter.js index 86d5174..5b1cfbc 100644 --- a/src/presenter/waypoint-presenter.js +++ b/src/presenter/waypoint-presenter.js @@ -28,6 +28,38 @@ export default class WaypointPresenter { this.init(this.#waypoint); } + setSavingStatus() { + if (this.#isEdit) { + this.#editComponent.updateElement({ + isLoading: true, + }); + } + } + + setDeletingStatus() { + if (this.#isEdit) { + this.#editComponent.updateElement({ + isDeleting: true, + }); + } + } + + setAbortingStatus() { + if (!this.#isEdit) { + this.#waypointComponent.shake(); + return; + } + + const resetFormState = () => { + this.#editComponent.updateElement({ + isLoading: false, + isDeleting: false, + }); + }; + + this.#editComponent.shake(resetFormState); + } + init(waypoint) { this.#waypoint = waypoint; @@ -39,16 +71,16 @@ export default class WaypointPresenter { offers: this.#offers, waypoint: waypoint, onEditClick: () => this.openForm(), - onFavoriteClick: () => this.#handleFavoriteClick() + onFavoriteClick: () => this.#onClickFavorite() }); this.#editComponent = new EditingFormView({ offers: this.#offers, destinations: this.#destinations, waypoint: waypoint, - onFormSubmit: (newWaypoint) => this.#handleSaveClick(newWaypoint), + onFormSubmit: (newWaypoint) => this.#onSave(newWaypoint), onClose: () => this.closeForm(), - onDelete: this.#handleDeleteClick + onDelete: this.#onDelete }); if (!prevWaypointComponent || !prevEditComponent) { @@ -69,7 +101,7 @@ export default class WaypointPresenter { openForm() { this.#closeAllEditForms(); replace(this.#editComponent, this.#waypointComponent); - document.addEventListener('keydown', this.#escKeyDownHandler); + document.addEventListener('keydown', this.#onEscKeyDown); this.#isEdit = true; } @@ -77,44 +109,17 @@ export default class WaypointPresenter { if (this.#isEdit) { this.#editComponent.reset(this.#waypoint); replace(this.#waypointComponent, this.#editComponent); - document.removeEventListener('keydown', this.#escKeyDownHandler); + document.removeEventListener('keydown', this.#onEscKeyDown); this.#isEdit = false; } } - setSavingStatus() { - if (this.#isEdit) { - this.#editComponent.updateElement({ - isLoading: true, - }); - } - } - - setDeletingStatus() { - if (this.#isEdit) { - this.#editComponent.updateElement({ - isDeleting: true, - }); - } - } - - setAbortingStatus() { - if (!this.#isEdit) { - this.#waypointComponent.shake(); - return; - } - - const resetFormState = () => { - this.#editComponent.updateElement({ - isLoading: false, - isDeleting: false, - }); - }; - - this.#editComponent.shake(resetFormState); + destroy() { + remove(this.#waypointComponent); + remove(this.#editComponent); } - #escKeyDownHandler = (evt) => { + #onEscKeyDown = (evt) => { if (isEscape(evt.key)) { evt.preventDefault(); this.#editComponent.reset(this.#waypoint); @@ -122,7 +127,7 @@ export default class WaypointPresenter { } }; - #handleFavoriteClick = () => { + #onClickFavorite = () => { this.#onChange( USER_ACTION.UPDATE_POINT, UPDATE_TYPE.MINOR, @@ -130,7 +135,7 @@ export default class WaypointPresenter { ); }; - #handleSaveClick = (waypoint) => { + #onSave = (waypoint) => { this.#onChange( USER_ACTION.UPDATE_POINT, UPDATE_TYPE.MINOR, @@ -138,12 +143,7 @@ export default class WaypointPresenter { ); }; - destroy() { - remove(this.#waypointComponent); - remove(this.#editComponent); - } - - #handleDeleteClick = (point) => { + #onDelete = (point) => { this.#onChange( USER_ACTION.DELETE_POINT, UPDATE_TYPE.MINOR, diff --git a/src/presenter/waypoints-list-presenter.js b/src/presenter/waypoints-list-presenter.js index d278cc6..8d9445a 100644 --- a/src/presenter/waypoints-list-presenter.js +++ b/src/presenter/waypoints-list-presenter.js @@ -5,6 +5,7 @@ import WaypointPresenter from './waypoint-presenter'; import { ACTIONS as USER_ACTION, EVENTS_MESSAGE, + FILTER_TYPE, FILTER_TYPE_MESSAGE, SORTING_TYPES, TIME_LIMITS, @@ -54,8 +55,8 @@ export default class WaypointsListPresenter { init() { this.renderWaypoints(); - this.#filterModel.addObserver(this.#handleFilterTypeChange.bind(this)); - this.waypointsModel.addObserver(this.#handleModelEvent); + this.#filterModel.addObserver(this.#onFilterTypeChange.bind(this)); + this.waypointsModel.addObserver(this.#onModelEvent); } createWaypoint() { @@ -63,11 +64,13 @@ export default class WaypointsListPresenter { destinations: this.waypointsModel.getDestinations(), offers: this.waypointsModel.getOffers(), pointListContainer: this.#eventListContainer.element, - onDataChange: this.#handleWaypointChange, + onDataChange: this.#onChangeWaypoint, onDestroy: this.#onNewPointDestroy, closeAllEditForms: () => this.#closeAllEditForms(), }); + this.#filterModel.setFilter(FILTER_TYPE.EVERYTHING); + this.#sortWaypoints(this.#sorts[0].name); this.#newPointPresenter.init(); } @@ -96,7 +99,7 @@ export default class WaypointsListPresenter { this.#sortsComponent = new SortView({ sorts: this.#sorts, currentSort: this.#currentSortType, - onChange: this.#handleSortTypeChange + onChange: this.#onSortTypeChange }); this.#renderInfo(); @@ -104,20 +107,6 @@ export default class WaypointsListPresenter { filteredPoints.forEach((waypoint) => this.#renderWaypoint(waypoint)); } - #renderInfo() { - const route = getRoute( - this.#sortWaypoints(SORTING_TYPES.DAY, this.waypointsModel.getWaypoints()), - this.waypointsModel.destinations - ); - this.#infoComponent = new InfoView({ - route: route.route, - routeDates: route.routeDates, - totalPrice: getTotalPrice(this.waypointsModel.getWaypoints(), this.waypointsModel.offers), - }); - - render(this.#infoComponent, this.#mainContainer, RenderPosition.AFTERBEGIN); - } - reset() { this.#waypointPresenters.forEach((waypointPresenter) => waypointPresenter.destroy()); this.#waypointPresenters = []; @@ -137,6 +126,10 @@ export default class WaypointsListPresenter { if (this.#emptyComponent) { remove(this.#emptyComponent); } + + if (this.#newPointPresenter) { + this.#newPointPresenter.destroy(); + } } #closeAllEditForms() { @@ -147,7 +140,7 @@ export default class WaypointsListPresenter { this.#waypointPresenters.forEach((waypoint) => waypoint.closeForm()); } - #handleWaypointChange = async (action, type, waypoint) => { + #onChangeWaypoint = async (action, type, waypoint) => { this.#uiBlocker.block(); switch (action) { case USER_ACTION.ADD_POINT: @@ -186,7 +179,7 @@ export default class WaypointsListPresenter { offers: this.waypointsModel.getOffers(), containerElement: this.#eventListContainer.element, closeAllEditForms: () => this.#closeAllEditForms(), - onChange: this.#handleWaypointChange + onChange: this.#onChangeWaypoint }); waypointPresenter.init(waypoint); this.#waypointPresenters.push(waypointPresenter); @@ -201,14 +194,19 @@ export default class WaypointsListPresenter { ); } - #handleSortTypeChange = (sortType) => { - if (sortType === this.#currentSortType) { - return; - } - this.#sortWaypoints(sortType); - this.#deleteWaypoints(); - this.waypointsModel.getWaypoints().forEach((waypoint) => this.#renderWaypoint(waypoint)); - }; + #renderInfo() { + const route = getRoute( + this.#sortWaypoints(SORTING_TYPES.DAY, this.waypointsModel.getWaypoints()), + this.waypointsModel.destinations + ); + this.#infoComponent = new InfoView({ + route: route.route, + routeDates: route.routeDates, + totalPrice: getTotalPrice(this.waypointsModel.getWaypoints(), this.waypointsModel.offers), + }); + + render(this.#infoComponent, this.#mainContainer, RenderPosition.AFTERBEGIN); + } #sortWaypoints(sortType) { const sortedWaypoints = this.#sorts.find((sort) => sort.name === sortType).getPoints(this.waypointsModel.getWaypoints()); @@ -225,13 +223,23 @@ export default class WaypointsListPresenter { this.#waypointPresenters = []; } - #handleFilterTypeChange() { + #onSortTypeChange = (sortType) => { + if (sortType === this.#currentSortType) { + return; + } + + this.#sortWaypoints(sortType); + this.#deleteWaypoints(); + this.waypointsModel.getWaypoints().forEach((waypoint) => this.#renderWaypoint(waypoint)); + }; + + #onFilterTypeChange() { this.reset(); this.#currentSortType = SORTING_TYPES.DAY; this.renderWaypoints(); } - #handleModelEvent = (updateType, data) => { + #onModelEvent = (updateType, data) => { switch (updateType) { case UPDATE_TYPE.PATCH: this.#waypointPresenters.get(data.id).init(data); @@ -242,6 +250,7 @@ export default class WaypointsListPresenter { break; case UPDATE_TYPE.MAJOR: this.#currentSortType = SORTING_TYPES.DAY; + this.#sortWaypoints(this.#currentSortType); this.reset(); this.renderWaypoints(); break; diff --git a/src/utils.js b/src/utils.js index e32a08a..f6b959d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,36 +1,37 @@ import dayjs from 'dayjs'; import {FILTER_TYPE, SORTING_TYPES} from './const'; -function humanizeWaypointDueDate(dueDate, format) { +export function humanizeWaypointDueDate(dueDate, format) { return dueDate ? dayjs(dueDate).format(format) : ''; } -function countDuration(dateFrom, dateTo) { +export function countDuration(dateFrom, dateTo) { return dayjs(dateTo).diff(dateFrom, 'm'); } -function formatDuration(minutes) { +export function formatDuration(minutes) { const days = Math.floor(minutes / 24 / 60); const hours = Math.floor(minutes / 60) - (days * 24); minutes = minutes - hours * 60 - days * 60 * 24; let result = ''; if (days > 0) { - result += `${days}D `; + result = `${days}D ${hours}H ${minutes}M`; + } else { + if (hours > 0) { + result += `${hours}H `; + } + result += `${minutes}M`; } - if (hours > 0) { - result += `${hours}H `; - } - result += `${minutes}M`; + return result; } -function isEscape(key) { +export function isEscape(key) { return key === 'Escape' || key === 'Esc'; } -export const formatDate = (date, formatPattern) => - date ? dayjs(date).format(formatPattern) : ''; +export const formatDate = (date, formatPattern) => date ? dayjs(date).format(formatPattern) : ''; export const getRoute = (events, destinations) => { let route = ''; @@ -50,30 +51,26 @@ export const getRoute = (events, destinations) => { .map((event) => destinations.find((destination) => destination.id === event.destination).name) .join(' — '); - return { route, routeDates }; + return {route, routeDates}; } const firstRoutePoint = destinations.find((destination) => destination.id === firstEvent.destination); const lastRoutePoint = destinations.find((destination) => destination.id === lastEvent.destination); route = `${firstRoutePoint.name} — ... — ${lastRoutePoint.name}`; - return { route, routeDates }; + return {route, routeDates}; }; export const getOfferById = (offers, type, id) => offers - .find((offer) => offer.type === type) - .offers.find((item) => item.id === id); - -export const getTotalEventPrice = (event, offers) => event.basePrice + - event.offers.reduce( - (sum, offer) => sum + getOfferById(offers, event.type, offer).price, - 0 - ); + .find((offer) => offer.type === type).offers + .find((item) => item.id === id); + +export const getTotalEventPrice = (event, offers) => + event.basePrice + event.offers.reduce((sum, offer) => sum + getOfferById(offers, event.type, offer).price, 0); export const getTotalPrice = (events, offers) => events.reduce((sum, event) => sum + getTotalEventPrice(event, offers), 0); - const filters = { [FILTER_TYPE.EVERYTHING]: (points) => points.filter((point) => point), [FILTER_TYPE.FUTURE]: (points) => points.filter((point) => new Date(point.dateFrom) > new Date()), @@ -81,6 +78,13 @@ const filters = { [FILTER_TYPE.PAST]: (points) => points.filter((point) => new Date(point.dateTo) < new Date()), }; +export function getFilters() { + return Object.entries(filters).map(([name, getPoints]) => ({ + name, + getPoints, + })); +} + const sorts = { [SORTING_TYPES.DAY]: (points) => points.sort((pointA, pointB) => new Date(pointA.dateFrom) - new Date(pointB.dateFrom)), [SORTING_TYPES.EVENT]: (points) => points, @@ -89,12 +93,10 @@ const sorts = { [SORTING_TYPES.OFFERS]: (points) => points, }; - -export { - humanizeWaypointDueDate, - countDuration, - formatDuration, - isEscape, - filters, - sorts -}; +export function getSorts() { + return Object.entries(sorts).map(([name, getPoints]) => ({ + name, + getPoints, + isDisabled: name === SORTING_TYPES.EVENT || name === SORTING_TYPES.OFFERS + })); +} diff --git a/src/view/editing-form-view.js b/src/view/editing-form-view.js index b0f5bdd..121c5c6 100644 --- a/src/view/editing-form-view.js +++ b/src/view/editing-form-view.js @@ -159,14 +159,14 @@ function createEditingFormTemplate(allDestinations, allOffers, editMode, { } export default class EditingFormView extends AbstractStatefulView { + #datepickerFrom = null; + #datepickerTo = null; #onFormSubmit; #onClose; #offers; #destinations; #onDelete; #editMode; - #datepickerFrom = null; - #datepickerTo = null; constructor({offers, destinations, waypoint, onFormSubmit, onClose, onDelete}) { super(); @@ -204,21 +204,79 @@ export default class EditingFormView extends AbstractStatefulView { } } + #initDatepickerFrom = () => { + this.#datepickerFrom = flatpickr( + this.element.querySelector('#event-start-time-1'), + { + ['time_24hr']: true, + dateFormat: DATE_FORMAT_EDIT, + defaultDate: this._state.dateFrom, + enableTime: true, + onChange: this.#onCloseDateFrom, + } + ); + }; + + #initDatepickerTo = () => { + this.#datepickerTo = flatpickr( + this.element.querySelector('#event-end-time-1'), + { + ['time_24hr']: true, + dateFormat: 'd/m/y H:i', + defaultDate: this._state.dateTo, + minDate: this.#datepickerFrom.selectedDates[0], + enableTime: true, + onChange: this.#onCloseDateTo, + } + ); + }; + + #parseEventToState = (event) => ({ + ...event, + isSaving: false, + isDeleting: false, + }); + + #parseStateToEvent = (state) => { + const event = {...state}; + delete event.isSaving; + delete event.isDeleting; + return event; + }; + + _restoreHandlers() { + this.element.querySelector('.event--edit').addEventListener('submit', this.#onSubmit); + this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#onCloseForm); + this.element.querySelectorAll('.event__type-input').forEach((element) => { + element.addEventListener('click', this.#onChangeType); + }); + this.element.querySelector('.event__input--destination').addEventListener('input', this.#onChangeDestination); + this.element.querySelector('.event__input--price').addEventListener('change', this.#onChangePrice); + this.element.querySelector('.event__input--price').addEventListener('keypress', this.#onKeydownPrice); + this.element.querySelectorAll('.event__offer-checkbox').forEach((element) => { + element.addEventListener('click', this.#onChangeOffers); + }); + this.element.querySelector('.event__reset-btn').addEventListener('click', this.#onDeleteForm); + + this.#initDatepickerFrom(); + this.#initDatepickerTo(); + } + #getEditMode() { return this._state.id ? ACTIONS.UPDATE_POINT : ACTIONS.ADD_POINT; } - #closeFormHandler = (event) => { + #onCloseForm = (event) => { event.preventDefault(); this.#onClose(); }; - #submitFormHandler = (evt) => { + #onSubmit = (evt) => { evt.preventDefault(); this.#onFormSubmit(this.#parseStateToEvent(this._state)); }; - #changeTypeHandler = (evt) => { + #onChangeType = (evt) => { evt.preventDefault(); this._state.type = evt.target.value; this.updateElement({ @@ -226,7 +284,7 @@ export default class EditingFormView extends AbstractStatefulView { }); }; - #changeDestinationHandler = (evt) => { + #onChangeDestination = (evt) => { evt.preventDefault(); if (this.#destinations.find((destination) => destination.name === evt.target.value)) { this._state.destination = this.#destinations.find((destination) => destination.name === evt.target.value).id; @@ -236,7 +294,7 @@ export default class EditingFormView extends AbstractStatefulView { } }; - #changePriceHandler = (event) => { + #onChangePrice = (event) => { event.preventDefault(); this._state.basePrice = parseInt(event.target.value, 10); this.updateElement({ @@ -244,22 +302,13 @@ export default class EditingFormView extends AbstractStatefulView { }); }; - #keydownPriceHandler = (event) => { + #onKeydownPrice = (event) => { if (!/[0-9]/.test(event.key)) { event.preventDefault(); } }; - #dateFromCloseHandler = ([userDate]) => { - this._setState({dateFrom: userDate}); - this.#initDatepickerTo(); - }; - - #dateToCloseHandler = ([userDate]) => { - this._setState({dateTo: userDate}); - }; - - #changeOffersHandler = (event) => { + #onChangeOffers = (event) => { event.preventDefault(); const offers = []; this.element.querySelectorAll('.event__offer-checkbox:checked').forEach((element) => { @@ -271,66 +320,17 @@ export default class EditingFormView extends AbstractStatefulView { }); }; - #deleteFromHandler = (event) => { - event.preventDefault(); - this.#onDelete(this.#parseStateToEvent(this.editingForm)); - }; - - #initDatepickerFrom = () => { - this.#datepickerFrom = flatpickr( - this.element.querySelector('#event-start-time-1'), - { - ['time_24hr']: true, - dateFormat: DATE_FORMAT_EDIT, - defaultDate: this._state.dateFrom, - enableTime: true, - onChange: this.#dateFromCloseHandler, - } - ); + #onCloseDateFrom = ([userDate]) => { + this._setState({dateFrom: userDate}); + this.#initDatepickerTo(); }; - #initDatepickerTo = () => { - this.#datepickerTo = flatpickr( - this.element.querySelector('#event-end-time-1'), - { - ['time_24hr']: true, - dateFormat: 'd/m/y H:i', - defaultDate: this._state.dateTo, - minDate: this.#datepickerFrom.selectedDates[0], - enableTime: true, - onChange: this.#dateToCloseHandler, - } - ); + #onCloseDateTo = ([userDate]) => { + this._setState({dateTo: userDate}); }; - #parseEventToState = (event) => ({ - ...event, - isSaving: false, - isDeleting: false, - }); - - #parseStateToEvent = (state) => { - const event = {...state}; - delete event.isSaving; - delete event.isDeleting; - return event; + #onDeleteForm = (event) => { + event.preventDefault(); + this.#onDelete(this.#parseStateToEvent(this.editingForm)); }; - - _restoreHandlers() { - this.element.querySelector('.event--edit').addEventListener('submit', this.#submitFormHandler); - this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#closeFormHandler); - this.element.querySelectorAll('.event__type-input').forEach((element) => { - element.addEventListener('click', this.#changeTypeHandler); - }); - this.element.querySelector('.event__input--destination').addEventListener('input', this.#changeDestinationHandler); - this.element.querySelector('.event__input--price').addEventListener('change', this.#changePriceHandler); - this.element.querySelector('.event__input--price').addEventListener('keypress', this.#keydownPriceHandler); - this.element.querySelectorAll('.event__offer-checkbox').forEach((element) => { - element.addEventListener('click', this.#changeOffersHandler); - }); - this.element.querySelector('.event__reset-btn').addEventListener('click', this.#deleteFromHandler); - - this.#initDatepickerFrom(); - this.#initDatepickerTo(); - } } diff --git a/src/view/filter-view.js b/src/view/filter-view.js index 080ec05..f23386f 100644 --- a/src/view/filter-view.js +++ b/src/view/filter-view.js @@ -34,14 +34,14 @@ export default class FilterView extends AbstractView { this.#type = type; this.#handleTypeChange = onChange; - this.element.addEventListener('click', this.#typeChangeHandler); + this.element.addEventListener('click', this.#onChangeType); } get template() { return createFilterTemplate(this.#filters, this.#type); } - #typeChangeHandler = (event) => { + #onChangeType = (event) => { if (event.target.classList.contains('trip-filters__filter-input')) { this.#handleTypeChange(event.target.value); } diff --git a/src/view/new-point-button-view.js b/src/view/new-point-button-view.js index d94f37b..05944a2 100644 --- a/src/view/new-point-button-view.js +++ b/src/view/new-point-button-view.js @@ -10,14 +10,14 @@ export default class NewPointButtonView extends AbstractView { constructor({onClick}) { super(); this.#handleClick = onClick; - this.element.addEventListener('click', this.#clickHandler); + this.element.addEventListener('click', this.#onClick); } get template() { return createNewPointButtonTemplate(); } - #clickHandler = (evt) => { + #onClick = (evt) => { evt.preventDefault(); this.#handleClick(); }; diff --git a/src/view/sort-view.js b/src/view/sort-view.js index 6e3ea06..b5161d1 100644 --- a/src/view/sort-view.js +++ b/src/view/sort-view.js @@ -34,14 +34,14 @@ export default class SortView extends AbstractView { this.#currentSort = currentSort; this.#handleTypeChange = onChange; - this.element.addEventListener('click', this.#changeTypeHandler); + this.element.addEventListener('click', this.#onChangeType); } get template() { return createSortTemplate(this.#sorts, this.#currentSort); } - #changeTypeHandler = (evt) => { + #onChangeType = (evt) => { if (evt.target.classList.contains('trip-sort__input')) { this.#handleTypeChange(evt.target.dataset.sortType); } diff --git a/src/view/waypoint-view.js b/src/view/waypoint-view.js index 7a72e3b..95cea10 100644 --- a/src/view/waypoint-view.js +++ b/src/view/waypoint-view.js @@ -29,9 +29,7 @@ function createWaypointTemplate(destinations, allOffers, { const destinationObject = destinations.find((dest) => dest.id === destination); const offersObject = allOffers.find((offer) => offer.type === type)?.offers.filter((offer) => offers.includes(offer.id)); - const favoriteClassName = isFavorite - ? 'event__favorite-btn--active' - : ''; + const favoriteClassName = isFavorite ? 'event__favorite-btn--active' : ''; return `
  • @@ -84,20 +82,20 @@ export default class WaypointView extends AbstractView { this.#handleEditClick = onEditClick; this.#handleFavoriteClick = onFavoriteClick; - this.element.querySelector('.event__rollup-btn').onclick = this.#editClickHandler; - this.element.querySelector('.event__favorite-btn').onclick = this.#favoriteClickHandler; + this.element.querySelector('.event__rollup-btn').onclick = this.#onEdit; + this.element.querySelector('.event__favorite-btn').onclick = this.#onClickFavorite; } get template() { return createWaypointTemplate(this.#destinations, this.#offers, this.waypoint); } - #editClickHandler = (event) => { + #onEdit = (event) => { event.preventDefault(); this.#handleEditClick(); }; - #favoriteClickHandler = (event) => { + #onClickFavorite = (event) => { event.preventDefault(); this.#handleFavoriteClick(); };