Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<link rel="stylesheet" href="app.css">
<script src="./js/app.js" defer></script>
<script src="./js/main.js" defer type="module"></script>
</head>
<body>
<header>
<h1>Phones App</h1>
<h1>Phones App fe_19</h1>
</header>

<div class="container-fluid">
<div data-component="App">
<h3>Content will be here</h3>
<div data-page-container>

</div>
</div>

Expand Down
2 changes: 0 additions & 2 deletions js/app.js

This file was deleted.

5 changes: 5 additions & 0 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import PhonesPage from './phones/phones-page.js'

const phonesPage = new PhonesPage ({
element: document.querySelector('[data-page-container')
})
54 changes: 54 additions & 0 deletions js/phones/components/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export default class Component {
constructor({ element }) {
this._callbackMap = {};
this._element = element;
}

on(eventName, selector, callback) {
this._element.addEventListener(eventName, (event) => {
const deligatedTarget = event.target.closest(selector);
if (!deligatedTarget) {
return;
}
callback(event);

})
}

emit(eventName, data) {
const callback = this._callbackMap[eventName];
if(!callback) {
return;
}
this._callbackMap[eventName].forEach(callback => {
callback(data)
});
}

subscribe(eventName, callback) {
if(!this._callbackMap[eventName]) {
this._callbackMap[eventName] = [];
}

this._callbackMap[eventName].push(callback);

}

unsubscribe(eventName, callbackToRemove) {
const callback = this._callbackMap[eventName];
if(callback) {
this._callbackMap[eventName] = callback
.filter( cb => cb !== callbackToRemove
)
}
}

hide() {
this._element.hidden = true;
}

show() {
this._element.hidden = false;
}

}
48 changes: 48 additions & 0 deletions js/phones/components/filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Component from "./component.js";
import utils from "../../utils.js";

export default class Filter extends Component {
constructor({ element }) {
super({ element });

this._render();

this._queryField = this._element.querySelector('[data-element="query-fild"]');
this._orderField = this._element.querySelector('[data-element="order-fild"]');

const debounceOnInput = utils.debounce(() => {
this.emit('query-change')
} ,500)

this.on('input', '[data-element="query-fild"]', debounceOnInput);

this.on('change', '[data-element="order-fild"]',() => {
this.emit('order-change')
});
}

getCurrent() {
return {
query: this._queryField.value,
order: this._orderField.value
}
}

_render() {
this._element.innerHTML = `
<p>
Search:
<input data-element="query-fild">
</p>

<p>
Sort by:
<select data-element="order-fild">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select>
</p>
`
}
}

58 changes: 58 additions & 0 deletions js/phones/components/phone-viewer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Component from './component.js'

export default class PhoneViewer extends Component{
constructor({
element
}) {
super({element}),

this.on('click', '[data-batton="back-button"]', () => {
this.emit('back');
})

this.on('click', '[data-element="small-preview"]', (event) =>{
this.bigImg = this._element.querySelector('[data-element="big-preview"]');
this.bigImg.src = event.target.src;
})

this.on('click', '[data-batton="add-to-basket"]', () => {
this.emit('add-to-basket',this._phoneDetaild.id);
})

}

show(phoneDetails) {
super.show();
this._phoneDetaild = phoneDetails;
this._render();
}

_render() {
this._element.innerHTML = `
<img
data-element="big-preview"
class="phone"
src="${this._phoneDetaild.images[0]}"
>

<button data-batton="back-button">Back</button>
<button data-batton="add-to-basket">Add to basket</button>


<h1>${this._phoneDetaild.name}</h1>

<p>Motorola XOOM with Wi-Fi has a super-powerful dual-core processor and Android™ 3.0 (Honeycomb) — the Android platform designed specifically for tablets. With its 10.1-inch HD widescreen display, you’ll enjoy HD video in a thin, light, powerful and upgradeable tablet.</p>

<ul class="phone-thumbs">
${
this._phoneDetaild.images.map( src => `
<li>
<img src="${src}" data-element="small-preview">
</li>
`
).join('')
}
</ul>
`
}
}
75 changes: 75 additions & 0 deletions js/phones/components/phones-catalog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import Component from './component.js'

export default class PhonesCatalog extends Component{
constructor({element}) {

super({ element });

this._phones = [];
this._render();

this.on('click', '[data-element="details-link"]', () => {

const phoneEl = event.target.closest('[data-element="phone-elnment"]');
const phoneId = phoneEl.dataset.phoneId;
this.emit('phone-selected', phoneId);
})

this.on('click', '[data-element="add-phone-to-basket"]', () => {
const phoneEl = event.target.closest('[data-element="phone-elnment"]');
const phoneId = phoneEl.dataset.phoneId;
this.emit('add-to-basket', phoneId);
})

}

show(phones) {
this._phones = phones;
super.show();
this._render();
}


_render() {
this._element.innerHTML = `
<ul class="phones">
${

this._phones.map(phone => `
<li
class="thumbnail"
data-element="phone-elnment"
data-phone-id="${phone.id}
">
<a
data-element="details-link"
href="#!/phones/motorola-xoom-with-wi-fi"
class="thumb"
>
<img alt="Motorola XOOM™ with Wi-Fi" src="${phone.imageUrl}">
</a>

<div class="phones__btn-buy-wrapper">
<a
data-element="add-phone-to-basket"
class="btn btn-success"
>
Add
</a>
</div>

<a
data-element="details-link"
href="#!/phones/motorola-xoom-with-wi-fi"
>${phone.name}</a>
<p>${phone.snippet}</p>
</li>
`
).join('')
}


</ul>
`
}
}
54 changes: 54 additions & 0 deletions js/phones/components/shoping-cart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Component from "./component.js"

export default class ShoppingCart extends Component {
constructor( {element} ) {
super( {element} )
this.allPhoneInBasket = {};
this._render();
this.on('click', '[data-element ="remove-button"]', (event) => {
const phone = event.target.closest('li');
this.remove(phone.dataset.elementId);
})
}


addToBasket(selectedPhone) {
if(!this.allPhoneInBasket.hasOwnProperty(selectedPhone)) {
this.allPhoneInBasket[selectedPhone] = 0;
}
this.allPhoneInBasket[selectedPhone] += 1;
this._render();

}

remove(phone) {
if(this.allPhoneInBasket.hasOwnProperty(phone)) {
this.allPhoneInBasket[phone] -= 1;
}

if(this.allPhoneInBasket[phone] === 0) {
delete this.allPhoneInBasket[phone]
}
this._render()

}

_render() {
this._element.innerHTML = `
<p>Shopping Cart</p>
<ul data-element="phone-in-basket">
${
Object.entries(this.allPhoneInBasket)
.map(([name, quantity]) => `
<li
data-element-id="${name}"
>
${name} - ${quantity}
<button data-element ="remove-button">X</button>
</li>`)
.join('')
}
</ul>
`
}
}
Loading