Skip to content

Commit

Permalink
Merge pull request #5 from MaxSiryatov/module4-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Apr 14, 2024
2 parents 0d1c5ae + 9c49990 commit 6e132d6
Show file tree
Hide file tree
Showing 17 changed files with 603 additions and 164 deletions.
387 changes: 386 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
"@babel/preset-env": "7.20.2",
"babel-loader": "9.1.0",
"copy-webpack-plugin": "11.0.0",
"css-loader": "6.7.2",
"dayjs": "1.11.6",
"eslint": "8.28.0",
"eslint-config-htmlacademy": "8.0.0",
"flatpickr": "4.6.13",
"he": "1.2.0",
"html-webpack-plugin": "5.6.0",
"style-loader": "3.3.1",
"webpack": "5.75.0",
"webpack-cli": "5.0.0",
"webpack-dev-server": "4.11.1"
Expand Down
22 changes: 11 additions & 11 deletions src/model/destination-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ import {getRandomDestination} from '../mock/destination.js';
import {CITIES_COUNT} from '../const.js';

export default class DestinationModel {
towns = Array.from({length: CITIES_COUNT}, getRandomDestination);
#cities = Array.from({length: CITIES_COUNT}, getRandomDestination);

getTowns() {
return this.towns;
getCities() {
return this.#cities;
}

getTownNameById(townArr, id) {
getCityNameById(cityArr, id) {
let temp = '';
townArr.forEach((town) => {
if (town.id === id) {
temp = town.name;
cityArr.forEach((city) => {
if (city.id === id) {
temp = city.name;
}
});
return temp;
}

getTownDescByID(townArr, id) {
getCityDescriptionByID(cityArr, id) {
let temp = '';
townArr.forEach((town) => {
if (town.id === id) {
temp = town.description;
cityArr.forEach((city) => {
if (city.id === id) {
temp = city.description;
}
});
return temp;
Expand Down
10 changes: 5 additions & 5 deletions src/model/point-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import OfferModel from '../model/offer-model.js';

export default class PointModel {
destinationModel = new DestinationModel();
towns = this.destinationModel.getTowns();
cities = this.destinationModel.getCities();

points = Array.from({length: POINTS_COUNT}, () => {
const offerModel = new OfferModel(getRandomValue(0, OFFERS_COUNT));
Expand All @@ -17,12 +17,12 @@ export default class PointModel {
offers.push(offerModel.getOfferByID(offersArr, offerID));
});

const townID = getRandomArrayElement(this.towns).id;
const cityID = getRandomArrayElement(this.cities).id;

const point = (getRandomPoint(townID, offersID));
point.destination = this.destinationModel.getTownNameById(this.towns, townID);
const point = (getRandomPoint(cityID, offersID));
point.destination = this.destinationModel.getCityNameById(this.cities, cityID);
point.offers = offers;
point.description = this.destinationModel.getTownDescByID(this.towns, townID);
point.description = this.destinationModel.getCityDescriptionByID(this.cities, cityID);
return point;
});

Expand Down
71 changes: 58 additions & 13 deletions src/presenter/trip-presenter.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,74 @@
import SortView from '../view/sort-view.js';
import EventsListView from '../view/event-list-view.js';
import CurrentFormView from '../view/point-edit-view.js';
import SortView from '../view/sort-view.js';
import PointView from '../view/point-view.js';
import { render } from '../render.js';
import OpenFormBtnView from '../view/open-form-button-view.js';
import { RenderPosition, render, replace } from '../framework/render.js';
import CloseFormBtnView from '../view/close-form-button-view.js';
import SaveFormBtnView from '../view/save-form-button-view.js';

export default class TripPresenter {
sortFormView = new SortView();
eventsListView = new EventsListView();
#sortFormView = new SortView();
#pointsListView = new EventsListView();
#container = null;
#pointModel = null;
#formComponent = null;
#tripPoint = [];

constructor ({container, pointModel}) {
this.container = container;
this.pointModel = pointModel;
this.#container = container;
this.#pointModel = pointModel;
}

init() {
this.tripPoint = [...this.pointModel.getPoints()];
this.currentPoint = this.pointModel.getPoint();
this.#tripPoint = [...this.#pointModel.getPoints()];

render(this.#sortFormView, this.#container);
render(this.#pointsListView, this.#container);

for (let i = 0; i < this.#tripPoint.length; i++) {
this.#renderPoint(this.#tripPoint[i]);
}
}

render(this.sortFormView, this.container);
render(this.eventsListView, this.container);
#renderPoint (point) {
const escKeyDownBtnHandler = (evt) => {
if (evt.key === 'Escape') {
replacePointToForm();
document.removeEventListener('keydown', escKeyDownBtnHandler);
}
};
const pointComponent = new PointView({data: point});
const formComponent = new CurrentFormView({
data: point,
onSubmit: () => {
replacePointToForm();
document.removeEventListener('keydown', escKeyDownBtnHandler);
}});
const deleteBtn = formComponent.element.querySelector('.event__reset-btn');
const openBtn = new OpenFormBtnView({
onClick: () => {
replaceFormToPoint();
document.addEventListener('keydown', escKeyDownBtnHandler);
}});
const closeBtn = new CloseFormBtnView({
onClick: () => {
replacePointToForm();
document.removeEventListener('keydown', escKeyDownBtnHandler);
}});
const saveBtn = new SaveFormBtnView();

render(new CurrentFormView({point: this.currentPoint}), this.eventsListView.getElement());
render(pointComponent, this.#pointsListView.element);
render(openBtn, pointComponent.element, RenderPosition.BEFOREEND);
render(saveBtn, deleteBtn, RenderPosition.BEFOREBEGIN);
render(closeBtn, deleteBtn, RenderPosition.AFTEREND);

function replacePointToForm() {
replace(pointComponent, formComponent);
}

for (let i = 0; i < this.tripPoint.length; i++) {
render(new PointView({data: this.tripPoint[i]}), this.eventsListView.getElement());
function replaceFormToPoint() {
replace(formComponent, pointComponent);
}
}
}

Check failure on line 74 in src/presenter/trip-presenter.js

View workflow job for this annotation

GitHub Actions / Check

Newline required at end of file but not found
2 changes: 1 addition & 1 deletion src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function createElement(template) {
}

function render(component, container, place = RenderPosition.BEFOREEND) {
container.insertAdjacentElement(place, component.getElement());
container.insertAdjacentElement(place, component.element);
}

export {RenderPosition, createElement, render};
21 changes: 9 additions & 12 deletions src/templates/point-edit-template.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {POINTS_TYPE, DESTINATIONS, OFFERS, IMAGES} from '../const.js';
import { getRandomValue, getFullDate } from '../utils.js';

function createPointEditTemplate (point) {
function createPointEditTemplate (pointForm) {
return `<li class="trip-events__item">
<form class="event event--edit" action="#" method="post">
<header class="event__header">
<div class="event__type-wrapper">
<label class="event__type event__type-btn" for="event-type-toggle-1">
<span class="visually-hidden">Choose event type</span>
<img class="event__type-icon" width="17" height="17" src="img/icons/${point.type}.png" alt="Event type icon">
<img class="event__type-icon" width="17" height="17" src="img/icons/${pointForm.type}.png" alt="Event type icon">
</label>
<input class="event__type-toggle visually-hidden" id="event-type-toggle-1" type="checkbox">
<div class="event__type-list">
Expand All @@ -23,19 +23,19 @@ function createPointEditTemplate (point) {
</div>
<div class="event__field-group event__field-group--destination">
<label class="event__label event__type-output" for="event-destination-1">
${point.type}
${pointForm.type}
</label>
<input class="event__input event__input--destination" id="event-destination-1" type="text" name="event-destination" value="${point.destination}" list="destination-list-1">
<input class="event__input event__input--destination" id="event-destination-1" type="text" name="event-destination" value="${pointForm.destination}" list="destination-list-1">
<datalist id="destination-list-1">
${DESTINATIONS.map((town) => `<option value="${town}"></option>`).join('')};
</datalist>
</div>
<div class="event__field-group event__field-group--time">
<label class="visually-hidden" for="event-start-time-1">From</label>
<input class="event__input event__input--time" id="event-start-time-1" type="text" name="event-start-time" value="${getFullDate(point.dateFrom)}">
<input class="event__input event__input--time" id="event-start-time-1" type="text" name="event-start-time" value="${getFullDate(pointForm.dateFrom)}">
&mdash;
<label class="visually-hidden" for="event-end-time-1">To</label>
<input class="event__input event__input--time" id="event-end-time-1" type="text" name="event-end-time" value="${getFullDate(point.dateTo)}">
<input class="event__input event__input--time" id="event-end-time-1" type="text" name="event-end-time" value="${getFullDate(pointForm.dateTo)}">
</div>
<div class="event__field-group event__field-group--price">
<label class="event__label" for="event-price-1">
Expand All @@ -44,15 +44,14 @@ function createPointEditTemplate (point) {
</label>
<input class="event__input event__input--price" id="event-price-1" type="text" name="event-price" value="">
</div>
<button class="event__save-btn btn btn--blue" type="submit">Save</button>
<button class="event__reset-btn" type="reset">Cancel</button>
<button class="event__reset-btn" type="reset">Delete</button>'
</header>
<section class="event__details">
<section class="event__section event__section--offers">
<h3 class="event__section-title event__section-title--offers">Offers</h3>
<div class="event__available-offers">
${OFFERS.map((offer) => `<div class="event__offer-selector">
<input class="event__offer-checkbox visually-hidden" id="event-offer-${offer.toLowerCase()}-1" type="checkbox" name="event-offer-${offer.toLowerCase()}" ${isChecked(point.offers, offer)}>
<input class="event__offer-checkbox visually-hidden" id="event-offer-${offer.toLowerCase()}-1" type="checkbox" name="event-offer-${offer.toLowerCase()}" ${isChecked(pointForm.offers, offer)}>
<label class="event__offer-label" for="event-offer-${offer.toLowerCase()}-1">
<span class="event__offer-title">${offer}</span>
&plus;&euro;&nbsp;
Expand All @@ -61,7 +60,7 @@ function createPointEditTemplate (point) {
</div>`).join('')};
<section class="event__section event__section--destination">
<h3 class="event__section-title event__section-title--destination">Destination</h3>
<p class="event__destination-description">${point.description}</p>
<p class="event__destination-description">${pointForm.description}</p>
<div class="event__photos-container">
<div class="event__photos-tape">
${IMAGES.map((img) => `<img class="event__photo" src="${img}.jpg" alt="Event photo">`).join('')};
Expand All @@ -73,7 +72,6 @@ function createPointEditTemplate (point) {
</li>
`;
}

function isChecked(offers, title) {
let check = false;
offers.forEach((offer) => {
Expand All @@ -84,5 +82,4 @@ function isChecked(offers, title) {
});
return check ? 'checked' : '';
}

export {createPointEditTemplate};
65 changes: 31 additions & 34 deletions src/templates/point-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,37 @@ import {getDateDiff, getMonthAndDay, getTime} from '../utils.js';

function createPointTemplate (point) {
return `<div class="event">
<time class="event__date" datetime=${point.dateFrom}>${getMonthAndDay(point.dateFrom)}</time>
<div class="event__type">
<img class="event__type-icon" width="42" height="42" src="img/icons/${point.type.toLowerCase()}.png" alt="Event type icon">
</div>
<h3 class="event__title">${point.type} ${point.destination}</h3>
<div class="event__schedule">
<p class="event__time">
<time class="event__start-time" datetime="${point.dateFrom}">${getTime(point.dateFrom)}</time>
&mdash;
<time class="event__end-time" datetime="${point.dateTo}">${getTime(point.dateTo)}</time>
</p>
<p class="event__duration">${getDateDiff(point.dateFrom, point.dateTo)}</p>
</div>
<p class="event__price">
&euro;&nbsp;<span class="event__price-value">${point.basePrice}</span>
</p>
<h4 class="visually-hidden">Offers:</h4>
<ul class="event__selected-offers">
${point.offers.map((offer) => `<li class="event__offer">
<span class="event__offer-title">${offer.title}</span>
&plus;&euro;&nbsp;
<span class="event__offer-price">${offer.price}</span>
</li>`).join('')}
</ul>
<button class="event__favorite-btn ${isFavorite(point.isFavorite)}" type="button">
<span class="visually-hidden">Add to favorite</span>
<svg class="event__favorite-icon" width="28" height="28" viewBox="0 0 28 28">
<path d="M14 21l-8.22899 4.3262 1.57159-9.1631L.685209 9.67376 9.8855 8.33688 14 0l4.1145 8.33688 9.2003 1.33688-6.6574 6.48934 1.5716 9.1631L14 21z"/>
</svg>
</button>
<button class="event__rollup-btn" type="button">
<span class="visually-hidden">Open event</span>
</button>
</div>`;
<time class="event__date" datetime=${point.dateFrom}>${getMonthAndDay(point.dateFrom)}</time>
<div class="event__type">
<img class="event__type-icon" width="42" height="42" src="img/icons/${point.type.toLowerCase()}.png" alt="Event type icon">
</div>
<h3 class="event__title">${point.type} ${point.destination}</h3>
<div class="event__schedule">
<p class="event__time">
<time class="event__start-time" datetime="${point.dateFrom}">${getTime(point.dateFrom)}</time>
&mdash;
<time class="event__end-time" datetime="${point.dateTo}">${getTime(point.dateTo)}</time>
</p>
<p class="event__duration">${getDateDiff(point.dateFrom, point.dateTo)}</p>
</div>
<p class="event__price">
&euro;&nbsp;<span class="event__price-value">${point.basePrice}</span>
</p>
<h4 class="visually-hidden">Offers:</h4>
<ul class="event__selected-offers">
${point.offers.map((offer) => `<li class="event__offer">
<span class="event__offer-title">${offer.title}</span>
&plus;&euro;&nbsp;
<span class="event__offer-price">${offer.price}</span>
</li>`).join('')}
</ul>
<button class="event__favorite-btn ${isFavorite(point.isFavorite)}" type="button">
<span class="visually-hidden">Add to favorite</span>
<svg class="event__favorite-icon" width="28" height="28" viewBox="0 0 28 28">
<path d="M14 21l-8.22899 4.3262 1.57159-9.1631L.685209 9.67376 9.8855 8.33688 14 0l4.1145 8.33688 9.2003 1.33688-6.6574 6.48934 1.5716 9.1631L14 21z"/>
</svg>
</button>
</div>`;
}

function isFavorite(check) {
Expand Down
26 changes: 26 additions & 0 deletions src/view/close-form-button-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import AbstractView from '../framework/view/abstract-view';

function createCloseFormBtn() {
return `<button class="event__rollup-btn" type="button">
<span class="visually-hidden">Open event</span>
</button>`;
}

export default class CloseFormBtnView extends AbstractView{
#handleClick = null;

constructor ({onClick}) {
super();
this.#handleClick = onClick;
this.element.addEventListener('click', this.#clickHandler);
}

get template() {
return createCloseFormBtn();
}

#clickHandler = (evt) => {
evt.preventDefault();
this.#handleClick();
};
}
17 changes: 3 additions & 14 deletions src/view/event-list-view.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import { createEventListTemplate } from '../templates/event-list-template.js';
import { createElement } from '../render.js';
import AbstractView from '../framework/view/abstract-view.js';

export default class EventsListView {
getTemplate() {
export default class EventListView extends AbstractView{
get template() {
return createEventListTemplate();
}

getElement() {
if (!this.element) {
this.element = createElement(this.getTemplate());
}
return this.element;
}

removeElement() {
this.element = null;
}
}
Loading

0 comments on commit 6e132d6

Please sign in to comment.