From 74f65abace49e5bb41f51ce8eee9b75676dc887d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B0=D1=81=D1=82=D0=B0=D1=81=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=A2=D0=BE=D0=BF=D0=BE=D1=80=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Sun, 14 Apr 2024 12:25:46 +0500 Subject: [PATCH 1/2] =?UTF-8?q?=D0=A8=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D0=B7=D0=B8=D1=80=D1=83=D0=B9=20=D1=82=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/const.js | 10 ++++++- src/main.js | 6 ++-- src/mock/filter.js | 11 ++++++++ src/presenter/filter-presenter.js | 19 +++++++++++++ src/presenter/trip-presenter.js | 6 ++++ src/utils.js | 22 ++++++++++++++- src/utils/filter.js | 11 ++++++++ src/view/empty-list-view.js | 16 +++++++++++ src/view/filter-view.js | 47 ++++++++++++++++++------------- 9 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 src/mock/filter.js create mode 100644 src/presenter/filter-presenter.js create mode 100644 src/utils/filter.js create mode 100644 src/view/empty-list-view.js diff --git a/src/const.js b/src/const.js index cc4c19a..2148d3e 100644 --- a/src/const.js +++ b/src/const.js @@ -59,6 +59,13 @@ const POINT_EMPTY = { type: DEFAULT_TYPE }; +const FilterType = { + EVERYTHING: 'everything', + FUTURE: 'future', + PRESENT: 'present', + PAST: 'past' +} + export { OFFER_COUNT, DESTINATION_COUNT, @@ -69,5 +76,6 @@ export { Price, TYPES, DEFAULT_TYPE, - POINT_EMPTY + POINT_EMPTY, + FilterType } diff --git a/src/main.js b/src/main.js index 22f2c77..04d7fa9 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,6 @@ import TripInfoView from './view/trip-info-view.js'; -import FilterView from './view/filter-view.js'; import TripPresenter from './presenter/trip-presenter.js'; +import FilterPresenter from './presenter/filter-presenter.js'; import MockService from './service/mock-service.js'; import DestinationsModel from './model/destinations-model.js'; import OffersModel from './model/offers-model.js'; @@ -10,6 +10,7 @@ import { render, RenderPosition } from './framework/render.js'; const tripInfoElement = document.querySelector('.trip-main'); const siteMainElement = document.querySelector('.page-main'); const eventListElement = siteMainElement.querySelector('.trip-events'); +const filterElement = tripInfoElement.querySelector('.trip-controls__filters'); const mockService = new MockService(); const destinationsModel = new DestinationsModel(mockService); @@ -17,8 +18,9 @@ const offersModel = new OffersModel(mockService); const pointsModel = new PointsModel(mockService); const tripPresenter = new TripPresenter({ tripContainer: eventListElement, destinationsModel, offersModel, pointsModel }); +const filterPresenter = new FilterPresenter({ container: filterElement, pointsModel }); render(new TripInfoView(), tripInfoElement, RenderPosition.AFTERBEGIN); -render(new FilterView(), tripInfoElement.querySelector('.trip-controls__filters')); tripPresenter.init(); +filterPresenter.init(); diff --git a/src/mock/filter.js b/src/mock/filter.js new file mode 100644 index 0000000..9e6881d --- /dev/null +++ b/src/mock/filter.js @@ -0,0 +1,11 @@ +import { filter } from "../utils/filter.js"; + +const generateFilters = (points) => { + return Object.entries(filter) + .map(([filterType, filterPoints]) => ({ + type: filterType, + hasPoints: filterPoints(points).length > 0 + })); +}; + +export { generateFilters }; diff --git a/src/presenter/filter-presenter.js b/src/presenter/filter-presenter.js new file mode 100644 index 0000000..f1812f1 --- /dev/null +++ b/src/presenter/filter-presenter.js @@ -0,0 +1,19 @@ +import FilterView from "../view/filter-view.js"; +import { render } from "../framework/render.js"; +import { generateFilters } from "../mock/filter.js"; + +export default class FilterPresenter { + #container = null; + #pointsModel = null; + #filters = []; + + constructor({ container, pointsModel }) { + this.#container = container; + this.#pointsModel = pointsModel; + this.#filters = generateFilters(this.#pointsModel.get()); + } + + init() { + render(new FilterView(this.#filters), this.#container); + } +} diff --git a/src/presenter/trip-presenter.js b/src/presenter/trip-presenter.js index d4c628a..9dcecbe 100644 --- a/src/presenter/trip-presenter.js +++ b/src/presenter/trip-presenter.js @@ -2,6 +2,7 @@ import SortView from '../view/sort-view.js'; import EditPointView from '../view/edit-point-view.js'; import PointView from '../view/point-view.js'; import TripView from '../view/point-list-view.js'; +import EmptyListView from '../view/empty-list-view.js'; import { render, replace } from '../framework/render.js'; export default class TripPresenter { @@ -23,6 +24,11 @@ export default class TripPresenter { } init() { + if (this.#points.length === 0) { + render(new EmptyListView(), this.#tripContainer); + return; + } + render(this.#sortComponent, this.#tripContainer); render(this.#pointListComponent, this.#tripContainer); diff --git a/src/utils.js b/src/utils.js index 9a0deaf..9575a4d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -62,6 +62,10 @@ function formatStringToTime(date) { return dayjs(date).format('HH:mm'); } +function capitalize(string) { + return `${string[0].toUpperCase()}${string.slice(1)}`; +} + function getPointDuration(dateFrom, dateTo) { const timeDiff = dayjs(dateTo).diff(dayjs(dateFrom)); @@ -82,6 +86,18 @@ function getPointDuration(dateFrom, dateTo) { return pointDuration; } +function isPointFuture(point) { + return dayjs().isBefore(point.dateFrom); +} + +function isPointPresent(point) { + return (dayjs().isAfter(point.dateFrom) && dayjs().isBefore(point.dateTo)); +} + +function isPointPast(point) { + return dayjs().isAfter(point.dateTo); +} + export { getDate, getRandomInteger, @@ -89,5 +105,9 @@ export { formatStringToDateTime, formatStringToShortDate, formatStringToTime, - getPointDuration + capitalize, + getPointDuration, + isPointFuture, + isPointPast, + isPointPresent } diff --git a/src/utils/filter.js b/src/utils/filter.js new file mode 100644 index 0000000..9c59dc1 --- /dev/null +++ b/src/utils/filter.js @@ -0,0 +1,11 @@ +import { FilterType } from "../const.js"; +import { isPointFuture, isPointPresent, isPointPast } from "../utils.js"; + +const filter = { + [FilterType.EVERYTHING]: (points) => [...points], + [FilterType.FUTURE]: (points) => points.filter((point) => isPointFuture(point)), + [FilterType.PRESENT]: (points) => points.filter((point) => isPointPresent(point)), + [FilterType.PAST]: (points) => points.filter((point) => isPointPast(point)) +}; + +export { filter }; diff --git a/src/view/empty-list-view.js b/src/view/empty-list-view.js new file mode 100644 index 0000000..3f8615e --- /dev/null +++ b/src/view/empty-list-view.js @@ -0,0 +1,16 @@ +import AbstractView from "../framework/view/abstract-view.js"; + +const createEmptyListViewTemplate = () => { + return ( + `
+

Trip events

+

Click New Event to create your first point

+
` + ); +} + +export default class EmptyListView extends AbstractView { + get template() { + return createEmptyListViewTemplate(); + } +} diff --git a/src/view/filter-view.js b/src/view/filter-view.js index dcc3181..1cf4221 100644 --- a/src/view/filter-view.js +++ b/src/view/filter-view.js @@ -1,32 +1,41 @@ import AbstractView from '../framework/view/abstract-view.js'; +import { capitalize } from '../utils.js'; -const createFilterTemplate = () => { +const createFilterItemsTemplate = ({ filters }) => { + const filterItems = filters.map(filter => { + return ( + `
+ + +
` + ) + }).join(''); + + return filterItems; +} + +const createFilterTemplate = ({ filters }) => { return ( `
-
- - -
-
- - -
-
- - -
-
- - -
- + ${createFilterItemsTemplate({ filters })} +
` ); } export default class FilterView extends AbstractView { + #filters = []; + + constructor(filters) { + super(); + this.#filters = filters; + } + get template() { - return createFilterTemplate(); + return createFilterTemplate({ + filters: this.#filters + }); } } From 32684eaf5f6983e61073c63157035a02688e7264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B0=D1=81=D1=82=D0=B0=D1=81=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=A2=D0=BE=D0=BF=D0=BE=D1=80=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Sun, 14 Apr 2024 16:21:10 +0500 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A8=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D0=B7=D0=B8=D1=80=D1=83=D0=B9=20=D1=82=D0=BE2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/const.js | 4 ++-- src/mock/filter.js | 2 +- src/presenter/filter-presenter.js | 6 +++--- src/utils.js | 4 ++-- src/utils/filter.js | 4 ++-- src/view/empty-list-view.js | 4 ++-- src/view/filter-view.js | 6 +++--- src/view/point-list-view.js | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/const.js b/src/const.js index 2148d3e..414d7d5 100644 --- a/src/const.js +++ b/src/const.js @@ -64,7 +64,7 @@ const FilterType = { FUTURE: 'future', PRESENT: 'present', PAST: 'past' -} +}; export { OFFER_COUNT, @@ -78,4 +78,4 @@ export { DEFAULT_TYPE, POINT_EMPTY, FilterType -} +}; diff --git a/src/mock/filter.js b/src/mock/filter.js index 9e6881d..d1dc4a8 100644 --- a/src/mock/filter.js +++ b/src/mock/filter.js @@ -1,4 +1,4 @@ -import { filter } from "../utils/filter.js"; +import { filter } from '../utils/filter.js'; const generateFilters = (points) => { return Object.entries(filter) diff --git a/src/presenter/filter-presenter.js b/src/presenter/filter-presenter.js index f1812f1..9c17249 100644 --- a/src/presenter/filter-presenter.js +++ b/src/presenter/filter-presenter.js @@ -1,6 +1,6 @@ -import FilterView from "../view/filter-view.js"; -import { render } from "../framework/render.js"; -import { generateFilters } from "../mock/filter.js"; +import FilterView from '../view/filter-view.js'; +import { render } from '../framework/render.js'; +import { generateFilters } from '../mock/filter.js'; export default class FilterPresenter { #container = null; diff --git a/src/utils.js b/src/utils.js index 9575a4d..54db7ef 100644 --- a/src/utils.js +++ b/src/utils.js @@ -10,7 +10,7 @@ const TimePeriods = { SEC_IN_MIN: 60, MIN_IN_HOUR: 60, HOUR_IN_DAY: 24 -} +}; const MSEC_IN_HOUR = TimePeriods.MIN_IN_HOUR * TimePeriods.SEC_IN_MIN * TimePeriods.MSEC_IN_SEC; const MSEC_IN_DAY = TimePeriods.HOUR_IN_DAY * MSEC_IN_HOUR; @@ -110,4 +110,4 @@ export { isPointFuture, isPointPast, isPointPresent -} +}; diff --git a/src/utils/filter.js b/src/utils/filter.js index 9c59dc1..1db606a 100644 --- a/src/utils/filter.js +++ b/src/utils/filter.js @@ -1,5 +1,5 @@ -import { FilterType } from "../const.js"; -import { isPointFuture, isPointPresent, isPointPast } from "../utils.js"; +import { FilterType } from '../const.js'; +import { isPointFuture, isPointPresent, isPointPast } from '../utils.js'; const filter = { [FilterType.EVERYTHING]: (points) => [...points], diff --git a/src/view/empty-list-view.js b/src/view/empty-list-view.js index 3f8615e..14ee290 100644 --- a/src/view/empty-list-view.js +++ b/src/view/empty-list-view.js @@ -1,4 +1,4 @@ -import AbstractView from "../framework/view/abstract-view.js"; +import AbstractView from '../framework/view/abstract-view.js'; const createEmptyListViewTemplate = () => { return ( @@ -7,7 +7,7 @@ const createEmptyListViewTemplate = () => {

Click New Event to create your first point

` ); -} +}; export default class EmptyListView extends AbstractView { get template() { diff --git a/src/view/filter-view.js b/src/view/filter-view.js index 1cf4221..a969897 100644 --- a/src/view/filter-view.js +++ b/src/view/filter-view.js @@ -9,11 +9,11 @@ const createFilterItemsTemplate = ({ filters }) => { ${(filter.hasPoints) ? '' : 'disabled'}> ` - ) + ); }).join(''); return filterItems; -} +}; const createFilterTemplate = ({ filters }) => { return ( @@ -22,7 +22,7 @@ const createFilterTemplate = ({ filters }) => { ` ); -} +}; export default class FilterView extends AbstractView { #filters = []; diff --git a/src/view/point-list-view.js b/src/view/point-list-view.js index 0efcfa4..ff0f932 100644 --- a/src/view/point-list-view.js +++ b/src/view/point-list-view.js @@ -4,7 +4,7 @@ const createPointListTemplate = () => { return ( `