Skip to content

Commit

Permalink
Merge pull request #11 from TeaWithSalt/module8-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored May 27, 2024
2 parents a7b82d9 + c7752e6 commit 3d40be5
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 189 deletions.
114 changes: 14 additions & 100 deletions src/const.js
Original file line number Diff line number Diff line change
@@ -1,95 +1,5 @@
const WAYPOINTS_COUNT = 3;

const PRICES = [100, 150, 200];

const DATES = [
{from: '2024-01-24T23:55:43.845Z', to: '2024-03-24T09:13:25.845Z'},
{from: '2024-04-05T13:34:15.845Z', to: '2024-06-05T22:05:34.845Z'},
{from: '2025-03-12T10:21:12.845Z', to: '2025-03-12T12:18:24.845Z'},
{from: '2022-01-31T19:54:08.845Z', to: '2022-01-31T21:45:19.845Z'},
{from: '2025-06-17T16:15:14.845Z', to: '2025-06-19T02:06:08.845Z'}
];

const DESTINATIONS = [
{id: '1', description: 'Description of Moscow', name: 'Moscow', pictures: [{src: 'https://loremflickr.com/248/152?random=1}', description: 'Photo of Moscow'}]},
{id: '2', description: 'Description of Saint Petersburg', name: 'Saint Petersburg', pictures: [{src: 'https://loremflickr.com/248/152?random=2}', description: 'Photo of Saint Petersburg'}]},
{id: '3', description: 'Description of Ekaterinburg', name: 'Ekaterinburg', pictures: [{src: 'https://loremflickr.com/248/152?random=3}', description: 'Photo of Ekaterinburg'}]},
{id: '4', description: 'Description of Sochi', name: 'Sochi', pictures: [{src: 'https://loremflickr.com/248/152?random=4}', description: 'Photo of Sochi'}]},
{id: '5', description: 'Description of Krasnodar', name: 'Krasnodar', pictures: [{src: 'https://loremflickr.com/248/152?random=5}', description: 'Photo of Krasnodar'}]},
];

const BOOL = [true, false];

const OFFERS = [
{
type: 'taxi',
offers: [
{id: '1', title: 'Add luggage', price: '20'},
{id: '2', title: 'Switch to comfort class', price: '50'},
{id: '3', title: 'Add water', price: '5'}
]
},
{
type: 'bus',
offers: [
{id: '1', title: 'Add luggage', price: '40'}
]
},
{
type: 'train',
offers: [
{id: '1', title: 'Add luggage', price: '70'},
{id: '2', title: 'Add water', price: '10'},
{id: '3', title: 'Add meal', price: '20'}
]
},
{
type: 'ship',
offers: [
{id: '3', title: 'Add meal', price: '25'}
]
},
{
type: 'drive',
offers: [
{id: '1', title: 'Rent a car', price: '200'},
]
},
{
type: 'flight',
offers: [
{id: '1', title: 'Add luggage', price: '50'},
{id: '2', title: 'Switch to comfort class', price: '80'},
{id: '3', title: 'Add meal', price: '15'},
{id: '4', title: 'Choose seats', price: '5'},
{id: '5', title: 'Travel by train', price: '40'}
]
},
{
type: 'check-in',
offers: []
},
{
type: 'sightseeing',
offers: []
},
{
type: 'restaurant',
offers: []
},
];

const TYPES = ['taxi', 'bus', 'train', 'ship', 'drive', 'flight', 'check-in', 'sightseeing', 'restaurant'];

const EDITING_FORM = {
type: 'flight',
price: 160,
dateFrom: '2019-03-18T12:25:00.845Z',
dateTo: '2019-03-18T13:35:00.845Z',
destination: '1',
isFavorite: false,
offers: [ '1', '2' ],
};
const API_SRC = 'https://23.objects.htmlacademy.pro/big-trip';
const AUTHORIZATION = 'Basic awdaf5g34123csdrh56w2r5';

const ACTIONS = {
UPDATE_POINT: 'update',
Expand All @@ -98,11 +8,11 @@ const ACTIONS = {
};

const UPDATE_TYPE = {
PATCH: 'PATCH',
MINOR: 'MINOR',
MAJOR: 'MAJOR',
};


const DATE_FORMAT_EDIT = 'DD/MM/YY hh:mm';
const DATE_FORMAT_DAY = 'MMM DD';
const DATE_FORMAT_HOURS = 'hh:mm';
Expand All @@ -122,10 +32,14 @@ const SORTING_TYPES = {
OFFERS: 'offers'
};

export { WAYPOINTS_COUNT };
export { PRICES, DATES, BOOL, TYPES };
export { DESTINATIONS };
export { OFFERS };
export { DATE_FORMAT_EDIT, DATE_FORMAT_DAY, DATE_FORMAT_HOURS };
export { EDITING_FORM };
export { FILTER_TYPE, SORTING_TYPES, ACTIONS, UPDATE_TYPE };
export {
API_SRC,
AUTHORIZATION,
DATE_FORMAT_EDIT,
DATE_FORMAT_DAY,
DATE_FORMAT_HOURS,
FILTER_TYPE,
SORTING_TYPES,
ACTIONS,
UPDATE_TYPE
};
8 changes: 7 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ 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';

const mainContainer = document.querySelector('.trip-main');
const filterContainer = document.querySelector('.trip-controls__filters');
Expand All @@ -16,7 +18,10 @@ const mockFilters = getMockFilters();
const mockSorts = getMockSorts();


const waypointsModel = new WaypointsModel();
const waypointsModel = new WaypointsModel({
waypointsService: new WaypointsService(API_SRC, AUTHORIZATION)
});

const filterModel = new FilterModel();

const filterPresenter = new FilterPresenter({
Expand Down Expand Up @@ -54,3 +59,4 @@ render(newPointButtonComponent, mainContainer, RenderPosition.BEFOREEND);

filterPresenter.init();
eventPresenter.init();
waypointsModel.init();
103 changes: 81 additions & 22 deletions src/model/waypoint-model.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
import {getRandomWaypoint} from '../mock/waypoint.js';
import {UPDATE_TYPE, WAYPOINTS_COUNT} from '../const.js';
import {UPDATE_TYPE} from '../const.js';
import Observable from '../framework/observable';

export default class WaypointsModel extends Observable {
waypoints = Array.from({length: WAYPOINTS_COUNT}, getRandomWaypoint);
#waypointsService = null;
waypoints = [];
destinations = [];
offers = [];

constructor({waypointsService}) {
super();
this.#waypointsService = waypointsService;
}

getWaypoints() {
return this.waypoints;
}

getDestinations() {
return this.destinations;
}

getOffers() {
return this.offers;
}

getWaypoint(id) {
return this.waypoints.find((waypoint) => waypoint.id === id);
}
Expand All @@ -21,42 +36,86 @@ export default class WaypointsModel extends Observable {
this.waypoints = [...this.waypoints.filter((other) => other.id !== id), waypoint];
}

addPoint(updateType, update) {
this.waypoints = [
update,
...this.waypoints,
];
this._notify(updateType, update);
async init() {
try {
const waypoints = await this.#waypointsService.events;
this.waypoints = waypoints.map(this.#adapter);
this.destinations = await this.#waypointsService.destinations;
this.offers = await this.#waypointsService.offers;
} catch (err) {
this.waypoints = [];
}

this._notify(UPDATE_TYPE.MAJOR);
}

updatePoint(updateType, update) {
async addPoint(updateType, update) {
try {
const response = await this.#waypointsService.addEvent(update);
const adaptedWaypoint = this.#adapter(response);
this.waypoints = [response, ...this.waypoints];
this._notify(updateType, adaptedWaypoint);
} catch (err) {
throw new Error('Can\'t add event');
}
}

async updatePoint(updateType, update) {
const index = this.waypoints.findIndex((point) => point.id === update.id);

if (index === -1) {
throw new Error('The point doesn\'t exist!');
}

this.waypoints = [
...this.waypoints.slice(0, index),
update,
...this.waypoints.slice(index + 1),
];

this._notify(updateType, update);
try {
const response = await this.#waypointsService.updateEvent(update);
const adaptedWaypoint = this.#adapter(response);
this.waypoints = [
...this.waypoints.slice(0, index),
adaptedWaypoint,
...this.waypoints.slice(index + 1),
];
this._notify(updateType, adaptedWaypoint);
} catch (err) {
throw new Error('Can\'t update event');
}
}

deletePoint(updateType, update) {
async deletePoint(updateType, update) {
const index = this.waypoints.findIndex((point) => point.id === update.id);

if (index === -1) {
throw new Error('The point doesn\'t exist!');
}

this.waypoints = [
...this.waypoints.slice(0, index),
...this.waypoints.slice(index + 1),
];
try {
await this.#waypointsService.deleteEvent(update);
this.waypoints = [
...this.waypoints.slice(0, index),
...this.waypoints.slice(index + 1),
];

this._notify(UPDATE_TYPE.MINOR, update);
} catch (err) {
throw new Error('Can\'t delete event');
}
}

#adapter(waypoint) {
const adaptedWaypoint = {
...waypoint,
basePrice: waypoint['base_price'],
dateFrom: waypoint['date_from'],
dateTo: waypoint['date_to'],
isFavorite: waypoint['is_favorite'],
};

delete adaptedWaypoint['base_price'];
delete adaptedWaypoint['date_from'];
delete adaptedWaypoint['date_to'];
delete adaptedWaypoint['is_favorite'];

this._notify(UPDATE_TYPE.MINOR, update);
return adaptedWaypoint;
}
}
9 changes: 8 additions & 1 deletion src/presenter/event-presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export default class EventPresenter {

createWaypoint() {
this.#newPointPresenter = new NewWaypointPresenter({
destinations: this.waypointsModel.getDestinations(),
offers: this.waypointsModel.getOffers(),
pointListContainer: this.#eventListContainer.element,
onDataChange: this.#handleWaypointChange,
onDestroy: this.#onNewPointDestroy,
Expand Down Expand Up @@ -91,6 +93,8 @@ export default class EventPresenter {
#renderWaypoint(waypoint) {
const waypointPresenter = new WaypointPresenter({
waypoint,
destinations: this.waypointsModel.getDestinations(),
offers: this.waypointsModel.getOffers(),
containerElement: this.#eventListContainer.element,
closeAllEditForms: () => this.#closeAllEditForms(),
onChange: this.#handleWaypointChange
Expand Down Expand Up @@ -128,8 +132,11 @@ export default class EventPresenter {
this.renderWaypoints();
}

#handleModelEvent = (updateType) => {
#handleModelEvent = (updateType, data) => {
switch (updateType) {
case UPDATE_TYPE.PATCH:
this.#waypointPresenters.get(data.id).init(data);
break;
case UPDATE_TYPE.MINOR:
this.reset();
this.renderWaypoints();
Expand Down
28 changes: 15 additions & 13 deletions src/presenter/new-waypoint-presenter.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import {remove, render, RenderPosition} from '../framework/render.js';
import {ACTIONS as USER_ACTION, UPDATE_TYPE} from '../const';
import EditingFormView from '../view/editing-form-view';
import {isEscape} from '../utils';

export default class NewWaypointPresenter {
#offers;
#destinations;
#pointListContainer;
#newWaypointComponent = null;
#handleDataChange;
#handleDestroy;
#closeAllEditForms;

constructor({pointListContainer, onDataChange, onDestroy, closeAllEditForms}) {
constructor({offers, destinations, pointListContainer, onDataChange, onDestroy, closeAllEditForms}) {
this.#offers = offers;
this.#destinations = destinations;
this.#handleDataChange = onDataChange;
this.#handleDestroy = onDestroy;
this.#pointListContainer = pointListContainer;
Expand All @@ -24,8 +29,9 @@ export default class NewWaypointPresenter {
this.#closeAllEditForms();

this.#newWaypointComponent = new EditingFormView({
formType: 'create',
waypoint: {type: 'flight', destination: '', price: '0', offers: []},
offers: this.#offers,
destinations: this.#destinations,
waypoint: {type: 'flight', destination: '', basePrice: 0, offers: []},
onFormSubmit: (newWaypoint) => this.#handleSaveClick(newWaypoint),
onClose: () => this.#handleCancelClick(),
onDelete: this.#handleCancelClick
Expand All @@ -48,15 +54,11 @@ export default class NewWaypointPresenter {
document.removeEventListener('keydown', this.#escKeyDownHandler);
}

#handleSaveClick = (point) => {
this.#handleDataChange(
USER_ACTION.ADD_POINT,
UPDATE_TYPE.MAJOR,
{
id: Date.now().toString(36) + Math.random().toString(36).slice(2),
...point
},
);
#handleSaveClick = (waypoint) => {
this.#handleDataChange(USER_ACTION.ADD_POINT, UPDATE_TYPE.MAJOR, {
...waypoint,
isFavorite: false
});
this.destroy();
};

Expand All @@ -65,7 +67,7 @@ export default class NewWaypointPresenter {
};

#escKeyDownHandler = (evt) => {
if (evt.key === 'Esc' || evt.key === 'Escape') {
if (isEscape(evt.key)) {
evt.preventDefault();
this.destroy();
}
Expand Down
Loading

0 comments on commit 3d40be5

Please sign in to comment.