Skip to content

Commit

Permalink
Merge pull request #3 from ershegm/module4-task2
Browse files Browse the repository at this point in the history
Module4 task2
  • Loading branch information
ershegm authored Apr 14, 2024
2 parents c5f9b9f + c3b08e7 commit ce2288a
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 81 deletions.
18 changes: 0 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions src/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,60 @@ const DurationFormat = {
MINS: 'mm[M]',
};

const FilterType = {
ANY: 'any',
FUTURE: 'future',
PRESENT: 'present',
PAST: 'past'
};

const SortType = {
DAY: 'day',
EVENT: 'event',
TIME: 'time',
PRICE: 'price',
OFFER: 'offer',
};

const FilterSettings = {
[FilterType.ANY]: {
label: 'Everything',
defaultSelected: true,
},
[FilterType.FUTURE]: { label: 'Future' },
[FilterType.PRESENT]: { label: 'Present' },
[FilterType.PAST]: { label: 'Past' },
};

const SORTING_COLUMNS = [
{
type: SortType.DAY,
label: 'Day',
active: true,
defaultSelected: true,
},
{
type: SortType.EVENT,
label: 'Event',
active: false,
},
{
type: SortType.TIME,
label: 'Time',
active: true,
},
{
type: SortType.PRICE,
label: 'Price',
active: true,
},
{
type: SortType.OFFER,
label: 'Offer',
active: false,
},
];

export {
POINTS_COUNT,
MSEC_IN_SEC,
Expand All @@ -78,4 +132,8 @@ export {
MocksMaxCount,
DateFormat,
DurationFormat,
FilterType,
FilterSettings,
SortType,
SORTING_COLUMNS,
};
2 changes: 1 addition & 1 deletion src/framework/api-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class ApiService {
/**
* Метод для обработки ответа
* @param {Response} response Объект ответа
* @returns {Promise}
* @returns {Promise<JSON>}
*/
static parseResponse(response) {
return response.json();
Expand Down
6 changes: 3 additions & 3 deletions src/framework/ui-blocker/ui-blocker.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
.ui-blocker {
display: none;
place-content: center;
position: fixed;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
min-width: 100%;
min-height: 100%;
z-index: 1000;
cursor: wait;
background-color: rgba(255, 255, 255, 0.5);
Expand Down
3 changes: 3 additions & 0 deletions src/framework/view/abstract-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export default class AbstractView {
/** @type {HTMLElement|null} Элемент представления */
#element = null;

/** @type {Object} Объект с колбэками. Может использоваться для хранения обработчиков событий */
_callback = {};

constructor() {
if (new.target === AbstractView) {
throw new Error('Can\'t instantiate AbstractView, only concrete one.');
Expand Down
20 changes: 18 additions & 2 deletions src/presenter/filters-presenter.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import {
render
} from '../framework/render.js';

import FiltersView from '../view/filters-view.js';
import { FilterSettings } from '../const.js';
import { filterByType } from '../utils';

const filtersContainer = document.querySelector('.trip-controls__filters');

export default class FiltersPresenter {
#pointsModel = null;
#filters = [];

constructor({pointsModel}) {
this.#pointsModel = pointsModel;

this.#filters = Object.entries(filterByType)
.map(([type, filter]) => ({
...FilterSettings[type],
type,
disabled: filter(this.#pointsModel.get()).length === 0
}));
}

init() {
render(new FiltersView(), filtersContainer);
render(new FiltersView({
items: this.#filters
}), filtersContainer);
}
}
2 changes: 1 addition & 1 deletion src/service/mock-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default class MockService {

#generatePoints() {
return Array.from({
length: MocksMaxCount.POINTS
length: getRandomPositiveNumber(0, MocksMaxCount.POINTS)
}, () => {
const type = getRandomArrayElement(EVENT_TYPES);
const destination = getRandomArrayElement(this.#destinations);
Expand Down
17 changes: 15 additions & 2 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
MSEC_IN_HOUR,
MSEC_IN_DAY,
DateFormat,
DurationFormat
DurationFormat,
FilterType
} from './const.js';

const getRandomArrayElement = (items) => items[Math.floor(Math.random() * items.length)];
Expand All @@ -14,7 +15,7 @@ const getRandomPositiveNumber = (min = 0, max = 1) => {
const upper = Math.floor(Math.max(min, max));
return Math.floor(lower + Math.random() * (upper - lower + 1));
};
const getRandomDate = (start = new Date(2022, 0, 1), end = new Date()) => new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
const getRandomDate = (start = new Date(2022, 0, 1), end = new Date(2025, 0, 1)) => new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
const formatDate = (currentDate, format = DateFormat.FULL) => dayjs(currentDate).format(format);

const calculateDuration = (dateFrom, dateTo) => {
Expand Down Expand Up @@ -46,6 +47,17 @@ const incrementCounter = (START_FROM) => {

const toCapitalize = (str) => `${str[0].toUpperCase()}${str.slice(1)}`;

const isPointFuture = (point) => dayjs().isBefore(point.dateFrom);
const isPointPresent = (point) => dayjs().isAfter(point.dateFrom) && dayjs().isBefore(point.dateTo);
const isPointPast = (point) => dayjs().isAfter(point.dateTo);

const filterByType = {
[FilterType.ANY]: (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 {
getRandomArrayElement,
getRandomPositiveNumber,
Expand All @@ -54,4 +66,5 @@ export {
calculateDuration,
incrementCounter,
toCapitalize,
filterByType,
};
49 changes: 19 additions & 30 deletions src/view/create-sort-view.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,26 @@
import AbstractView from '../framework/view/abstract-view.js';
import { SORTING_COLUMNS } from '../const.js';
import ItemListView from './item-list-view.js';

function createSortingTemplate() {
return (
`<form class="trip-events__trip-sort trip-sort" action="#" method="get">
<div class="trip-sort__item trip-sort__item--day">
<input id="sort-day" class="trip-sort__input visually-hidden" type="radio" name="trip-sort" value="sort-day" checked>
<label class="trip-sort__btn" for="sort-day">Day</label>
</div>
<div class="trip-sort__item trip-sort__item--event">
<input id="sort-event" class="trip-sort__input visually-hidden" type="radio" name="trip-sort" value="sort-event" disabled>
<label class="trip-sort__btn" for="sort-event">Event</label>
</div>
<div class="trip-sort__item trip-sort__item--time">
<input id="sort-time" class="trip-sort__input visually-hidden" type="radio" name="trip-sort" value="sort-time">
<label class="trip-sort__btn" for="sort-time">Time</label>
</div>
<div class="trip-sort__item trip-sort__item--price">
<input id="sort-price" class="trip-sort__input visually-hidden" type="radio" name="trip-sort" value="sort-price">
<label class="trip-sort__btn" for="sort-price">Price</label>
</div>
function createSortingItemTemplate(column) {
const { type, label, active, defaultSelected } = column;
return `
<div class="trip-sort__item trip-sort__item--${type}">
<input id="sort-${type}" class="trip-sort__input visually-hidden" type="radio" name="trip-sort" value="${type}" ${!active ? 'disabled' : ''} ${defaultSelected ? 'checked' : ''}>
<label class="trip-sort__btn" for="sort-${type}">${label}</label>
</div>`;
}

<div class="trip-sort__item trip-sort__item--offer">
<input id="sort-offer" class="trip-sort__input visually-hidden" type="radio" name="trip-sort" value="sort-offer" disabled>
<label class="trip-sort__btn" for="sort-offer">Offers</label>
</div>
</form>`
);
function createSortingTemplate() {
return `<form class="trip-events__trip-sort trip-sort" action="#" method="get">
${SORTING_COLUMNS.map(createSortingItemTemplate).join('')}
</form>`;
}

export default class SortingView extends AbstractView {
export default class SortingView extends ItemListView {
constructor() {
super({ items: SORTING_COLUMNS });
}

get template() {
return createSortingTemplate();
}
Expand Down
39 changes: 15 additions & 24 deletions src/view/filters-view.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
import AbstractView from '../framework/view/abstract-view.js';
import ItemListView from './item-list-view.js';

function createFiltersTemplate() {
function createFilterItemTemplate(filter) {
const { type, label, defaultSelected, disabled } = filter;
return (
`<form class="trip-filters" action="#" method="get">
<div class="trip-filters__filter">
<input id="filter-everything" class="trip-filters__filter-input visually-hidden" type="radio" name="trip-filter" value="everything" checked>
<label class="trip-filters__filter-label" for="filter-everything">Everything</label>
</div>
<div class="trip-filters__filter">
<input id="filter-future" class="trip-filters__filter-input visually-hidden" type="radio" name="trip-filter" value="future">
<label class="trip-filters__filter-label" for="filter-future">Future</label>
</div>
<div class="trip-filters__filter">
<input id="filter-present" class="trip-filters__filter-input visually-hidden" type="radio" name="trip-filter" value="present">
<label class="trip-filters__filter-label" for="filter-present">Present</label>
</div>
<div class="trip-filters__filter">
<input id="filter-past" class="trip-filters__filter-input visually-hidden" type="radio" name="trip-filter" value="past">
<label class="trip-filters__filter-label" for="filter-past">Past</label>
</div>
`<div class="trip-filters__filter">
<input id="filter-${type}" class="trip-filters__filter-input visually-hidden" type="radio" name="trip-filter" value="${type}" ${defaultSelected ? 'checked' : ''} ${disabled ? 'disabled' : ''}>
<label class="trip-filters__filter-label" for="filter-${type}">${label}</label>
</div>`
);
}

function createFiltersTemplate(filters) {
return (
`<form class="trip-filters" action="#" method="get">
${filters.map(createFilterItemTemplate).join('')}
<button class="visually-hidden" type="submit">Accept filter</button>
</form>`
);
}

export default class FiltersView extends AbstractView {
export default class FiltersView extends ItemListView {
get template() {
return createFiltersTemplate();
return createFiltersTemplate(this._items);
}
}
21 changes: 21 additions & 0 deletions src/view/item-list-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import AbstractView from '../framework/view/abstract-view.js';

export default class ItemListView extends AbstractView {
_items = [];
_handleItemChange = null;

constructor ({
items,
onItemChange
}) {
super();
this._items = items;
this._handleItemChange = onItemChange;
this.element.addEventListener('change', this.#itemChangeHandler);
}

#itemChangeHandler = (evt) => {
evt.preventDefault();
this._handleItemChange?.(evt.target.dataset.item);
};
}

0 comments on commit ce2288a

Please sign in to comment.